diff --git a/server.js b/server.js index 66e665e79..1eaa4b8ec 100644 --- a/server.js +++ b/server.js @@ -51,6 +51,12 @@ app.use(bodyParser.json({limit: "50mb"})); app.use(bodyParser.urlencoded({limit: "50mb", extended: true})); app.use(cors({credentials: true, exposedHeaders: ["set-cookie"]})); +// Helper middleware +app.use((req, res, next) => { + req.logger = logger; + next(); +}); + // Route groupings app.use('/', require("./server/routes/miscellaneousRoutes")); app.use("/notifications", require("./server/routes/notificationsRoutes")); @@ -85,4 +91,4 @@ main() }) .catch((error) => { logger.log(`[${process.env.NODE_ENV || "DEVELOPMENT"}] Server failed to start on port ${port}`, "ERROR", "api", error); -}); \ No newline at end of file + }); \ No newline at end of file diff --git a/server/email/sendemail.js b/server/email/sendemail.js index 640d24f2e..170504ce2 100644 --- a/server/email/sendemail.js +++ b/server/email/sendemail.js @@ -1,269 +1,269 @@ const path = require("path"); require("dotenv").config({ - path: path.resolve( - process.cwd(), - `.env.${process.env.NODE_ENV || "development"}` - ), + path: path.resolve( + process.cwd(), + `.env.${process.env.NODE_ENV || "development"}` + ), }); const axios = require("axios"); let nodemailer = require("nodemailer"); let aws = require("@aws-sdk/client-ses"); -let { defaultProvider } = require("@aws-sdk/credential-provider-node"); +let {defaultProvider} = require("@aws-sdk/credential-provider-node"); const logger = require("../utils/logger"); const client = require("../graphql-client/graphql-client").client; const queries = require("../graphql-client/queries"); const ses = new aws.SES({ - // The key apiVersion is no longer supported in v3, and can be removed. - // @deprecated The client uses the "latest" apiVersion. - apiVersion: "latest", - region: "ca-central-1", - defaultProvider + // The key apiVersion is no longer supported in v3, and can be removed. + // @deprecated The client uses the "latest" apiVersion. + apiVersion: "latest", + region: "ca-central-1", + defaultProvider }); let transporter = nodemailer.createTransport({ - SES: { ses, aws }, + SES: {ses, aws}, }); -exports.sendServerEmail = async function ({ subject, text }) { - if (process.env.NODE_ENV === undefined) return; - try { - transporter.sendMail( - { - from: `ImEX Online API - ${process.env.NODE_ENV} `, - to: ["patrick@imexsystems.ca", "support@thinkimex.com"], - subject: subject, - text: text, - ses: { - // optional extra arguments for SendRawEmail - Tags: [ +exports.sendServerEmail = async function ({subject, text}) { + if (process.env.NODE_ENV === undefined) return; + try { + transporter.sendMail( { - Name: "tag_name", - Value: "tag_value", + from: `ImEX Online API - ${process.env.NODE_ENV} `, + to: ["patrick@imexsystems.ca", "support@thinkimex.com"], + subject: subject, + text: text, + ses: { + // optional extra arguments for SendRawEmail + Tags: [ + { + Name: "tag_name", + Value: "tag_value", + }, + ], + }, }, - ], - }, - }, - (err, info) => { - console.log(err || info); - } - ); - } catch (error) { - console.log(error); - logger.log("server-email-failure", "error", null, null, error); - } + (err, info) => { + console.log(err || info); + } + ); + } catch (error) { + console.log(error); + logger.log("server-email-failure", "error", null, null, error); + } }; -exports.sendTaskEmail = async function ({ to, subject, text, attachments }) { - try { - transporter.sendMail( - { - from: `ImEX Online `, - to: to, - subject: subject, - text: text, - attachments: attachments || null, - }, - (err, info) => { - console.log(err || info); - } - ); - } catch (error) { - console.log(error); - logger.log("server-email-failure", "error", null, null, error); - } +exports.sendTaskEmail = async function ({to, subject, text, attachments}) { + try { + transporter.sendMail( + { + from: `ImEX Online `, + to: to, + subject: subject, + text: text, + attachments: attachments || null, + }, + (err, info) => { + console.log(err || info); + } + ); + } catch (error) { + console.log(error); + logger.log("server-email-failure", "error", null, null, error); + } }; exports.sendEmail = async (req, res) => { - logger.log("send-email", "DEBUG", req.user.email, null, { - from: `${req.body.from.name} <${req.body.from.address}>`, - replyTo: req.body.ReplyTo.Email, - to: req.body.to, - cc: req.body.cc, - subject: req.body.subject, - }); + logger.log("send-email", "DEBUG", req.user.email, null, { + from: `${req.body.from.name} <${req.body.from.address}>`, + replyTo: req.body.ReplyTo.Email, + to: req.body.to, + cc: req.body.cc, + subject: req.body.subject, + }); - let downloadedMedia = []; - if (req.body.media && req.body.media.length > 0) { - downloadedMedia = await Promise.all( - req.body.media.map((m) => { - try { - return getImage(m); - } catch (error) { - logger.log("send-email-error", "ERROR", req.user.email, null, { + let downloadedMedia = []; + if (req.body.media && req.body.media.length > 0) { + downloadedMedia = await Promise.all( + req.body.media.map((m) => { + try { + return getImage(m); + } catch (error) { + logger.log("send-email-error", "ERROR", req.user.email, null, { + from: `${req.body.from.name} <${req.body.from.address}>`, + replyTo: req.body.ReplyTo.Email, + to: req.body.to, + cc: req.body.cc, + subject: req.body.subject, + error, + }); + } + }) + ); + } + + transporter.sendMail( + { from: `${req.body.from.name} <${req.body.from.address}>`, replyTo: req.body.ReplyTo.Email, to: req.body.to, cc: req.body.cc, subject: req.body.subject, - error, - }); + attachments: + [ + ...((req.body.attachments && + req.body.attachments.map((a) => { + return { + filename: a.filename, + path: a.path, + }; + })) || + []), + ...downloadedMedia.map((a) => { + return { + path: a, + }; + }), + ] || null, + html: req.body.html, + ses: { + // optional extra arguments for SendRawEmail + Tags: [ + { + Name: "tag_name", + Value: "tag_value", + }, + ], + }, + }, + (err, info) => { + console.log(err || info); + if (info) { + logger.log("send-email-success", "DEBUG", req.user.email, null, { + from: `${req.body.from.name} <${req.body.from.address}>`, + replyTo: req.body.ReplyTo.Email, + to: req.body.to, + cc: req.body.cc, + subject: req.body.subject, + // info, + }); + logEmail(req, { + to: req.body.to, + cc: req.body.cc, + subject: req.body.subject, + messageId: info.response, + }); + res.json({ + success: true, //response: info + }); + } else { + logger.log("send-email-failure", "ERROR", req.user.email, null, { + from: `${req.body.from.name} <${req.body.from.address}>`, + replyTo: req.body.ReplyTo.Email, + to: req.body.to, + cc: req.body.cc, + subject: req.body.subject, + error: err, + }); + logEmail(req, { + to: req.body.to, + cc: req.body.cc, + subject: req.body.subject, + bodyshopid: req.body.bodyshopid, + }); + res.status(500).json({success: false, error: err}); + } } - }) ); - } - - transporter.sendMail( - { - from: `${req.body.from.name} <${req.body.from.address}>`, - replyTo: req.body.ReplyTo.Email, - to: req.body.to, - cc: req.body.cc, - subject: req.body.subject, - attachments: - [ - ...((req.body.attachments && - req.body.attachments.map((a) => { - return { - filename: a.filename, - path: a.path, - }; - })) || - []), - ...downloadedMedia.map((a) => { - return { - path: a, - }; - }), - ] || null, - html: req.body.html, - ses: { - // optional extra arguments for SendRawEmail - Tags: [ - { - Name: "tag_name", - Value: "tag_value", - }, - ], - }, - }, - (err, info) => { - console.log(err || info); - if (info) { - logger.log("send-email-success", "DEBUG", req.user.email, null, { - from: `${req.body.from.name} <${req.body.from.address}>`, - replyTo: req.body.ReplyTo.Email, - to: req.body.to, - cc: req.body.cc, - subject: req.body.subject, - // info, - }); - logEmail(req, { - to: req.body.to, - cc: req.body.cc, - subject: req.body.subject, - messageId: info.response, - }); - res.json({ - success: true, //response: info - }); - } else { - logger.log("send-email-failure", "ERROR", req.user.email, null, { - from: `${req.body.from.name} <${req.body.from.address}>`, - replyTo: req.body.ReplyTo.Email, - to: req.body.to, - cc: req.body.cc, - subject: req.body.subject, - error: err, - }); - logEmail(req, { - to: req.body.to, - cc: req.body.cc, - subject: req.body.subject, - bodyshopid: req.body.bodyshopid, - }); - res.status(500).json({ success: false, error: err }); - } - } - ); }; async function getImage(imageUrl) { - let image = await axios.get(imageUrl, { responseType: "arraybuffer" }); - let raw = Buffer.from(image.data).toString("base64"); - return "data:" + image.headers["content-type"] + ";base64," + raw; + let image = await axios.get(imageUrl, {responseType: "arraybuffer"}); + let raw = Buffer.from(image.data).toString("base64"); + return "data:" + image.headers["content-type"] + ";base64," + raw; } async function logEmail(req, email) { - try { - const insertresult = await client.request(queries.INSERT_EMAIL_AUDIT, { - email: { - to: email.to, - cc: email.cc, - subject: email.subject, - bodyshopid: req.body.bodyshopid, - useremail: req.user.email, - contents: req.body.html, - jobid: req.body.jobid, - sesmessageid: email.messageId, - status: "Sent", - }, - }); - console.log(insertresult); - } catch (error) { - logger.log("email-log-error", "error", req.user.email, null, { - from: `${req.body.from.name} <${req.body.from.address}>`, - to: req.body.to, - cc: req.body.cc, - subject: req.body.subject, - // info, - }); - } + try { + const insertresult = await client.request(queries.INSERT_EMAIL_AUDIT, { + email: { + to: email.to, + cc: email.cc, + subject: email.subject, + bodyshopid: req.body.bodyshopid, + useremail: req.user.email, + contents: req.body.html, + jobid: req.body.jobid, + sesmessageid: email.messageId, + status: "Sent", + }, + }); + console.log(insertresult); + } catch (error) { + logger.log("email-log-error", "error", req.user.email, null, { + from: `${req.body.from.name} <${req.body.from.address}>`, + to: req.body.to, + cc: req.body.cc, + subject: req.body.subject, + // info, + }); + } } -exports.emailBounce = async function (req, res, next) { - try { - const body = JSON.parse(req.body); - if (body.Type === "SubscriptionConfirmation") { - logger.log("SNS-message", "DEBUG", "api", null, { - body: req.body, - }); - } - const message = JSON.parse(body.Message); - if (message.notificationType === "Bounce") { - let replyTo, subject, messageId; - message.mail.headers.forEach((header) => { - if (header.name === "Reply-To") { - replyTo = header.value; - } else if (header.name === "Subject") { - subject = header.value; +exports.emailBounce = async function (req, res) { + try { + const body = JSON.parse(req.body); + if (body.Type === "SubscriptionConfirmation") { + logger.log("SNS-message", "DEBUG", "api", null, { + body: req.body, + }); } - }); - messageId = message.mail.messageId; - if (replyTo === "noreply@imex.online") { - res.sendStatus(200); - return; - } - //If it's bounced, log it as bounced in audit log. Send an email to the user. - const result = await client.request(queries.UPDATE_EMAIL_AUDIT, { - sesid: messageId, - status: "Bounced", - context: message.bounce?.bouncedRecipients, - }); - transporter.sendMail( - { - from: `ImEX Online `, - to: replyTo, - //bcc: "patrick@snapt.ca", - subject: `ImEX Online Bounced Email - RE: ${subject}`, - text: `ImEX Online has tried to deliver an email with the subject: ${subject} to the intended recipients but encountered an error. + const message = JSON.parse(body.Message); + if (message.notificationType === "Bounce") { + let replyTo, subject, messageId; + message.mail.headers.forEach((header) => { + if (header.name === "Reply-To") { + replyTo = header.value; + } else if (header.name === "Subject") { + subject = header.value; + } + }); + messageId = message.mail.messageId; + if (replyTo === "noreply@imex.online") { + res.sendStatus(200); + return; + } + //If it's bounced, log it as bounced in audit log. Send an email to the user. + const result = await client.request(queries.UPDATE_EMAIL_AUDIT, { + sesid: messageId, + status: "Bounced", + context: message.bounce?.bouncedRecipients, + }); + transporter.sendMail( + { + from: `ImEX Online `, + to: replyTo, + //bcc: "patrick@snapt.ca", + subject: `ImEX Online Bounced Email - RE: ${subject}`, + text: `ImEX Online has tried to deliver an email with the subject: ${subject} to the intended recipients but encountered an error. ${body.bounce?.bouncedRecipients.map( - (r) => - `Recipient: ${r.emailAddress} | Status: ${r.action} | Code: ${r.diagnosticCode} + (r) => + `Recipient: ${r.emailAddress} | Status: ${r.action} | Code: ${r.diagnosticCode} ` -)} + )} `, - }, - (err, info) => { - console.log("***", err || info); + }, + (err, info) => { + console.log("***", err || info); + } + ); } - ); + } catch (error) { + logger.log("sns-error", "ERROR", "api", null, { + error: JSON.stringify(error), + }); } - } catch (error) { - logger.log("sns-error", "ERROR", "api", null, { - error: JSON.stringify(error), - }); - } - res.sendStatus(200); + res.sendStatus(200); }; diff --git a/server/firebase/firebase-handler.js b/server/firebase/firebase-handler.js index e203bcbf3..d8cf63fb6 100644 --- a/server/firebase/firebase-handler.js +++ b/server/firebase/firebase-handler.js @@ -1,287 +1,215 @@ -var admin = require("firebase-admin"); +const admin = require("firebase-admin"); const logger = require("../utils/logger"); const path = require("path"); -const { auth } = require("firebase-admin"); +const {auth} = require("firebase-admin"); + require("dotenv").config({ - path: path.resolve( - process.cwd(), - `.env.${process.env.NODE_ENV || "development"}` - ), + path: path.resolve( + process.cwd(), + `.env.${process.env.NODE_ENV || "development"}` + ), }); const client = require("../graphql-client/graphql-client").client; -var serviceAccount = require(process.env.FIREBASE_ADMINSDK_JSON); + +const serviceAccount = require(process.env.FIREBASE_ADMINSDK_JSON); +const adminEmail = require("../utils/adminEmail"); admin.initializeApp({ - credential: admin.credential.cert(serviceAccount), - databaseURL: process.env.FIREBASE_DATABASE_URL, + credential: admin.credential.cert(serviceAccount), + databaseURL: process.env.FIREBASE_DATABASE_URL, }); exports.admin = admin; -const adminEmail = [ - "patrick@imex.dev", - //"patrick@imex.test", - "patrick@imex.prod", - "patrick@imexsystems.ca", - "patrick@thinkimex.com", -]; - exports.createUser = async (req, res) => { - logger.log("admin-create-user", "ADMIN", req.user.email, null, { - request: req.body, - ioadmin: true, - }); + logger.log("admin-create-user", "ADMIN", req.user.email, null, { + request: req.body, + ioadmin: true, + }); - const { email, displayName, password, shopid, authlevel } = req.body; - try { - const userRecord = await admin - .auth() - .createUser({ email, displayName, password }); + const {email, displayName, password, shopid, authlevel} = req.body; + try { + const userRecord = await admin + .auth() + .createUser({email, displayName, password}); - // See the UserRecord reference doc for the contents of userRecord. + // See the UserRecord reference doc for the contents of userRecord. - const result = await client.request( - ` + const result = await client.request( + ` mutation INSERT_USER($user: users_insert_input!) { insert_users_one(object: $user) { email } } `, - { - user: { - email: email.toLowerCase(), - authid: userRecord.uid, - associations: { - data: [{ shopid, authlevel, active: true }], - }, - }, - } - ); + { + user: { + email: email.toLowerCase(), + authid: userRecord.uid, + associations: { + data: [{shopid, authlevel, active: true}], + }, + }, + } + ); - res.json({ userRecord, result }); - } catch (error) { - logger.log("admin-update-user-error", "ERROR", req.user.email, null, { - error, - }); - res.status(500).json(error); - } + res.json({userRecord, result}); + } catch (error) { + logger.log("admin-update-user-error", "ERROR", req.user.email, null, { + error, + }); + res.status(500).json(error); + } }; exports.updateUser = (req, res) => { - logger.log("admin-update-user", "ADMIN", req.user.email, null, { - request: req.body, - ioadmin: true, - }); - - if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) { - logger.log( - "admin-update-user-unauthorized", - "ERROR", - req.user.email, - null, - { + logger.log("admin-update-user", "ADMIN", req.user.email, null, { request: req.body, - user: req.user, - } - ); - res.sendStatus(404); - return; - } - - admin - .auth() - .updateUser( - req.body.uid, - req.body.user - // { - // email: "modifiedUser@example.com", - // phoneNumber: "+11234567890", - // emailVerified: true, - // password: "newPassword", - // displayName: "Jane Doe", - // photoURL: "http://www.example.com/12345678/photo.png", - // disabled: true, - // } - ) - .then((userRecord) => { - // See the UserRecord reference doc for the contents of userRecord. - - logger.log("admin-update-user-success", "ADMIN", req.user.email, null, { - userRecord, ioadmin: true, - }); - res.json(userRecord); - }) - .catch((error) => { - logger.log("admin-update-user-error", "ERROR", req.user.email, null, { - error, - }); - res.status(500).json(error); }); + + if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) { + logger.log( + "admin-update-user-unauthorized", + "ERROR", + req.user.email, + null, + { + request: req.body, + user: req.user, + } + ); + res.sendStatus(404); + return; + } + + admin + .auth() + .updateUser( + req.body.uid, + req.body.user + // { + // email: "modifiedUser@example.com", + // phoneNumber: "+11234567890", + // emailVerified: true, + // password: "newPassword", + // displayName: "Jane Doe", + // photoURL: "http://www.example.com/12345678/photo.png", + // disabled: true, + // } + ) + .then((userRecord) => { + // See the UserRecord reference doc for the contents of userRecord. + + logger.log("admin-update-user-success", "ADMIN", req.user.email, null, { + userRecord, + ioadmin: true, + }); + res.json(userRecord); + }) + .catch((error) => { + logger.log("admin-update-user-error", "ERROR", req.user.email, null, { + error, + }); + res.status(500).json(error); + }); }; exports.getUser = (req, res) => { - logger.log("admin-get-user", "ADMIN", req.user.email, null, { - request: req.body, - ioadmin: true, - }); - - if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) { - logger.log( - "admin-update-user-unauthorized", - "ERROR", - req.user.email, - null, - { + logger.log("admin-get-user", "ADMIN", req.user.email, null, { request: req.body, - user: req.user, - } - ); - res.sendStatus(404); - return; - } - - admin - .auth() - .getUser(req.body.uid) - .then((userRecord) => { - res.json(userRecord); - }) - .catch((error) => { - logger.log("admin-get-user-error", "ERROR", req.user.email, null, { - error, - }); - res.status(500).json(error); + ioadmin: true, }); + + if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) { + logger.log( + "admin-update-user-unauthorized", + "ERROR", + req.user.email, + null, + { + request: req.body, + user: req.user, + } + ); + res.sendStatus(404); + return; + } + + admin + .auth() + .getUser(req.body.uid) + .then((userRecord) => { + res.json(userRecord); + }) + .catch((error) => { + logger.log("admin-get-user-error", "ERROR", req.user.email, null, { + error, + }); + res.status(500).json(error); + }); }; exports.sendNotification = async (req, res) => { - setTimeout(() => { - // Send a message to the device corresponding to the provided - // registration token. - admin - .messaging() - .send({ - topic: "PRD_PATRICK-messaging", - notification: { - title: `ImEX Online Message - +16049992002`, - body: "Test Noti.", - //imageUrl: "https://thinkimex.com/img/io-fcm.png", - }, - data: { - type: "messaging-inbound", - conversationid: "e0eb17c3-3a78-4e3f-b932-55ef35aa2297", - text: "Hello. ", - image_path: "", - phone_num: "+16049992002", - }, - }) - .then((response) => { - // Response is a message ID string. - console.log("Successfully sent message:", response); - }) - .catch((error) => { - console.log("Error sending message:", error); - }); + setTimeout(() => { + // Send a message to the device corresponding to the provided + // registration token. + admin + .messaging() + .send({ + topic: "PRD_PATRICK-messaging", + notification: { + title: `ImEX Online Message - +16049992002`, + body: "Test Noti.", + //imageUrl: "https://thinkimex.com/img/io-fcm.png", + }, + data: { + type: "messaging-inbound", + conversationid: "e0eb17c3-3a78-4e3f-b932-55ef35aa2297", + text: "Hello. ", + image_path: "", + phone_num: "+16049992002", + }, + }) + .then((response) => { + // Response is a message ID string. + console.log("Successfully sent message:", response); + }) + .catch((error) => { + console.log("Error sending message:", error); + }); - res.sendStatus(200); - }, 500); + res.sendStatus(200); + }, 500); }; exports.subscribe = async (req, res) => { - const result = await admin - .messaging() - .subscribeToTopic( - req.body.fcm_tokens, - `${req.body.imexshopid}-${req.body.type}` - ); + const result = await admin + .messaging() + .subscribeToTopic( + req.body.fcm_tokens, + `${req.body.imexshopid}-${req.body.type}` + ); - res.json(result); + res.json(result); }; exports.unsubscribe = async (req, res) => { - try { - const result = await admin - .messaging() - .unsubscribeFromTopic( - req.body.fcm_tokens, - `${req.body.imexshopid}-${req.body.type}` - ); + try { + const result = await admin + .messaging() + .unsubscribeFromTopic( + req.body.fcm_tokens, + `${req.body.imexshopid}-${req.body.type}` + ); - res.json(result); - } catch (error) { - res.sendStatus(500); - } + res.json(result); + } catch (error) { + res.sendStatus(500); + } }; -exports.validateFirebaseIdToken = async (req, res, next) => { - if ( - (!req.headers.authorization || - !req.headers.authorization.startsWith("Bearer ")) && - !(req.cookies && req.cookies.__session) - ) { - console.error("Unauthorized attempt. No authorization provided."); - res.status(403).send("Unauthorized"); - return; - } - - let idToken; - if ( - req.headers.authorization && - req.headers.authorization.startsWith("Bearer ") - ) { - // console.log('Found "Authorization" header'); - // Read the ID Token from the Authorization header. - idToken = req.headers.authorization.split("Bearer ")[1]; - } else if (req.cookies) { - //console.log('Found "__session" cookie'); - // Read the ID Token from cookie. - idToken = req.cookies.__session; - } else { - // No cookie - console.error("Unauthorized attempt. No cookie provided."); - logger.log("api-unauthorized-call", "WARN", null, null, { - req, - type: "no-cookie", - }); - res.status(403).send("Unauthorized"); - return; - } - - try { - const decodedIdToken = await admin.auth().verifyIdToken(idToken); - //console.log("ID Token correctly decoded", decodedIdToken); - req.user = decodedIdToken; - next(); - return; - } catch (error) { - logger.log("api-unauthorized-call", "WARN", null, null, { - path: req.path, - body: req.body, - - type: "unauthroized", - ...error, - }); - - res.status(401).send("Unauthorized"); - return; - } -}; - -exports.validateAdmin = async (req, res, next) => { - if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) { - logger.log("admin-validation-failed", "ERROR", req.user.email, null, { - request: req.body, - user: req.user, - }); - res.sendStatus(404); - return; - } else { - next(); - return; - } -}; //Admin claims code. // const uid = "JEqqYlsadwPEXIiyRBR55fflfko1"; diff --git a/server/job/job-costing.js b/server/job/job-costing.js index e7568fa72..4c23538cc 100644 --- a/server/job/job-costing.js +++ b/server/job/job-costing.js @@ -13,6 +13,7 @@ async function JobCosting(req, res) { const { jobid } = req.body; const BearerToken = req.headers.authorization; + logger.log("job-costing-start", "DEBUG", req.user.email, jobid, null); const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, { headers: { diff --git a/server/job/job-lifecycle.js b/server/job/job-lifecycle.js index 3834bf1cb..61e3703fb 100644 --- a/server/job/job-lifecycle.js +++ b/server/job/job-lifecycle.js @@ -1,5 +1,17 @@ +const _ = require("lodash"); const jobLifecycle = (req, res) => { - return res.status(200).send("jobLifecycle"); + const {jobids} = req.body; + return _.isArray(jobids) ? + handleMultipleJobs(jobids, req, res) : + handleSingleJob(jobids, req, res); }; +const handleMultipleJobs = (jobIDs, req, res) => { + return res.status(200).send(jobIDs); +} + +const handleSingleJob = (req, res) => { + return res.status(200).send(req.body); +} + module.exports = jobLifecycle; \ No newline at end of file diff --git a/server/job/job-status-transition.js b/server/job/job-status-transition.js index 294ab395d..960041746 100644 --- a/server/job/job-status-transition.js +++ b/server/job/job-status-transition.js @@ -9,89 +9,84 @@ const logger = require("../utils/logger"); Dinero.globalRoundingMode = "HALF_EVEN"; const path = require("path"); const client = require("../graphql-client/graphql-client").client; + require("dotenv").config({ - path: path.resolve( - process.cwd(), - `.env.${process.env.NODE_ENV || "development"}` - ), + path: path.resolve( + process.cwd(), + `.env.${process.env.NODE_ENV || "development"}` + ), }); + async function StatusTransition(req, res) { - if (req.headers["event-secret"] !== process.env.EVENT_SECRET) { - res.status(401).send("Unauthorized"); - return; - } - - // return res.sendStatus(200); - - const { - id: jobid, - status: value, - shopid: bodyshopid, - } = req.body.event.data.new; + const { + id: jobid, + status: value, + shopid: bodyshopid, + } = req.body.event.data.new; // Create record OPEN on new item, enter state // If change to SCHEDULE, update the last record and create a new record (update status and end time on old record, create a new record saying we came from previous status going to previous status // (Timeline) // Final status is exported, there is no end date as there is no further transition (has no end date) - try { - const { update_transitions } = await client.request( - queries.UPDATE_OLD_TRANSITION, - { - jobid: jobid, - existingTransition: { - end: new Date(), - next_value: value, + try { + const {update_transitions} = await client.request( + queries.UPDATE_OLD_TRANSITION, + { + jobid: jobid, + existingTransition: { + end: new Date(), + next_value: value, - //duration - }, - } - ); + //duration + }, + } + ); - let duration = - update_transitions.affected_rows === 0 - ? 0 - : new Date(update_transitions.returning[0].end) - - new Date(update_transitions.returning[0].start); + let duration = + update_transitions.affected_rows === 0 + ? 0 + : new Date(update_transitions.returning[0].end) - + new Date(update_transitions.returning[0].start); - const resp2 = await client.request(queries.INSERT_NEW_TRANSITION, { - oldTransitionId: - update_transitions.affected_rows === 0 - ? null - : update_transitions.returning[0].id, - duration, - newTransition: { - bodyshopid: bodyshopid, - jobid: jobid, - start: - update_transitions.affected_rows === 0 - ? new Date() - : update_transitions.returning[0].end, - prev_value: - update_transitions.affected_rows === 0 - ? null - : update_transitions.returning[0].value, - value: value, - type: "status", - }, - }); + const resp2 = await client.request(queries.INSERT_NEW_TRANSITION, { + oldTransitionId: + update_transitions.affected_rows === 0 + ? null + : update_transitions.returning[0].id, + duration, + newTransition: { + bodyshopid: bodyshopid, + jobid: jobid, + start: + update_transitions.affected_rows === 0 + ? new Date() + : update_transitions.returning[0].end, + prev_value: + update_transitions.affected_rows === 0 + ? null + : update_transitions.returning[0].value, + value: value, + type: "status", + }, + }); - //Check to see if there is an existing status transition record. - //Query using Job ID, start is not null, end is null. + //Check to see if there is an existing status transition record. + //Query using Job ID, start is not null, end is null. - //If there is no existing record, this is the start of the transition life cycle. - // Create the initial transition record. + //If there is no existing record, this is the start of the transition life cycle. + // Create the initial transition record. - //If there is a current status transition record, update it with the end date, duration, and next value. + //If there is a current status transition record, update it with the end date, duration, and next value. - res.sendStatus(200); //.json(ret); - } catch (error) { - logger.log("job-status-transition-error", "ERROR", req.user?.email, jobid, { - message: error.message, - stack: error.stack, - }); + res.sendStatus(200); //.json(ret); + } catch (error) { + logger.log("job-status-transition-error", "ERROR", req.user?.email, jobid, { + message: error.message, + stack: error.stack, + }); - res.status(400).send(JSON.stringify(error)); - } + res.status(400).send(JSON.stringify(error)); + } } exports.statustransition = StatusTransition; diff --git a/server/middleware/eventAuthorizationMIddleware.js b/server/middleware/eventAuthorizationMIddleware.js new file mode 100644 index 000000000..8579a2e89 --- /dev/null +++ b/server/middleware/eventAuthorizationMIddleware.js @@ -0,0 +1,15 @@ +/** + * Checks if the event secret is correct + * @param req + * @param res + * @param next + */ +function eventAuthorizationMiddleware(req, res, next) { + if (req.headers["event-secret"] !== process.env.EVENT_SECRET) { + return res.status(401).send("Unauthorized"); + } + + next(); +} + +module.exports = eventAuthorizationMiddleware; \ No newline at end of file diff --git a/server/middleware/validateAdminMiddleware.js b/server/middleware/validateAdminMiddleware.js new file mode 100644 index 000000000..a93c7d659 --- /dev/null +++ b/server/middleware/validateAdminMiddleware.js @@ -0,0 +1,15 @@ +const logger = require("../utils/logger"); +const adminEmail = require("../utils/adminEmail"); + +const validateAdminMiddleware = (req, res, next) => { + if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) { + logger.log("admin-validation-failed", "ERROR", req.user.email, null, { + request: req.body, + user: req.user, + }); + return res.sendStatus(404); + } + next(); +}; + +module.exports = validateAdminMiddleware; \ No newline at end of file diff --git a/server/middleware/validateFirebaseIdTokenMiddleware.js b/server/middleware/validateFirebaseIdTokenMiddleware.js new file mode 100644 index 000000000..a9522a0bb --- /dev/null +++ b/server/middleware/validateFirebaseIdTokenMiddleware.js @@ -0,0 +1,59 @@ +const logger = require("../utils/logger"); +const admin = require("firebase-admin"); + +const validateFirebaseIdTokenMiddleware = async (req, res, next) => { + if ( + (!req.headers.authorization || + !req.headers.authorization.startsWith("Bearer ")) && + !(req.cookies && req.cookies.__session) + ) { + console.error("Unauthorized attempt. No authorization provided."); + res.status(403).send("Unauthorized"); + return; + } + + let idToken; + + if ( + req.headers.authorization && + req.headers.authorization.startsWith("Bearer ") + ) { + // console.log('Found "Authorization" header'); + // Read the ID Token from the Authorization header. + idToken = req.headers.authorization.split("Bearer ")[1]; + } else if (req.cookies) { + //console.log('Found "__session" cookie'); + // Read the ID Token from cookie. + idToken = req.cookies.__session; + } else { + // No cookie + console.error("Unauthorized attempt. No cookie provided."); + logger.log("api-unauthorized-call", "WARN", null, null, { + req, + type: "no-cookie", + }); + res.status(403).send("Unauthorized"); + return; + } + + try { + const decodedIdToken = await admin.auth().verifyIdToken(idToken); + //console.log("ID Token correctly decoded", decodedIdToken); + req.user = decodedIdToken; + next(); + + } catch (error) { + logger.log("api-unauthorized-call", "WARN", null, null, { + path: req.path, + body: req.body, + + type: "unauthroized", + ...error, + }); + + res.status(401).send("Unauthorized"); + + } +}; + +module.exports = validateFirebaseIdTokenMiddleware; \ No newline at end of file diff --git a/server/opensearch/os-handler.js b/server/opensearch/os-handler.js index 7cb544400..2beeaca3a 100644 --- a/server/opensearch/os-handler.js +++ b/server/opensearch/os-handler.js @@ -15,10 +15,6 @@ const {getClient} = require('../../libs/awsUtils'); async function OpenSearchUpdateHandler(req, res) { - if (req.headers["event-secret"] !== process.env.EVENT_SECRET) { - res.status(401).send("Unauthorized"); - return; - } try { const osClient = await getClient(); diff --git a/server/routes/accountingRoutes.js b/server/routes/accountingRoutes.js index 9e390746d..aff49cbdb 100644 --- a/server/routes/accountingRoutes.js +++ b/server/routes/accountingRoutes.js @@ -1,10 +1,12 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -const accountQbxml = require('../accounting/qbxml/qbxml'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); +const {payments, payables, receivables} = require("../accounting/qbxml/qbxml"); -router.post('/qbxml/receivables', fb.validateFirebaseIdToken, accountQbxml.receivables); -router.post('/qbxml/payables', fb.validateFirebaseIdToken, accountQbxml.payables); -router.post('/qbxml/payments', fb.validateFirebaseIdToken, accountQbxml.payments); +router.use(validateFirebaseIdTokenMiddleware); + +router.post('/qbxml/receivables', receivables); +router.post('/qbxml/payables', payables); +router.post('/qbxml/payments', payments); module.exports = router; diff --git a/server/routes/adminRoutes.js b/server/routes/adminRoutes.js index 9fffd1568..617f343b3 100644 --- a/server/routes/adminRoutes.js +++ b/server/routes/adminRoutes.js @@ -1,15 +1,18 @@ const express = require('express'); const router = express.Router(); const fb = require('../firebase/firebase-handler'); -const adm = require('../admin/adminops'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); +const {createAssociation, createShop, updateShop, updateCounter} = require("../admin/adminops"); +const validateAdminMiddleware = require("../middleware/validateAdminMiddleware"); +router.use(validateFirebaseIdTokenMiddleware); -router.post('/createassociation', fb.validateFirebaseIdToken, fb.validateAdmin, adm.createAssociation); -router.post('/createshop', fb.validateFirebaseIdToken, fb.validateAdmin, adm.createShop); -router.post('/updateshop', fb.validateFirebaseIdToken, fb.validateAdmin, adm.updateShop); -router.post('/updatecounter', fb.validateFirebaseIdToken, fb.validateAdmin, adm.updateCounter); -router.post('/updateuser', fb.validateFirebaseIdToken, fb.updateUser); -router.post('/getuser', fb.validateFirebaseIdToken, fb.getUser); -router.post('/createuser', fb.validateFirebaseIdToken, fb.createUser); +router.post('/createassociation', validateAdminMiddleware, createAssociation); +router.post('/createshop', validateAdminMiddleware, createShop); +router.post('/updateshop', validateAdminMiddleware, updateShop); +router.post('/updatecounter', validateAdminMiddleware, updateCounter); +router.post('/updateuser', fb.updateUser); +router.post('/getuser', fb.getUser); +router.post('/createuser', fb.createUser); module.exports = router; diff --git a/server/routes/cdkRoutes.js b/server/routes/cdkRoutes.js index 9aa234655..fdedadf92 100644 --- a/server/routes/cdkRoutes.js +++ b/server/routes/cdkRoutes.js @@ -1,8 +1,10 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); const cdkGetMake = require('../cdk/cdk-get-makes'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); -router.post('/getvehicles', fb.validateFirebaseIdToken, cdkGetMake.default); +router.use(validateFirebaseIdTokenMiddleware); + +router.post('/getvehicles', cdkGetMake.default); module.exports = router; diff --git a/server/routes/dataRoutes.js b/server/routes/dataRoutes.js index 7a6c631ff..0240f3388 100644 --- a/server/routes/dataRoutes.js +++ b/server/routes/dataRoutes.js @@ -1,9 +1,9 @@ const express = require('express'); const router = express.Router(); -const data = require('../data/data'); +const {autohouse, claimscorp, kaizen} = require('../data/data'); -router.post('/ah', data.autohouse); -router.post('/cc', data.claimscorp); -router.post('/kaizen', data.kaizen); +router.post('/ah', autohouse); +router.post('/cc', claimscorp); +router.post('/kaizen', kaizen); module.exports = router; diff --git a/server/routes/intellipayRoutes.js b/server/routes/intellipayRoutes.js index 88144f1be..3952a3450 100644 --- a/server/routes/intellipayRoutes.js +++ b/server/routes/intellipayRoutes.js @@ -1,11 +1,11 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -const intellipay = require('../intellipay/intellipay'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); +const {lightbox_credentials, payment_refund, generate_payment_url, postback} = require("../intellipay/intellipay"); -router.post('/lightbox_credentials', fb.validateFirebaseIdToken, intellipay.lightbox_credentials); -router.post('/payment_refund', fb.validateFirebaseIdToken, intellipay.payment_refund); -router.post('/generate_payment_url', fb.validateFirebaseIdToken, intellipay.generate_payment_url); -router.post('/postback', intellipay.postback); +router.post('/lightbox_credentials', validateFirebaseIdTokenMiddleware, lightbox_credentials); +router.post('/payment_refund', validateFirebaseIdTokenMiddleware, payment_refund); +router.post('/generate_payment_url', validateFirebaseIdTokenMiddleware, generate_payment_url); +router.post('/postback', postback); module.exports = router; diff --git a/server/routes/jobRoutes.js b/server/routes/jobRoutes.js index f3cc7bf1b..dea660200 100644 --- a/server/routes/jobRoutes.js +++ b/server/routes/jobRoutes.js @@ -1,15 +1,19 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); const job = require('../job/job'); -const partsScan = require('../parts-scan/parts-scan'); +const {partsScan} = require('../parts-scan/parts-scan'); +const eventAuthorizationMiddleware = require('../middleware/eventAuthorizationMIddleware'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); +const {totals, statustransition, totalsSsu, costing, lifecycle, costingmulti} = require("../job/job"); -router.post('/totals', fb.validateFirebaseIdToken, job.totals); -router.post('/statustransition', fb.validateFirebaseIdToken, job.statustransition); -router.post('/totalsssu', fb.validateFirebaseIdToken, job.totalsSsu); -router.post('/costing', fb.validateFirebaseIdToken, job.costing); -router.get('/lifecycle', fb.validateFirebaseIdToken, job.lifecycle); -router.post('/costingmulti', fb.validateFirebaseIdToken, job.costingmulti); -router.post('/partsscan', fb.validateFirebaseIdToken, partsScan.partsScan); +router.use(validateFirebaseIdTokenMiddleware); + +router.post('/totals', totals); +router.post('/statustransition', eventAuthorizationMiddleware, statustransition); +router.post('/totalsssu', totalsSsu); +router.post('/costing', costing); +router.get('/lifecycle', lifecycle); +router.post('/costingmulti', costingmulti); +router.post('/partsscan', partsScan); module.exports = router; diff --git a/server/routes/mediaRoutes.js b/server/routes/mediaRoutes.js index 3d6d9f69e..a44a1a048 100644 --- a/server/routes/mediaRoutes.js +++ b/server/routes/mediaRoutes.js @@ -1,11 +1,13 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -const media = require('../media/media'); +const {createSignedUploadURL, downloadFiles, renameKeys, deleteFiles} = require('../media/media'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); -router.post('/sign', fb.validateFirebaseIdToken, media.createSignedUploadURL); -router.post('/download', fb.validateFirebaseIdToken, media.downloadFiles); -router.post('/rename', fb.validateFirebaseIdToken, media.renameKeys); -router.post('/delete', fb.validateFirebaseIdToken, media.deleteFiles); +router.use(validateFirebaseIdTokenMiddleware); + +router.post('/sign', createSignedUploadURL); +router.post('/download', downloadFiles); +router.post('/rename', renameKeys); +router.post('/delete', deleteFiles); module.exports = router; diff --git a/server/routes/miscellaneousRoutes.js b/server/routes/miscellaneousRoutes.js index bae1a255c..fcdc23398 100644 --- a/server/routes/miscellaneousRoutes.js +++ b/server/routes/miscellaneousRoutes.js @@ -3,11 +3,12 @@ const router = express.Router(); const logger = require("../../server/utils/logger"); const sendEmail = require("../email/sendemail"); const data = require("../data/data"); -const fb = require("../firebase/firebase-handler"); const bodyParser = require("body-parser"); const ioevent = require("../ioevent/ioevent"); const taskHandler = require("../tasks/tasks"); const os = require("../opensearch/os-handler"); +const eventAuthorizationMiddleware = require("../middleware/eventAuthorizationMIddleware"); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); //Test route to ensure Express is responding. router.get("/test", async function (req, res) { @@ -29,15 +30,21 @@ router.get("/test", async function (req, res) { res.status(200).send(`OK - ${commit}`); }); -router.post("/search", fb.validateFirebaseIdToken, os.search); -router.post("/opensearch", os.handler); +// Search +router.post("/search", validateFirebaseIdTokenMiddleware, os.search); +router.post("/opensearch", eventAuthorizationMiddleware, os.handler); +// IO Events router.post('/ioevent', ioevent.default); -router.post('/sendemail', fb.validateFirebaseIdToken, sendEmail.sendEmail); + +// Email +router.post('/sendemail', validateFirebaseIdTokenMiddleware, sendEmail.sendEmail); router.post('/emailbounce', bodyParser.text(), sendEmail.emailBounce); + +// Handlers router.post('/record-handler/arms', data.arms); -router.post("/taskHandler", fb.validateFirebaseIdToken, taskHandler.taskHandler); +router.post("/taskHandler", validateFirebaseIdTokenMiddleware, taskHandler.taskHandler); module.exports = router; diff --git a/server/routes/mixDataRoutes.js b/server/routes/mixDataRoutes.js index 67559bd9a..f3f4d8afe 100644 --- a/server/routes/mixDataRoutes.js +++ b/server/routes/mixDataRoutes.js @@ -2,9 +2,9 @@ const express = require('express'); const router = express.Router(); const multer = require('multer'); const upload = multer(); -const fb = require('../firebase/firebase-handler'); -const mixdataUpload = require('../mixdata/mixdata'); +const {mixdataUpload} = require('../mixdata/mixdata'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); -router.post('/upload', fb.validateFirebaseIdToken, upload.any(), mixdataUpload.mixdataUpload); +router.post('/upload', validateFirebaseIdTokenMiddleware, upload.any(), mixdataUpload); module.exports = router; diff --git a/server/routes/notificationsRoutes.js b/server/routes/notificationsRoutes.js index b1c5ac48e..1a8e9de7b 100644 --- a/server/routes/notificationsRoutes.js +++ b/server/routes/notificationsRoutes.js @@ -1,8 +1,11 @@ const express = require('express'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); +const {subscribe, unsubscribe} = require("../firebase/firebase-handler"); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -router.post('/subscribe', fb.validateFirebaseIdToken, fb.subscribe); -router.post('/unsubscribe', fb.validateFirebaseIdToken, fb.unsubscribe); +router.use(validateFirebaseIdTokenMiddleware); + +router.post('/subscribe', subscribe); +router.post('/unsubscribe', unsubscribe); module.exports = router; diff --git a/server/routes/qboRoutes.js b/server/routes/qboRoutes.js index 69cb3edb9..e7a00619f 100644 --- a/server/routes/qboRoutes.js +++ b/server/routes/qboRoutes.js @@ -1,13 +1,13 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -const qbo = require('../accounting/qbo/qbo'); // Assuming you have a qbo module for handling QuickBooks Online related functionalities +const {authorize, callback, receivables, payables, payments} = require('../accounting/qbo/qbo'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); // Assuming you have a qbo module for handling QuickBooks Online related functionalities // Define the routes for QuickBooks Online -router.post('/authorize', fb.validateFirebaseIdToken, qbo.authorize); -router.get('/callback', qbo.callback); -router.post('/receivables', fb.validateFirebaseIdToken, qbo.receivables); -router.post('/payables', fb.validateFirebaseIdToken, qbo.payables); -router.post('/payments', fb.validateFirebaseIdToken, qbo.payments); +router.post('/authorize', validateFirebaseIdTokenMiddleware, authorize); +router.get('/callback', callback); +router.post('/receivables', validateFirebaseIdTokenMiddleware, receivables); +router.post('/payables', validateFirebaseIdTokenMiddleware, payables); +router.post('/payments', validateFirebaseIdTokenMiddleware, payments); module.exports = router; diff --git a/server/routes/renderRoutes.js b/server/routes/renderRoutes.js index 87dd75e70..7242404e5 100644 --- a/server/routes/renderRoutes.js +++ b/server/routes/renderRoutes.js @@ -1,9 +1,9 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -const inlineCss = require('../render/inlinecss'); +const {inlinecss} = require('../render/inlinecss'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); // Define the route for inline CSS rendering -router.post('/inlinecss', fb.validateFirebaseIdToken, inlineCss.inlinecss); +router.post('/inlinecss', validateFirebaseIdTokenMiddleware, inlinecss); module.exports = router; diff --git a/server/routes/schedulingRoutes.js b/server/routes/schedulingRoutes.js index 36a934102..38a91229b 100644 --- a/server/routes/schedulingRoutes.js +++ b/server/routes/schedulingRoutes.js @@ -1,8 +1,8 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -const scheduling = require('../scheduling/scheduling-job'); +const {job} = require('../scheduling/scheduling-job'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); -router.post('/job', fb.validateFirebaseIdToken, scheduling.job); +router.post('/job', validateFirebaseIdTokenMiddleware, job); module.exports = router; diff --git a/server/routes/smsRoutes.js b/server/routes/smsRoutes.js index a642c61bf..9952e0d64 100644 --- a/server/routes/smsRoutes.js +++ b/server/routes/smsRoutes.js @@ -1,17 +1,17 @@ const express = require('express'); const router = express.Router(); const twilio = require('twilio'); -const fb = require('../firebase/firebase-handler'); -const smsReceive = require('../sms/receive'); -const smsSend = require('../sms/send'); -const smsStatus = require('../sms/status'); +const {receive} = require('../sms/receive'); +const {send} = require('../sms/send'); +const {status, markConversationRead} = require('../sms/status'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); // Twilio Webhook Middleware for production const twilioWebhookMiddleware = twilio.webhook({ validate: process.env.NODE_ENV === "PRODUCTION" }); -router.post('/receive', twilioWebhookMiddleware, smsReceive.receive); -router.post('/send', fb.validateFirebaseIdToken, smsSend.send); -router.post('/status', twilioWebhookMiddleware, smsStatus.status); -router.post('/markConversationRead', fb.validateFirebaseIdToken, smsStatus.markConversationRead); +router.post('/receive', twilioWebhookMiddleware, receive); +router.post('/send', validateFirebaseIdTokenMiddleware, send); +router.post('/status', twilioWebhookMiddleware, status); +router.post('/markConversationRead', validateFirebaseIdTokenMiddleware, markConversationRead); module.exports = router; diff --git a/server/routes/techRoutes.js b/server/routes/techRoutes.js index ca6d4c936..e7594f532 100644 --- a/server/routes/techRoutes.js +++ b/server/routes/techRoutes.js @@ -1,8 +1,8 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -const tech = require('../tech/tech'); +const {techLogin} = require('../tech/tech'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); -router.post('/login', fb.validateFirebaseIdToken, tech.techLogin); +router.post('/login', validateFirebaseIdTokenMiddleware, techLogin); module.exports = router; diff --git a/server/routes/utilRoutes.js b/server/routes/utilRoutes.js index 173637479..938b1e1b1 100644 --- a/server/routes/utilRoutes.js +++ b/server/routes/utilRoutes.js @@ -1,9 +1,9 @@ const express = require('express'); const router = express.Router(); -const fb = require('../firebase/firebase-handler'); -const utils = require('../utils/utils'); +const {servertime, jsrAuth} = require('../utils/utils'); +const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); -router.post('/time', utils.servertime); -router.post('/jsr', fb.validateFirebaseIdToken, utils.jsrAuth); +router.post('/time', servertime); +router.post('/jsr', validateFirebaseIdTokenMiddleware, jsrAuth); module.exports = router; diff --git a/server/utils/adminEmail.js b/server/utils/adminEmail.js new file mode 100644 index 000000000..70c44cb47 --- /dev/null +++ b/server/utils/adminEmail.js @@ -0,0 +1,13 @@ +/** + * List of admin email addresses + * @type {string[]} + */ +const adminEmail = [ + "patrick@imex.dev", + //"patrick@imex.test", + "patrick@imex.prod", + "patrick@imexsystems.ca", + "patrick@thinkimex.com", +]; + +module.exports = adminEmail; \ No newline at end of file