diff --git a/functions/src/clientRegistration/clientRegistration.ts b/functions/src/clientRegistration/clientRegistration.ts new file mode 100644 index 0000000..08dbe19 --- /dev/null +++ b/functions/src/clientRegistration/clientRegistration.ts @@ -0,0 +1,96 @@ +import { onRequest } from "firebase-functions/v2/https"; +import { getAdmin } from "../shared/config"; +import { getCorsHandler } from "../shared/middleware"; + + +const corsHandler = getCorsHandler(); +const admin = getAdmin(); +export const registerClient = onRequest({ + region: '#{SERVICES_RGN}#' +}, async (req, res) => { + return corsHandler(req, res, async () => { + try { + if (req.method !== 'POST') { + return res.status(405).json({ error: 'Method not allowed. Please use POST.' }); + } + + const gymUser = req.body; + if (!gymUser.phoneNumber) { + return res.status(400).json({ error: 'Phone number is required' }); + } + + const isdCode = gymUser.isdCode || '+1'; + const formattedPhoneNumber = gymUser.phoneNumber.startsWith('+') + ? gymUser.phoneNumber + : `${isdCode}${gymUser.phoneNumber}`; + + let uid; + try { + const userRecord = await admin.auth().getUserByPhoneNumber(formattedPhoneNumber) + .catch(() => null); + + if (userRecord) { + uid = userRecord.uid; + } else { + const newUser = await admin.auth().createUser({ + phoneNumber: formattedPhoneNumber, + displayName: gymUser.name || '', + email: gymUser.email || null, + }); + 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 { + if (!gymUser.uid) { + await admin.auth().deleteUser(uid); + } + } catch (deleteError) { + console.error('Error deleting auth user after failed profile creation:', deleteError); + } + + return res.status(500).json({ + error: 'Failed to create client profile', + details: error + }); + } + } catch (error) { + console.error('Unexpected error in client registration:', error); + return res.status(500).json({ + error: 'Internal server error', + details: error + }); + } + }); +}); diff --git a/functions/src/clientRegistration/index.ts b/functions/src/clientRegistration/index.ts new file mode 100644 index 0000000..1f2445e --- /dev/null +++ b/functions/src/clientRegistration/index.ts @@ -0,0 +1 @@ +export { registerClient } from './clientRegistration'; \ No newline at end of file diff --git a/functions/src/email/sendEmail.ts b/functions/src/email/sendEmail.ts index d7b366f..4200b76 100644 --- a/functions/src/email/sendEmail.ts +++ b/functions/src/email/sendEmail.ts @@ -1,13 +1,14 @@ import { onRequest } from "firebase-functions/v2/https"; import { Request } from "firebase-functions/v2/https"; -import { corsHandler } from "../shared/middleware"; -import { logger } from "../shared/config"; +import { getCorsHandler } from "../shared/middleware"; +import { getLogger } from "../shared/config"; import formData from 'form-data'; import Mailgun from 'mailgun.js'; const { convert } = require('html-to-text'); const mailgun = new Mailgun(formData); - +const logger = getLogger(); +const corsHandler = getCorsHandler(); export const sendEmailMessage = onRequest({ region: '#{SERVICES_RGN}#' }, (request: Request, response) => { diff --git a/functions/src/email/sendEmailWithAttachment.ts b/functions/src/email/sendEmailWithAttachment.ts index 545112a..7c1bc74 100644 --- a/functions/src/email/sendEmailWithAttachment.ts +++ b/functions/src/email/sendEmailWithAttachment.ts @@ -4,14 +4,15 @@ import * as os from 'os'; import * as path from 'path'; import * as fs from 'fs'; import * as https from 'https'; -import { corsHandler } from "../shared/middleware"; -import { logger } from "../shared/config"; +import { getCorsHandler } from "../shared/middleware"; +import { getLogger } from "../shared/config"; import formData from 'form-data'; import Mailgun from 'mailgun.js'; const { convert } = require('html-to-text'); const mailgun = new Mailgun(formData); - +const logger = getLogger(); +const corsHandler = getCorsHandler(); export const sendEmailWithAttachment = onRequest({ region: '#{SERVICES_RGN}#' }, async (request: Request, response) => { diff --git a/functions/src/index.ts b/functions/src/index.ts index cf82272..692183f 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -5,3 +5,4 @@ export { sendSMSMessage } from './sms'; export { processNotificationOnCreate } from './notifications'; export { createCashfreeLink, createCashfreeOrder, verifyCashfreePayment } from './payments'; export { getPlaceDetails, getPlacesAutocomplete } from './places'; +export { registerClient } from './clientRegistration'; \ No newline at end of file diff --git a/functions/src/payments/cashfree/createOrder.ts b/functions/src/payments/cashfree/createOrder.ts index ef29814..6f57b8f 100644 --- a/functions/src/payments/cashfree/createOrder.ts +++ b/functions/src/payments/cashfree/createOrder.ts @@ -1,9 +1,11 @@ import { onRequest } from "firebase-functions/v2/https"; import { Request } from "firebase-functions/v2/https"; -import { corsHandler } from "../../shared/middleware"; -import { admin, logger } from "../../shared/config"; +import { getCorsHandler } from "../../shared/middleware"; +import { getAdmin, getLogger } from "../../shared/config"; import axios from "axios"; - +const admin = getAdmin(); +const logger = getLogger(); +const corsHandler = getCorsHandler(); interface CashfreeOrderRequest { amount: number; customerName?: string; diff --git a/functions/src/payments/cashfree/verifyPayment.ts b/functions/src/payments/cashfree/verifyPayment.ts index 1218665..ac5f1c1 100644 --- a/functions/src/payments/cashfree/verifyPayment.ts +++ b/functions/src/payments/cashfree/verifyPayment.ts @@ -1,9 +1,11 @@ import { onRequest } from "firebase-functions/v2/https"; import { Request } from "firebase-functions/v2/https"; -import { corsHandler } from "../../shared/middleware"; -import { admin, logger } from "../../shared/config"; +import { getCorsHandler } from "../../shared/middleware"; +import { getAdmin, getLogger } from "../../shared/config"; import axios from "axios"; - +const logger = getLogger(); +const corsHandler = getCorsHandler(); +const admin = getAdmin(); interface CashfreePaymentResponse { order_status: string; [key: string]: any;