-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Brijesh
committed
Aug 9, 2023
1 parent
758bf79
commit f5018c4
Showing
14 changed files
with
442 additions
and
20 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
22 changes: 22 additions & 0 deletions
22
src/libs/db2/migrations/20230726172245_add_email_templates_table.js
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,22 @@ | ||
exports.up = async function(knex) { | ||
await knex.raw(` | ||
create table email_template ( | ||
id serial2 NOT NULL, | ||
name varchar NOT NULL, | ||
from_email varchar NOT NULL, | ||
subject varchar NOT NULL, | ||
body varchar NULL, | ||
CONSTRAINT email_template_pk PRIMARY KEY (id) | ||
); | ||
INSERT INTO email_template | ||
(name, from_email, subject, body) | ||
VALUES('Plan Status Change', '[email protected]', 'Plan status changed - {agreementId}', 'Plan status changed from {fromStatus} to {toStatus} for the agreement {agreementId}'); | ||
`); | ||
|
||
}; | ||
|
||
exports.down = async function(knex) { | ||
await knex.raw(` | ||
drop table email_template; | ||
`); | ||
}; |
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,114 @@ | ||
"use strict"; | ||
|
||
import Model from "./model"; | ||
|
||
export default class EmailTemplate extends Model { | ||
constructor(data, db = undefined) { | ||
super(data, db); | ||
} | ||
|
||
static mapRow(row) { | ||
return { | ||
id: row.id, | ||
name: row.name, | ||
fromEmail: row.from_email, | ||
subject: row.subject, | ||
body: row.body, | ||
}; | ||
} | ||
|
||
static get fields() { | ||
// primary key *must* be first! | ||
return [ | ||
"id", | ||
"name", | ||
"from_email", | ||
"subject", | ||
"body", | ||
].map(field => `${this.table}.${field}`); | ||
} | ||
|
||
static get table() { | ||
return "email_template"; | ||
} | ||
|
||
static async update(db, where, values) { | ||
const obj = {}; | ||
Object.keys(values).forEach(key => { | ||
obj[Model.toSnakeCase(key)] = values[key]; | ||
}); | ||
|
||
try { | ||
const count = await db | ||
.table(EmailTemplate.table) | ||
.where(where) | ||
.update(obj); | ||
|
||
if (count > 0) { | ||
const [{ id }] = await db | ||
.table(EmailTemplate.table) | ||
.where(where) | ||
.returning("id"); | ||
|
||
const res = await db.raw( | ||
` | ||
SELECT email_template.* FROM email_template | ||
WHERE email_template.id = ?; | ||
`, | ||
[id] | ||
); | ||
return res.rows.map(EmailTemplate.mapRow)[0]; | ||
} | ||
|
||
return []; | ||
} catch (err) { | ||
throw err; | ||
} | ||
} | ||
|
||
static async create(db, values) { | ||
const obj = {}; | ||
Object.keys(values).forEach(key => { | ||
obj[Model.toSnakeCase(key)] = values[key]; | ||
}); | ||
|
||
try { | ||
const results = await db | ||
.table(EmailTemplate.table) | ||
.returning("id") | ||
.insert(obj); | ||
|
||
return await EmailTemplate.findOne(db, { id: results.pop() }); | ||
} catch (err) { | ||
throw err; | ||
} | ||
} | ||
|
||
static async findWithExclusion(db, where, order = null, exclude) { | ||
try { | ||
const q = db | ||
.table(EmailTemplate.table) | ||
.select("id") | ||
.where(where); | ||
|
||
if (exclude) { | ||
q.andWhereNot(...exclude); | ||
} | ||
|
||
const results = await q; | ||
const emailTemplateIds = results.map(obj => obj.id); | ||
|
||
const res = await db.raw( | ||
` | ||
SELECT DISTINCT ON (email_template.id) id, email_template.* FROM email_template | ||
WHERE email_template.id = ANY (?) ORDER BY email_template.id, ?; | ||
`, | ||
[emailTemplateIds, order], | ||
); | ||
|
||
return res.rows.map(EmailTemplate.mapRow); | ||
} catch (err) { | ||
throw err; | ||
} | ||
} | ||
} |
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,60 @@ | ||
import { errorWithCode, logger } from '@bcgov/nodejs-common-utils'; | ||
import axios from "axios"; | ||
|
||
export class Mailer { | ||
|
||
constructor(authenticaitonURL = process.env.CHES_AUTHENTICATION_URL, emailServiceURL = process.env.CHES_EMAIL_SERVICE_URL, clientId = process.env.CHES_CLIENT_ID, clientSecret = process.env.CHES_CLIENT_SECRET, enabled = process.env.CHES_ENABLED) { | ||
this.authenticationURL = authenticaitonURL; | ||
this.emailServiceURL = emailServiceURL; | ||
this.clientId = clientId; | ||
this.clientSecret = clientSecret; | ||
this.enabled = enabled; | ||
} | ||
|
||
async getBearerToken() { | ||
const tokenEndpoint = `${this.authenticationURL}/auth/realms/comsvcauth/protocol/openid-connect/token` | ||
const credentials = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString('base64') | ||
try { | ||
const response = await axios.post(tokenEndpoint, 'grant_type=client_credentials', { | ||
headers: { | ||
'Authorization': `Basic ${credentials}`, | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
} | ||
}); | ||
console.debug("Bearer token retrieved") | ||
return response.data.access_token | ||
} | ||
catch (error) { | ||
logger.error(`Failed to retrieve bearer token: ${JSON.stringify(error)}`) | ||
throw errorWithCode('Failed to retrieve bearer token', 500) | ||
} | ||
} | ||
|
||
async sendEmail(to, from, subject, body, bodyType) { | ||
if (!eval(this.enabled)) | ||
return; | ||
const emailEndpoint = `${this.emailServiceURL}/api/v1/email` | ||
try { | ||
const token = await this.getBearerToken() | ||
const emailPayload = { to, from, subject, body, bodyType, } | ||
logger.debug("email payload: " + JSON.stringify(emailPayload)) | ||
await axios.post(emailEndpoint, JSON.stringify(emailPayload), { | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${token}`, | ||
}, | ||
}).then(response => { | ||
if (response.status > 199 && response.status < 300) | ||
logger.info('Email sent successfully') | ||
else | ||
logger.error(`Could not send Email: ${response.statusText}`) | ||
}).catch(error => { | ||
logger.error(`Error sending email: ${JSON.stringify(error)}`) | ||
throw errorWithCode('Error sending email', 500) | ||
}); | ||
} catch (error) { | ||
logger.error(`Failed sending email: ${JSON.stringify(error)}`) | ||
throw errorWithCode('Failed sending email', 500) | ||
} | ||
} | ||
} |
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.