diff --git a/functions/src/index.ts b/functions/src/index.ts index c5f1c80..db89fe4 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -9,7 +9,7 @@ import * as path from 'path'; import * as fs from 'fs'; import * as https from 'https'; import axios from "axios"; - +import { getStorage } from 'firebase-admin/storage'; const formData = require('form-data'); const Mailgun = require('mailgun.js'); const { convert } = require('html-to-text'); @@ -79,6 +79,42 @@ export const sendEmailWithAttachment = onRequest({ response.status(500).json({ success: false, error: error instanceof Error ? error.message : String(error) }); } }); + +export const accessFile = onRequest({ + region: '#{SERVICES_RGN}#' +}, async (request: Request, response: express.Response) => { + try { + const filePath = request.query.path as string; + if (!filePath) { + response.status(400).send('File path is required'); + return; + } + + const expirationMs = 60 * 60 * 1000; + + const bucket = getStorage().bucket(); + const file = bucket.file(filePath); + + const [exists] = await file.exists(); + if (!exists) { + response.status(404).send('File not found'); + return; + } + + const [signedUrl] = await file.getSignedUrl({ + action: 'read', + expires: Date.now() + expirationMs, + responseDisposition: `attachment; filename="${path.basename(filePath)}"`, + }); + + response.redirect(signedUrl); + logger.info(`File access redirect for ${filePath}`); + } catch (error) { + logger.error('Error accessing file:', error); + response.status(500).send('Error accessing file'); + } +}); + export const sendEmailMessage = onRequest({ region: process.env.SERVICES_RGN }, (request: Request, response: express.Response) => { @@ -220,12 +256,12 @@ export const createCashfreeOrder = onRequest({ const decodedToken = await admin.auth().verifyIdToken(idToken); const uid = decodedToken.uid; - const { - amount, - customerName, - customerEmail, - customerPhone, - productInfo + const { + amount, + customerName, + customerEmail, + customerPhone, + productInfo } = request.body; if (!amount || !customerEmail || !customerPhone) { @@ -236,13 +272,13 @@ export const createCashfreeOrder = onRequest({ const clientId = process.env.CASHFREE_CLIENT_ID; const clientSecret = process.env.CASHFREE_CLIENT_SECRET; const isTest = true; - - const apiUrl = isTest + + const apiUrl = isTest ? 'https://sandbox.cashfree.com/pg/orders' : 'https://api.cashfree.com/pg/orders'; - + const orderId = `order_${Date.now()}_${uid.substring(0, 6)}`; - + const cashfreeResponse = await axios.post( apiUrl, { @@ -270,7 +306,7 @@ export const createCashfreeOrder = onRequest({ } } ); - + await admin.firestore().collection('payment_orders').doc(orderId).set({ userId: uid, amount: amount, @@ -281,16 +317,16 @@ export const createCashfreeOrder = onRequest({ createdAt: new Date(), ...cashfreeResponse.data }); - + response.json({ order_id: cashfreeResponse.data.order_id, payment_session_id: cashfreeResponse.data.payment_session_id }); - + logger.info(`Cashfree order created: ${orderId}`); } catch (error: any) { logger.error('Cashfree order creation error:', error); - response.status(500).json({ + response.status(500).json({ error: 'Failed to create payment order', details: error.response?.data || error.message }); @@ -302,20 +338,20 @@ export const verifyCashfreePayment = onRequest({ }, async (request: Request, response: express.Response) => { try { const orderId = request.body.order_id || request.query.order_id; - + if (!orderId) { response.status(400).json({ error: 'Order ID is required' }); return; } - + const clientId = process.env.CASHFREE_CLIENT_ID; const clientSecret = process.env.CASHFREE_CLIENT_SECRET; const isTest = process.env.CASHFREE_ENVIRONMENT !== 'production'; - - const apiUrl = isTest + + const apiUrl = isTest ? `https://sandbox.cashfree.com/pg/orders/${orderId}` : `https://api.cashfree.com/pg/orders/${orderId}`; - + const cashfreeResponse = await axios.get( apiUrl, { @@ -326,27 +362,27 @@ export const verifyCashfreePayment = onRequest({ } } ); - + await admin.firestore().collection('payment_orders').doc(orderId).update({ orderStatus: cashfreeResponse.data.order_status, paymentDetails: cashfreeResponse.data, updatedAt: new Date() }); - + if (request.headers['x-webhook-source'] === 'cashfree') { response.status(200).send('OK'); return; } - + response.json({ status: cashfreeResponse.data.order_status, paymentDetails: cashfreeResponse.data }); - + logger.info(`Cashfree payment verified: ${orderId}`); } catch (error: any) { logger.error('Cashfree payment verification error:', error); - response.status(500).json({ + response.status(500).json({ error: 'Failed to verify payment status', details: error.response?.data || error.message });