Skip to content

Instantly share code, notes, and snippets.

@NickBolles
Created December 6, 2018 19:14
Show Gist options
  • Save NickBolles/1bd3331c02feadcd34fd2042ca73b32c to your computer and use it in GitHub Desktop.
Save NickBolles/1bd3331c02feadcd34fd2042ca73b32c to your computer and use it in GitHub Desktop.
Authentication-local-management notifier
import { Application } from "@feathersjs/feathers";
import { join } from "path";
import pug from "pug";
import sender from "./notifier";
import { isString, isFunction } from "util";
import { stringify } from "querystring";
const isProd = process.env.NODE_ENV === 'production'
const encodeOpt = { encodeURIComponent: (str) => str }
enum AuthNotificationType {
resendVerifySignup = 'resendVerifySignup',
verifySignup = 'verifySignup',
sendResetPwd = 'sendResetPwd',
resetPwd = 'resetPwd',
passwordChange = 'passwordChange',
identityChange = 'identityChange'
}
interface StringIndexed<T> {
[i: string]: T
}
interface dataFn {
(app: Application, user: any, notifierOptions: any, type: AuthNotificationType): StringIndexed<any>
}
interface LinkFn {
(app: Application, data: StringIndexed<any>): string;
}
interface IAuthNotificationConfig {
/**
* The name of a template file in the
* join(__dirname, '../', 'templates', 'email', 'account')
* directory (server/templates/email/account)
*/
template: string;
/**
* A function to retrieve data for the template. this is merged into the base of the template
* logo, name, link, returnEmail are all used before the data, and may not merge to the template correctly
* avoid their use
*/
data: dataFn;
/**
* An Unencoded URI to link to in the email
*/
link: string | LinkFn;
}
interface IAuthNotificationConfigMap extends StringIndexed<IAuthNotificationConfig> { }
const getLink = (path, app, data) => `${getBase(app)}/account/${path}?${stringify(data, null, null, encodeOpt)}`
const AuthNotificationConfig: IAuthNotificationConfigMap = {
resendVerifySignup: {
template: 'verify-email.pug',
data: (_app, user) => ({ token: user.verifyToken }),
link: getLink.bind(null, "verify")
},
verifySignup: {
template: 'email-verified.pug',
data: (_app, user) => ({ token: user.verifyToken }),
link: getLink.bind(null, "verify")
},
sendResetPwd: {
template: 'reset-password.pug',
data: (_app, user) => ({ token: user.resetToken }),
link: getLink.bind(null, "reset")
},
resetPwd: {
template: 'password-was-reset.pug',
data: (_app, user) => ({ token: user.resetToken }),
link: getLink.bind(null, "reset")
},
passwordChange: {
template: 'password-change.pug',
data: (_app, user) => ({ token: user.verifyToken }),
link: getLink.bind(null, "verify")
},
identityChange: {
template: 'identity-change.pug',
data: (_app, user) => ({ token: user.verifyToken, changes: user.verifyChanges }),
link: (app, data) => getLink("verify", app, { token: data.token })
}
};
/**
* Get the base URL of the feathers app not including a trailing slash
* @param app The Feathers Application
*/
function getBase(app: Application) {
var port = (app.get('port') === '80' || isProd) ? '' : ':' + app.get('port')
var host = (app.get('host') === 'HOST') ? 'localhost' : app.get('host')
var protocol = (app.get('protocol') === 'PROTOCOL') ? 'http' : app.get('protocol')
return `${protocol}://${host}${port}`
}
function notifier(app: Application, type: AuthNotificationType, user: any, notifierOptions?: any) {
var emailAccountTemplatesPath = join(__dirname, '../', 'templates', 'email', 'account')
const returnEmail = app.get('complaint_email') || process.env.COMPLAINT_EMAIL
const { data, link, template } = AuthNotificationConfig[type.toString()];
const templateData = isFunction(data) ? data(app, user, notifierOptions, type) : data;
const templatePath = join(emailAccountTemplatesPath, template);
const compiledHTML = pug.compileFile(templatePath)({
logo: '',
name: user.name || user.email,
link: isString(link) ? link : link(app, templateData),
returnEmail,
...templateData
})
const email = {
from: process.env.GMAIL,
to: user.email,
subject: 'Confirm Signup',
html: compiledHTML
}
return sender.send({ email });
}
export default (app) => ({
notifier: notifier.bind(this, app)
})
export const SendVerificationEmail = (options = {}) => hook => {
const { params, result: user, app, data } = hook;
if (params.provider && data && data.email && user) {
notifier(app, AuthNotificationType.resendVerifySignup, user);
return hook;
}
return hook;
}
import NotifmeSdk from 'notifme-sdk';
const isProd = process.env.NODE_ENV === 'production'
export default new NotifmeSdk({
useNotificationCatcher: !isProd || process.env.USE_NOTIF_CATCHER,
channels: {
email: {
// If "Provider1" fails, use "Provider2"
multiProviderStrategy: 'fallback',
providers: [{
type: 'logger'
}
// ...Provider settings https://github.com/notifme/notifme-sdk#2-providers
]
},
sms: {
multiProviderStrategy: 'roundrobin',
providers: [{
type: 'logger'
}]
},
push: {
multiProviderStrategy: 'roundrobin',
providers: [{
type: 'logger'
}]
},
slack: {
multiProviderStrategy: 'roundrobin',
providers: [{
type: 'logger'
}]
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment