Added the validation using id token and checking if the user is a gym_owner
This commit is contained in:
parent
accf136896
commit
1f476a3071
@ -1,10 +1,11 @@
|
|||||||
import { onRequest } from "firebase-functions/v2/https";
|
import { onRequest } from "firebase-functions/v2/https";
|
||||||
import { getAdmin } from "../shared/config";
|
|
||||||
import { getCorsHandler } from "../shared/middleware";
|
import { getCorsHandler } from "../shared/middleware";
|
||||||
|
import { getAdmin, getLogger } from "../shared/config";
|
||||||
|
|
||||||
const corsHandler = getCorsHandler();
|
const corsHandler = getCorsHandler();
|
||||||
const admin = getAdmin();
|
const admin = getAdmin();
|
||||||
|
const logger = getLogger();
|
||||||
|
|
||||||
export const registerClient = onRequest({
|
export const registerClient = onRequest({
|
||||||
region: '#{SERVICES_RGN}#'
|
region: '#{SERVICES_RGN}#'
|
||||||
}, async (req, res) => {
|
}, async (req, res) => {
|
||||||
@ -13,80 +14,104 @@ export const registerClient = onRequest({
|
|||||||
if (req.method !== 'POST') {
|
if (req.method !== 'POST') {
|
||||||
return res.status(405).json({ error: 'Method not allowed. Please use POST.' });
|
return res.status(405).json({ error: 'Method not allowed. Please use POST.' });
|
||||||
}
|
}
|
||||||
|
const authHeader = req.headers.authorization;
|
||||||
const gymUser = req.body;
|
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||||
if (!gymUser.phoneNumber) {
|
return res.status(401).json({ error: 'Unauthorized. Missing or invalid authorization header.' });
|
||||||
return res.status(400).json({ error: 'Phone number is required' });
|
|
||||||
}
|
}
|
||||||
|
const idToken = authHeader.split('Bearer ')[1];
|
||||||
const isdCode = gymUser.isdCode || '+1';
|
|
||||||
const formattedPhoneNumber = gymUser.phoneNumber.startsWith('+')
|
|
||||||
? gymUser.phoneNumber
|
|
||||||
: `${isdCode}${gymUser.phoneNumber}`;
|
|
||||||
|
|
||||||
let uid;
|
|
||||||
try {
|
try {
|
||||||
const userRecord = await admin.auth().getUserByPhoneNumber(formattedPhoneNumber)
|
const decodedToken = await admin.auth().verifyIdToken(idToken);
|
||||||
.catch(() => null);
|
const uid = decodedToken.uid;
|
||||||
|
const userDoc = await admin.firestore().collection('users').doc(uid).get();
|
||||||
|
|
||||||
if (userRecord) {
|
if (!userDoc.exists) {
|
||||||
uid = userRecord.uid;
|
return res.status(403).json({ error: 'Forbidden. User not found.' });
|
||||||
} else {
|
}
|
||||||
const newUser = await admin.auth().createUser({
|
|
||||||
phoneNumber: formattedPhoneNumber,
|
const userData = userDoc.data();
|
||||||
displayName: gymUser.name || '',
|
if (!userData || !userData.roles || !userData.roles.includes('gym_owner')) {
|
||||||
email: gymUser.email || null,
|
return res.status(403).json({ error: 'Forbidden. Only gym owners can register clients.' });
|
||||||
|
}
|
||||||
|
const gymUser = req.body;
|
||||||
|
if (!gymUser.phoneNumber) {
|
||||||
|
return res.status(400).json({ error: 'Phone number is required' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const isdCode = gymUser.isdCode || '91';
|
||||||
|
const formattedPhoneNumber = gymUser.phoneNumber.startsWith('+')
|
||||||
|
? gymUser.phoneNumber
|
||||||
|
: `${isdCode}${gymUser.phoneNumber}`;
|
||||||
|
|
||||||
|
let clientUid;
|
||||||
|
try {
|
||||||
|
const userRecord = await admin.auth().getUserByPhoneNumber(formattedPhoneNumber)
|
||||||
|
.catch(() => null);
|
||||||
|
|
||||||
|
if (userRecord) {
|
||||||
|
clientUid = userRecord.uid;
|
||||||
|
} else {
|
||||||
|
const newUser = await admin.auth().createUser({
|
||||||
|
phoneNumber: formattedPhoneNumber,
|
||||||
|
displayName: gymUser.name || '',
|
||||||
|
email: gymUser.email || null,
|
||||||
|
});
|
||||||
|
clientUid = newUser.uid;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Error creating authentication user:', error);
|
||||||
|
return res.status(500).json({
|
||||||
|
error: 'Failed to create authentication user',
|
||||||
|
details: error
|
||||||
});
|
});
|
||||||
uid = newUser.uid;
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating authentication user:', error);
|
|
||||||
return res.status(500).json({
|
|
||||||
error: 'Failed to create authentication user',
|
|
||||||
details: error
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
gymUser.uid = uid;
|
|
||||||
|
|
||||||
if (gymUser.name) {
|
|
||||||
gymUser.normalizedName = gymUser.name.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gymUser.dateOfBirth && !(typeof gymUser.dateOfBirth === 'string')) {
|
|
||||||
gymUser.dateOfBirth = new Date(gymUser.dateOfBirth).toISOString();
|
|
||||||
}
|
|
||||||
|
|
||||||
const clientData = {
|
|
||||||
...gymUser,
|
|
||||||
};
|
|
||||||
|
|
||||||
await admin.firestore().collection('client_profile').doc(uid).set(clientData);
|
|
||||||
|
|
||||||
return res.status(201).json({
|
|
||||||
success: true,
|
|
||||||
message: 'Client registered successfully',
|
|
||||||
clientId: uid
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating client profile:', error);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!gymUser.uid) {
|
gymUser.uid = clientUid;
|
||||||
await admin.auth().deleteUser(uid);
|
gymUser.registeredBy = uid;
|
||||||
|
|
||||||
|
if (gymUser.name) {
|
||||||
|
gymUser.normalizedName = gymUser.name.toLowerCase();
|
||||||
}
|
}
|
||||||
} catch (deleteError) {
|
|
||||||
console.error('Error deleting auth user after failed profile creation:', deleteError);
|
if (gymUser.dateOfBirth && !(typeof gymUser.dateOfBirth === 'string')) {
|
||||||
|
gymUser.dateOfBirth = new Date(gymUser.dateOfBirth).toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const clientData = {
|
||||||
|
...gymUser,
|
||||||
|
phoneNumber: formattedPhoneNumber,
|
||||||
|
};
|
||||||
|
|
||||||
|
await admin.firestore().collection('client_profile').doc(clientUid).set(clientData);
|
||||||
|
|
||||||
|
return res.status(201).json({
|
||||||
|
success: true,
|
||||||
|
message: 'Client registered successfully',
|
||||||
|
clientId: clientUid
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Error creating client profile:', error);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!gymUser.uid) {
|
||||||
|
await admin.auth().deleteUser(clientUid);
|
||||||
|
}
|
||||||
|
} catch (deleteError) {
|
||||||
|
logger.error('Error deleting auth user after failed profile creation:', deleteError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(500).json({
|
||||||
|
error: 'Failed to create client profile',
|
||||||
|
details: error
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(500).json({
|
} catch (authError) {
|
||||||
error: 'Failed to create client profile',
|
logger.error('Authentication error:', authError);
|
||||||
details: error
|
return res.status(401).json({ error: 'Unauthorized. Invalid token.' });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Unexpected error in client registration:', error);
|
logger.error('Unexpected error in client registration:', error);
|
||||||
return res.status(500).json({
|
return res.status(500).json({
|
||||||
error: 'Internal server error',
|
error: 'Internal server error',
|
||||||
details: error
|
details: error
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user