-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from waterloop/applicant-email-reply
Applicant email reply
- Loading branch information
Showing
61 changed files
with
3,668 additions
and
3,963 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const rootImportOpts = { | ||
root: __dirname, | ||
rootPathSuffix: 'src', | ||
}; | ||
|
||
module.exports = { | ||
presets: ['@babel/preset-env'], | ||
plugins: [['babel-plugin-root-import', rootImportOpts]], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"compilerOptions": { | ||
"baseUrl": "src" | ||
}, | ||
"include": ["src/frontend"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
const { google } = require('googleapis'); | ||
const MailComposer = require('nodemailer/lib/mail-composer'); | ||
|
||
const encodeMessage = (message) => | ||
Buffer.from(message) | ||
.toString('base64') | ||
.replace(/\+/g, '-') | ||
.replace(/\//g, '_') | ||
.replace(/=+$/, ''); | ||
|
||
const createMail = async (options) => { | ||
const mailComposer = new MailComposer(options); | ||
const message = await mailComposer.compile().build(); | ||
return encodeMessage(message); | ||
}; | ||
|
||
export const sendEmail = async (message, token) => { | ||
try { | ||
const oAuth2Client = new google.auth.OAuth2(process.env.GOOGLE_CLIENT_ID); | ||
oAuth2Client.setCredentials({ | ||
access_token: token, | ||
scope: 'https://www.googleapis.com/auth/gmail.send', | ||
}); | ||
const gmail = google.gmail({ version: 'v1', auth: oAuth2Client }); | ||
const options = { | ||
to: message.to, | ||
subject: message.subject, | ||
html: message.body, | ||
textEncoding: 'base64', | ||
headers: [ | ||
{ key: 'X-Application-Developer', value: 'Gordon Wang' }, | ||
{ key: 'X-Application-Version', value: 'v1.0.0.2' }, | ||
], | ||
}; | ||
|
||
const rawMessage = await createMail(options); | ||
const { data: { id } = {} } = await gmail.users.messages.send({ | ||
userId: 'me', | ||
requestBody: { | ||
raw: rawMessage, | ||
}, | ||
}); | ||
return id; | ||
} catch (err) { | ||
console.log('sendMail error', err); | ||
return -1; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,19 @@ | ||
import express from 'express'; | ||
|
||
import updateEmailSent from './update-email-sent'; | ||
import updateEmailStatus from './update-email-sent'; | ||
import validationCheck from '../../utils/validation-check'; | ||
import { validateRequest } from '../../google-auth'; | ||
import { body } from 'express-validator'; | ||
|
||
const router = express.Router(); | ||
|
||
// NOTE: status checks will be done on DB end. | ||
router.patch('/', [body('id').isInt()], validationCheck, updateEmailSent); | ||
router.patch( | ||
'/', | ||
[body('id').isInt()], | ||
validationCheck, | ||
validateRequest, | ||
updateEmailStatus, | ||
); | ||
|
||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,26 @@ | ||
import db from '../../db'; | ||
import db from '~/backend/db'; | ||
import { sendEmail } from './helper'; | ||
|
||
export default (req, res) => { | ||
export default async (req, res) => { | ||
const appID = req.body.id; | ||
// Try applications db first: | ||
db.applications | ||
.updateEmailSent(appID) | ||
.then((response) => { | ||
if (Array.isArray(response) && response.length !== 0) { | ||
res.send(response[0]); | ||
} else { | ||
// If no entries matched criteria in db, then attempt to update interview table email_sent column | ||
db.interviews.updateEmailSent(appID).then((resp2) => { | ||
if (typeof resp2 === 'number') { | ||
let errMsg; | ||
switch (resp2) { | ||
// TODO: We should have an error struct in the future to distinguish between these 2 errors more easily. | ||
case -1: | ||
errMsg = `Could not find application (and corresponding interview entry) with ID ${appID}.`; | ||
break; | ||
case -2: | ||
errMsg = `Cannot modify application/interview entry with ID ${appID}: invalid status.`; | ||
break; | ||
default: | ||
break; | ||
} | ||
console.error(errMsg); | ||
res.status(403).send(errMsg); | ||
} else if (Array.isArray(resp2) && resp2.length === 1) { | ||
res.send(resp2[0]); | ||
} else { | ||
// We should never have more than 1 interview entry: | ||
throw new Error( | ||
'Multiple interview entries detected for single application! Please sanitize the database.', | ||
); | ||
} | ||
}); | ||
} | ||
}) | ||
.catch((err) => { | ||
const errMsg = `Could not modify email-sent status: ${err}`; | ||
console.error(errMsg); | ||
res.status(500).send(errMsg); | ||
}); | ||
|
||
// send the actual email, then check if email sent correctly | ||
if (req.body.accessToken) { | ||
await sendEmail(req.body, req.body.accessToken); // TODO: check if accessToken sent securely. | ||
} | ||
|
||
try { | ||
// if email sent correctly, proceed with code below, else abort procedure. | ||
const response = await db.applications.updateEmailStatus(appID); | ||
if (Array.isArray(response) && response.length !== 0) { | ||
res.send({ ...response[0] }); | ||
} else { | ||
// invalid ID or cannot send email for application with the status: | ||
res.sendStatus(403); | ||
} | ||
} catch (err) { | ||
const errMsg = `Could not modify email-sent status: ${err}`; | ||
console.error(errMsg); | ||
res.status(500).send(errMsg); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.