Move notifiers to typescript
parent
b0c6c61df5
commit
57278a7306
|
@ -48,6 +48,7 @@
|
|||
"@types/assert": "0.0.31",
|
||||
"@types/bluebird": "^3.5.3",
|
||||
"@types/body-parser": "^1.16.3",
|
||||
"@types/ejs": "^2.3.33",
|
||||
"@types/express": "^4.0.35",
|
||||
"@types/express-session": "0.0.32",
|
||||
"@types/ldapjs": "^1.0.0",
|
||||
|
@ -56,6 +57,7 @@
|
|||
"@types/nedb": "^1.8.3",
|
||||
"@types/nodemailer": "^1.3.32",
|
||||
"@types/object-path": "^0.9.28",
|
||||
"@types/proxyquire": "^1.3.27",
|
||||
"@types/request": "0.0.43",
|
||||
"@types/sinon": "^2.2.1",
|
||||
"@types/speakeasy": "^2.0.1",
|
||||
|
@ -67,6 +69,7 @@
|
|||
"grunt-run": "^0.6.0",
|
||||
"mocha": "^3.2.0",
|
||||
"mockdate": "^2.0.1",
|
||||
"proxyquire": "^1.8.0",
|
||||
"request": "^2.79.0",
|
||||
"should": "^11.1.1",
|
||||
"sinon": "^1.17.6",
|
||||
|
|
|
@ -30,14 +30,18 @@ interface SessionCookieConfiguration {
|
|||
domain?: string;
|
||||
}
|
||||
|
||||
interface GMailNotifier {
|
||||
user: string;
|
||||
pass: string;
|
||||
export interface GmailNotifierConfiguration {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
type NotifierType = string;
|
||||
export interface NotifiersConfiguration {
|
||||
gmail: GMailNotifier;
|
||||
export interface FileSystemNotifierConfiguration {
|
||||
filename: string;
|
||||
}
|
||||
|
||||
export interface NotifierConfiguration {
|
||||
gmail?: GmailNotifierConfiguration;
|
||||
filesystem?: FileSystemNotifierConfiguration;
|
||||
}
|
||||
|
||||
export interface UserConfiguration {
|
||||
|
@ -46,7 +50,7 @@ export interface UserConfiguration {
|
|||
ldap: LdapConfiguration;
|
||||
session: SessionCookieConfiguration;
|
||||
store_directory?: string;
|
||||
notifier: NotifiersConfiguration;
|
||||
notifier: NotifierConfiguration;
|
||||
access_control?: ACLConfiguration;
|
||||
}
|
||||
|
||||
|
@ -57,6 +61,6 @@ export interface AppConfiguration {
|
|||
session: SessionCookieConfiguration;
|
||||
store_in_memory?: boolean;
|
||||
store_directory?: string;
|
||||
notifier: NotifiersConfiguration;
|
||||
notifier: NotifierConfiguration;
|
||||
access_control?: ACLConfiguration;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
import * as ObjectPath from "object-path";
|
||||
import { AppConfiguration, UserConfiguration, NotifierConfiguration, ACLConfiguration, LdapConfiguration } from "./Configuration";
|
||||
|
||||
|
||||
function get_optional<T>(config: object, path: string, default_value: T): T {
|
||||
let entry = default_value;
|
||||
if (ObjectPath.has(config, path)) {
|
||||
entry = ObjectPath.get<object, T>(config, path);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
function ensure_key_existence(config: object, path: string): void {
|
||||
if (!ObjectPath.has(config, path)) {
|
||||
throw new Error(`Configuration error: key '${path}' is missing in configuration file`);
|
||||
}
|
||||
}
|
||||
|
||||
export default class ConfigurationAdapter {
|
||||
static adapt(yaml_config: UserConfiguration): AppConfiguration {
|
||||
ensure_key_existence(yaml_config, "ldap");
|
||||
ensure_key_existence(yaml_config, "session.secret");
|
||||
|
||||
const port = ObjectPath.get(yaml_config, "port", 8080);
|
||||
|
||||
return {
|
||||
port: port,
|
||||
ldap: ObjectPath.get<object, LdapConfiguration>(yaml_config, "ldap"),
|
||||
session: {
|
||||
domain: ObjectPath.get<object, string>(yaml_config, "session.domain"),
|
||||
secret: ObjectPath.get<object, string>(yaml_config, "session.secret"),
|
||||
expiration: get_optional<number>(yaml_config, "session.expiration", 3600000), // in ms
|
||||
},
|
||||
store_directory: get_optional<string>(yaml_config, "store_directory", undefined),
|
||||
logs_level: get_optional<string>(yaml_config, "logs_level", "info"),
|
||||
notifier: ObjectPath.get<object, NotifierConfiguration>(yaml_config, "notifier"),
|
||||
access_control: ObjectPath.get<object, ACLConfiguration>(yaml_config, "access_control")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import * as winston from "winston";
|
||||
import nodemailer = require("nodemailer");
|
||||
|
||||
export interface Nodemailer {
|
||||
createTransport: (options?: any, defaults?: Object) => nodemailer.Transporter;
|
||||
}
|
||||
|
||||
export interface GlobalDependencies {
|
||||
u2f: object;
|
||||
nodemailer: Nodemailer;
|
||||
ldapjs: object;
|
||||
session: any;
|
||||
winston: winston.Winston;
|
||||
speakeasy: object;
|
||||
nedb: any;
|
||||
}
|
||||
|
||||
export type NodemailerDependencies = Nodemailer;
|
||||
|
||||
export interface NotifierDependencies {
|
||||
nodemailer: Nodemailer;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
import * as winston from "winston";
|
||||
|
||||
export interface GlobalDependencies {
|
||||
u2f: object;
|
||||
nodemailer: any;
|
||||
ldapjs: object;
|
||||
session: any;
|
||||
winston: winston.Winston;
|
||||
speakeasy: object;
|
||||
nedb: any;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
|
||||
export interface Identity {
|
||||
userid: string;
|
||||
email: string;
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
import { UserConfiguration } from "./Configuration";
|
||||
import { GlobalDependencies } from "./GlobalDependencies";
|
||||
import { GlobalDependencies } from "./Dependencies";
|
||||
import { AuthenticationRegulator } from "./AuthenticationRegulator";
|
||||
import UserDataStore from "./UserDataStore";
|
||||
import ConfigurationAdapter from "./ConfigurationAdapter";
|
||||
import { NotifierFactory } from "./notifiers/NotifierFactory";
|
||||
|
||||
import * as Express from "express";
|
||||
import * as BodyParser from "body-parser";
|
||||
import * as Path from "path";
|
||||
import { AuthenticationRegulator } from "./AuthenticationRegulator";
|
||||
import UserDataStore from "./UserDataStore";
|
||||
import * as http from "http";
|
||||
|
||||
import config_adapter = require("./config_adapter");
|
||||
|
||||
const Notifier = require("./notifier");
|
||||
const setup_endpoints = require("./setup_endpoints");
|
||||
const Ldap = require("./ldap");
|
||||
const AccessControl = require("./access_control");
|
||||
|
@ -19,7 +19,7 @@ export default class Server {
|
|||
private httpServer: http.Server;
|
||||
|
||||
start(yaml_configuration: UserConfiguration, deps: GlobalDependencies): Promise<void> {
|
||||
const config = config_adapter(yaml_configuration);
|
||||
const config = ConfigurationAdapter.adapt(yaml_configuration);
|
||||
|
||||
const view_directory = Path.resolve(__dirname, "../views");
|
||||
const public_html_directory = Path.resolve(__dirname, "../public_html");
|
||||
|
@ -54,7 +54,7 @@ export default class Server {
|
|||
const five_minutes = 5 * 60;
|
||||
const data_store = new UserDataStore(datastore_options);
|
||||
const regulator = new AuthenticationRegulator(data_store, five_minutes);
|
||||
const notifier = new Notifier(config.notifier, deps);
|
||||
const notifier = NotifierFactory.build(config.notifier, deps);
|
||||
const ldap = new Ldap(deps, config.ldap);
|
||||
const access_control = AccessControl(deps.winston, config.access_control);
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
|
||||
import * as ObjectPath from "object-path";
|
||||
import { AppConfiguration, UserConfiguration, NotifiersConfiguration, ACLConfiguration, LdapConfiguration } from "./Configuration";
|
||||
|
||||
|
||||
function get_optional<T>(config: object, path: string, default_value: T): T {
|
||||
let entry = default_value;
|
||||
if (ObjectPath.has(config, path)) {
|
||||
entry = ObjectPath.get<object, T>(config, path);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
function ensure_key_existence(config: object, path: string): void {
|
||||
if (!ObjectPath.has(config, path)) {
|
||||
throw new Error(`Configuration error: key '${path}' is missing in configuration file`);
|
||||
}
|
||||
}
|
||||
|
||||
export = function(yaml_config: UserConfiguration): AppConfiguration {
|
||||
ensure_key_existence(yaml_config, "ldap");
|
||||
ensure_key_existence(yaml_config, "session.secret");
|
||||
|
||||
const port = ObjectPath.get(yaml_config, "port", 8080);
|
||||
|
||||
return {
|
||||
port: port,
|
||||
ldap: ObjectPath.get<object, LdapConfiguration>(yaml_config, "ldap"),
|
||||
session: {
|
||||
domain: ObjectPath.get<object, string>(yaml_config, "session.domain"),
|
||||
secret: ObjectPath.get<object, string>(yaml_config, "session.secret"),
|
||||
expiration: get_optional<number>(yaml_config, "session.expiration", 3600000), // in ms
|
||||
},
|
||||
store_directory: get_optional<string>(yaml_config, "store_directory", undefined),
|
||||
logs_level: get_optional<string>(yaml_config, "logs_level", "info"),
|
||||
notifier: ObjectPath.get<object, NotifiersConfiguration>(yaml_config, "notifier"),
|
||||
access_control: ObjectPath.get<object, ACLConfiguration>(yaml_config, "access_control")
|
||||
};
|
||||
};
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
module.exports = Notifier;
|
||||
|
||||
var GmailNotifier = require('./notifiers/gmail.js');
|
||||
var FSNotifier = require('./notifiers/filesystem.js');
|
||||
|
||||
function notifier_factory(options, deps) {
|
||||
if('gmail' in options) {
|
||||
return new GmailNotifier(options.gmail, deps);
|
||||
}
|
||||
else if('filesystem' in options) {
|
||||
return new FSNotifier(options.filesystem);
|
||||
}
|
||||
}
|
||||
|
||||
function Notifier(options, deps) {
|
||||
this._notifier = notifier_factory(options, deps);
|
||||
}
|
||||
|
||||
Notifier.prototype.notify = function(identity, subject, link) {
|
||||
return this._notifier.notify(identity, subject, link);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
import * as BluebirdPromise from "bluebird";
|
||||
import * as util from "util";
|
||||
import * as fs from "fs";
|
||||
import { INotifier } from "./INotifier";
|
||||
import { Identity } from "../Identity";
|
||||
|
||||
import { FileSystemNotifierConfiguration } from "../Configuration";
|
||||
|
||||
export class FileSystemNotifier extends INotifier {
|
||||
private filename: string;
|
||||
|
||||
constructor(options: FileSystemNotifierConfiguration) {
|
||||
super();
|
||||
this.filename = options.filename;
|
||||
}
|
||||
|
||||
notify(identity: Identity, subject: string, link: string): BluebirdPromise<void> {
|
||||
const content = util.format("User: %s\nSubject: %s\nLink: %s", identity.userid,
|
||||
subject, link);
|
||||
const writeFilePromised = BluebirdPromise.promisify<void, string, string>(fs.writeFile);
|
||||
return writeFilePromised(this.filename, content);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
import * as Promise from "bluebird";
|
||||
import * as fs from "fs";
|
||||
import * as ejs from "ejs";
|
||||
import nodemailer = require("nodemailer");
|
||||
|
||||
import { NodemailerDependencies } from "../Dependencies";
|
||||
import { Identity } from "../Identity";
|
||||
import { INotifier } from "../notifiers/INotifier";
|
||||
import { GmailNotifierConfiguration } from "../Configuration";
|
||||
|
||||
const email_template = fs.readFileSync(__dirname + "/../../resources/email-template.ejs", "UTF-8");
|
||||
|
||||
export class GMailNotifier extends INotifier {
|
||||
private transporter: any;
|
||||
|
||||
constructor(options: GmailNotifierConfiguration, deps: NodemailerDependencies) {
|
||||
super();
|
||||
const transporter = deps.createTransport({
|
||||
service: "gmail",
|
||||
auth: {
|
||||
user: options.username,
|
||||
pass: options.password
|
||||
}
|
||||
});
|
||||
this.transporter = Promise.promisifyAll(transporter);
|
||||
}
|
||||
|
||||
notify(identity: Identity, subject: string, link: string): Promise<void> {
|
||||
const d = {
|
||||
url: link,
|
||||
button_title: "Continue",
|
||||
title: subject
|
||||
};
|
||||
|
||||
const mailOptions = {
|
||||
from: "auth-server@open-intent.io",
|
||||
to: identity.email,
|
||||
subject: subject,
|
||||
html: ejs.render(email_template, d)
|
||||
};
|
||||
return this.transporter.sendMailAsync(mailOptions);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
import * as BluebirdPromise from "bluebird";
|
||||
import { Identity } from "../Identity";
|
||||
|
||||
export abstract class INotifier {
|
||||
abstract notify(identity: Identity, subject: string, link: string): BluebirdPromise<void>;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
import { NotifierConfiguration } from "..//Configuration";
|
||||
import { NotifierDependencies } from "../Dependencies";
|
||||
import { INotifier } from "./INotifier";
|
||||
|
||||
import { GMailNotifier } from "./GMailNotifier";
|
||||
import { FileSystemNotifier } from "./FileSystemNotifier";
|
||||
|
||||
export class NotifierFactory {
|
||||
static build(options: NotifierConfiguration, deps: NotifierDependencies): INotifier {
|
||||
if ("gmail" in options) {
|
||||
return new GMailNotifier(options.gmail, deps.nodemailer);
|
||||
}
|
||||
else if ("filesystem" in options) {
|
||||
return new FileSystemNotifier(options.filesystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
module.exports = FSNotifier;
|
||||
|
||||
var Promise = require('bluebird');
|
||||
var fs = Promise.promisifyAll(require('fs'));
|
||||
var util = require('util');
|
||||
|
||||
function FSNotifier(options) {
|
||||
this._filename = options.filename;
|
||||
}
|
||||
|
||||
FSNotifier.prototype.notify = function(identity, subject, link) {
|
||||
var content = util.format('User: %s\nSubject: %s\nLink: %s', identity.userid,
|
||||
subject, link);
|
||||
return fs.writeFileAsync(this._filename, content);
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
module.exports = GmailNotifier;
|
||||
|
||||
var Promise = require('bluebird');
|
||||
var fs = require('fs');
|
||||
var ejs = require('ejs');
|
||||
|
||||
var email_template = fs.readFileSync(__dirname + '/../../resources/email-template.ejs', 'UTF-8');
|
||||
|
||||
function GmailNotifier(options, deps) {
|
||||
var transporter = deps.nodemailer.createTransport({
|
||||
service: 'gmail',
|
||||
auth: {
|
||||
user: options.username,
|
||||
pass: options.password
|
||||
}
|
||||
});
|
||||
this.transporter = Promise.promisifyAll(transporter);
|
||||
}
|
||||
|
||||
GmailNotifier.prototype.notify = function(identity, subject, link) {
|
||||
var d = {};
|
||||
d.url = link;
|
||||
d.button_title = 'Continue';
|
||||
d.title = subject;
|
||||
|
||||
var mailOptions = {};
|
||||
mailOptions.from = 'auth-server@open-intent.io';
|
||||
mailOptions.to = identity.email;
|
||||
mailOptions.subject = subject;
|
||||
mailOptions.html = ejs.render(email_template, d);
|
||||
return this.transporter.sendMailAsync(mailOptions);
|
||||
}
|
||||
|
|
@ -44,8 +44,8 @@ describe("test the server", function () {
|
|||
store_in_memory: true,
|
||||
notifier: {
|
||||
gmail: {
|
||||
user: "user@example.com",
|
||||
pass: "password"
|
||||
username: "user@example.com",
|
||||
password: "password"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import * as Assert from "assert";
|
||||
import { UserConfiguration } from "../../src/lib/Configuration";
|
||||
import config_adapter = require("../../src/lib/config_adapter");
|
||||
|
||||
import ConfigurationAdapter from "../../src/lib/ConfigurationAdapter";
|
||||
|
||||
describe("test config adapter", function() {
|
||||
function build_yaml_config(): UserConfiguration {
|
||||
|
@ -22,8 +21,8 @@ describe("test config adapter", function() {
|
|||
logs_level: "debug",
|
||||
notifier: {
|
||||
gmail: {
|
||||
user: "user",
|
||||
pass: "password"
|
||||
username: "user",
|
||||
password: "password"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -33,14 +32,14 @@ describe("test config adapter", function() {
|
|||
it("should read the port from the yaml file", function() {
|
||||
const yaml_config = build_yaml_config();
|
||||
yaml_config.port = 7070;
|
||||
const config = config_adapter(yaml_config);
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.equal(config.port, 7070);
|
||||
});
|
||||
|
||||
it("should default the port to 8080 if not provided", function() {
|
||||
const yaml_config = build_yaml_config();
|
||||
delete yaml_config.port;
|
||||
const config = config_adapter(yaml_config);
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.equal(config.port, 8080);
|
||||
});
|
||||
|
||||
|
@ -55,7 +54,7 @@ describe("test config adapter", function() {
|
|||
password: "pass"
|
||||
};
|
||||
|
||||
const config = config_adapter(yaml_config);
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
|
||||
Assert.equal(config.ldap.url, "http://ldap");
|
||||
Assert.equal(config.ldap.additional_user_dn, "ou=users");
|
||||
|
@ -71,7 +70,7 @@ describe("test config adapter", function() {
|
|||
secret: "secret",
|
||||
expiration: 3600
|
||||
};
|
||||
const config = config_adapter(yaml_config);
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.equal(config.session.domain, "example.com");
|
||||
Assert.equal(config.session.secret, "secret");
|
||||
Assert.equal(config.session.expiration, 3600);
|
||||
|
@ -80,7 +79,7 @@ describe("test config adapter", function() {
|
|||
it("should get the log level", function() {
|
||||
const yaml_config = build_yaml_config();
|
||||
yaml_config.logs_level = "debug";
|
||||
const config = config_adapter(yaml_config);
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.equal(config.logs_level, "debug");
|
||||
});
|
||||
|
||||
|
@ -88,15 +87,15 @@ describe("test config adapter", function() {
|
|||
const yaml_config = build_yaml_config();
|
||||
yaml_config.notifier = {
|
||||
gmail: {
|
||||
user: "user",
|
||||
pass: "pass"
|
||||
username: "user",
|
||||
password: "pass"
|
||||
}
|
||||
};
|
||||
const config = config_adapter(yaml_config);
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.deepEqual(config.notifier, {
|
||||
gmail: {
|
||||
user: "user",
|
||||
pass: "pass"
|
||||
username: "user",
|
||||
password: "pass"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -108,7 +107,7 @@ describe("test config adapter", function() {
|
|||
users: {},
|
||||
groups: {}
|
||||
};
|
||||
const config = config_adapter(yaml_config);
|
||||
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||
Assert.deepEqual(config.access_control, {
|
||||
default: [],
|
||||
users: {},
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as request from "request";
|
|||
|
||||
import Server from "../../src/lib/Server";
|
||||
import { UserConfiguration } from "../../src/lib/Configuration";
|
||||
import { GlobalDependencies } from "../../src/lib/GlobalDependencies";
|
||||
import { GlobalDependencies } from "../../src/lib/Dependencies";
|
||||
import * as tmp from "tmp";
|
||||
|
||||
|
||||
|
@ -77,8 +77,8 @@ describe("test data persistence", function () {
|
|||
store_directory: tmpDir.name,
|
||||
notifier: {
|
||||
gmail: {
|
||||
user: "user@example.com",
|
||||
pass: "password"
|
||||
username: "user@example.com",
|
||||
password: "password"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
import sinon = require("sinon");
|
||||
import { Nodemailer } from "../../../src/lib/Dependencies";
|
||||
|
||||
export = {
|
||||
createTransport: sinon.stub()
|
||||
};
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
import * as sinon from "sinon";
|
||||
import * as assert from "assert";
|
||||
import { FileSystemNotifier } from "../../../src/lib/notifiers/FileSystemNotifier";
|
||||
import * as tmp from "tmp";
|
||||
import * as fs from "fs";
|
||||
|
||||
const NOTIFICATIONS_DIRECTORY = "notifications";
|
||||
|
||||
describe("test FS notifier", function() {
|
||||
let tmpDir: tmp.SynchrounousResult;
|
||||
before(function() {
|
||||
tmpDir = tmp.dirSync({ unsafeCleanup: true });
|
||||
});
|
||||
|
||||
after(function() {
|
||||
tmpDir.removeCallback();
|
||||
});
|
||||
|
||||
it("should write the notification in a file", function() {
|
||||
const options = {
|
||||
filename: tmpDir.name + "/" + NOTIFICATIONS_DIRECTORY
|
||||
};
|
||||
|
||||
const sender = new FileSystemNotifier(options);
|
||||
const subject = "subject";
|
||||
|
||||
const identity = {
|
||||
userid: "user",
|
||||
email: "user@example.com"
|
||||
};
|
||||
|
||||
const url = "http://test.com";
|
||||
|
||||
return sender.notify(identity, subject, url)
|
||||
.then(function() {
|
||||
const content = fs.readFileSync(options.filename, "UTF-8");
|
||||
assert(content.length > 0);
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
import * as sinon from "sinon";
|
||||
import * as assert from "assert";
|
||||
|
||||
import nodemailerMock = require("../mocks/nodemailer");
|
||||
import GMailNotifier = require("../../../src/lib/notifiers/GMailNotifier");
|
||||
|
||||
|
||||
describe("test gmail notifier", function () {
|
||||
it("should send an email", function () {
|
||||
const transporter = {
|
||||
sendMail: sinon.stub().yields()
|
||||
};
|
||||
nodemailerMock.createTransport.returns(transporter);
|
||||
|
||||
const options = {
|
||||
username: "user_gmail",
|
||||
password: "pass_gmail"
|
||||
};
|
||||
|
||||
const sender = new GMailNotifier.GMailNotifier(options, nodemailerMock);
|
||||
const subject = "subject";
|
||||
|
||||
const identity = {
|
||||
userid: "user",
|
||||
email: "user@example.com"
|
||||
};
|
||||
|
||||
const url = "http://test.com";
|
||||
|
||||
return sender.notify(identity, subject, url)
|
||||
.then(function () {
|
||||
assert.equal(nodemailerMock.createTransport.getCall(0).args[0].auth.user, "user_gmail");
|
||||
assert.equal(nodemailerMock.createTransport.getCall(0).args[0].auth.pass, "pass_gmail");
|
||||
assert.equal(transporter.sendMail.getCall(0).args[0].to, "user@example.com");
|
||||
assert.equal(transporter.sendMail.getCall(0).args[0].subject, "subject");
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
import * as sinon from "sinon";
|
||||
import * as BluebirdPromise from "bluebird";
|
||||
import * as assert from "assert";
|
||||
|
||||
import NodemailerMock = require("../mocks/nodemailer");
|
||||
|
||||
import { NotifierFactory } from "../../../src/lib/notifiers/NotifierFactory";
|
||||
import { GMailNotifier } from "../../../src/lib/notifiers/GMailNotifier";
|
||||
import { FileSystemNotifier } from "../../../src/lib/notifiers/FileSystemNotifier";
|
||||
|
||||
import { NotifierDependencies } from "../../../src/lib/Dependencies";
|
||||
|
||||
|
||||
describe("test notifier", function() {
|
||||
const deps: NotifierDependencies = {
|
||||
nodemailer: NodemailerMock
|
||||
};
|
||||
|
||||
it("should build a Gmail Notifier", function() {
|
||||
const options = {
|
||||
gmail: {
|
||||
username: "abc",
|
||||
password: "password"
|
||||
}
|
||||
};
|
||||
assert(NotifierFactory.build(options, deps) instanceof GMailNotifier);
|
||||
});
|
||||
|
||||
it("should build a FS Notifier", function() {
|
||||
const options = {
|
||||
filesystem: {
|
||||
filename: "abc"
|
||||
}
|
||||
};
|
||||
|
||||
assert(NotifierFactory.build(options, deps) instanceof FileSystemNotifier);
|
||||
});
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
var sinon = require('sinon');
|
||||
var assert = require('assert');
|
||||
var FSNotifier = require('../../../src/lib/notifiers/filesystem');
|
||||
var tmp = require('tmp');
|
||||
var fs = require('fs');
|
||||
|
||||
describe('test FS notifier', function() {
|
||||
var tmpDir;
|
||||
before(function() {
|
||||
tmpDir = tmp.dirSync({ unsafeCleanup: true });
|
||||
});
|
||||
|
||||
after(function() {
|
||||
tmpDir.removeCallback();
|
||||
});
|
||||
|
||||
it('should write the notification in a file', function() {
|
||||
var options = {};
|
||||
options.filename = tmpDir.name + '/notification';
|
||||
|
||||
var sender = new FSNotifier(options);
|
||||
var subject = 'subject';
|
||||
|
||||
var identity = {};
|
||||
identity.userid = 'user';
|
||||
identity.email = 'user@example.com';
|
||||
|
||||
var url = 'http://test.com';
|
||||
|
||||
return sender.notify(identity, subject, url)
|
||||
.then(function() {
|
||||
var content = fs.readFileSync(options.filename, 'UTF-8');
|
||||
assert(content.length > 0);
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,36 +0,0 @@
|
|||
var sinon = require('sinon');
|
||||
var assert = require('assert');
|
||||
var GmailNotifier = require('../../../src/lib/notifiers/gmail');
|
||||
|
||||
describe('test gmail notifier', function() {
|
||||
it('should send an email', function() {
|
||||
var nodemailer = {};
|
||||
var transporter = {};
|
||||
nodemailer.createTransport = sinon.stub().returns(transporter);
|
||||
transporter.sendMail = sinon.stub().yields();
|
||||
var options = {};
|
||||
options.username = 'user_gmail';
|
||||
options.password = 'pass_gmail';
|
||||
|
||||
var deps = {};
|
||||
deps.nodemailer = nodemailer;
|
||||
|
||||
var sender = new GmailNotifier(options, deps);
|
||||
var subject = 'subject';
|
||||
|
||||
var identity = {};
|
||||
identity.userid = 'user';
|
||||
identity.email = 'user@example.com';
|
||||
|
||||
var url = 'http://test.com';
|
||||
|
||||
return sender.notify(identity, subject, url)
|
||||
.then(function() {
|
||||
assert.equal(nodemailer.createTransport.getCall(0).args[0].auth.user, 'user_gmail');
|
||||
assert.equal(nodemailer.createTransport.getCall(0).args[0].auth.pass, 'pass_gmail');
|
||||
assert.equal(transporter.sendMail.getCall(0).args[0].to, 'user@example.com');
|
||||
assert.equal(transporter.sendMail.getCall(0).args[0].subject, 'subject');
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,35 +0,0 @@
|
|||
|
||||
var sinon = require('sinon');
|
||||
var Promise = require('bluebird');
|
||||
var assert = require('assert');
|
||||
|
||||
var Notifier = require('../../../src/lib/notifier');
|
||||
var GmailNotifier = require('../../../src/lib/notifiers/gmail');
|
||||
var FSNotifier = require('../../../src/lib/notifiers/filesystem');
|
||||
|
||||
describe('test notifier', function() {
|
||||
it('should build a Gmail Notifier', function() {
|
||||
var deps = {};
|
||||
deps.nodemailer = {};
|
||||
deps.nodemailer.createTransport = sinon.stub().returns({});
|
||||
|
||||
var options = {};
|
||||
options.gmail = {};
|
||||
options.gmail.user = 'abc';
|
||||
options.gmail.pass = 'abcd';
|
||||
|
||||
var notifier = new Notifier(options, deps);
|
||||
assert(notifier._notifier instanceof GmailNotifier);
|
||||
});
|
||||
|
||||
it('should build a FS Notifier', function() {
|
||||
var deps = {};
|
||||
|
||||
var options = {};
|
||||
options.filesystem = {};
|
||||
options.filesystem.filename = 'abc';
|
||||
|
||||
var notifier = new Notifier(options, deps);
|
||||
assert(notifier._notifier instanceof FSNotifier);
|
||||
});
|
||||
});
|
|
@ -8,7 +8,7 @@ import * as speakeasy from "speakeasy";
|
|||
import * as u2f from "authdog";
|
||||
|
||||
import { AppConfiguration, UserConfiguration } from "../../src/lib/Configuration";
|
||||
import { GlobalDependencies } from "../../src/lib/GlobalDependencies";
|
||||
import { GlobalDependencies, Nodemailer } from "../../src/lib/Dependencies";
|
||||
import Server from "../../src/lib/Server";
|
||||
|
||||
|
||||
|
@ -20,18 +20,18 @@ describe("test server configuration", function () {
|
|||
sendMail: sinon.stub().yields()
|
||||
};
|
||||
|
||||
const nodemailer = {
|
||||
const nodemailer: Nodemailer = {
|
||||
createTransport: sinon.spy(function () {
|
||||
return transporter;
|
||||
})
|
||||
};
|
||||
|
||||
deps = {
|
||||
nodemailer: nodemailer,
|
||||
speakeasy: speakeasy,
|
||||
u2f: u2f,
|
||||
nedb: nedb,
|
||||
winston: winston,
|
||||
nodemailer: nodemailer,
|
||||
ldapjs: {
|
||||
createClient: sinon.spy(function () {
|
||||
return { on: sinon.spy() };
|
||||
|
@ -57,8 +57,8 @@ describe("test server configuration", function () {
|
|||
},
|
||||
notifier: {
|
||||
gmail: {
|
||||
user: "user@example.com",
|
||||
pass: "password"
|
||||
username: "user@example.com",
|
||||
password: "password"
|
||||
}
|
||||
}
|
||||
} as UserConfiguration;
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
|
||||
import Server from "../../src/lib/Server";
|
||||
|
||||
import { UserConfiguration } from "../../src/lib/Configuration";
|
||||
import { GlobalDependencies } from "../../src/lib/Dependencies";
|
||||
import * as express from "express";
|
||||
|
||||
const sinon = require("sinon");
|
||||
const assert = require("assert");
|
||||
|
||||
describe("test server configuration", function () {
|
||||
let deps: GlobalDependencies;
|
||||
|
||||
before(function () {
|
||||
const transporter = {
|
||||
sendMail: sinon.stub().yields()
|
||||
};
|
||||
|
||||
const nodemailer = {
|
||||
createTransport: sinon.spy(function () {
|
||||
return transporter;
|
||||
})
|
||||
};
|
||||
|
||||
deps = {
|
||||
nodemailer: nodemailer,
|
||||
speakeasy: sinon.spy(),
|
||||
u2f: sinon.spy(),
|
||||
nedb: require("nedb"),
|
||||
winston: sinon.spy(),
|
||||
ldapjs: {
|
||||
createClient: sinon.spy(function () {
|
||||
return { on: sinon.spy() };
|
||||
})
|
||||
},
|
||||
session: sinon.spy(function () {
|
||||
return function (req: express.Request, res: express.Response, next: express.NextFunction) { next(); };
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
it("should set cookie scope to domain set in the config", function () {
|
||||
const config = {
|
||||
notifier: {
|
||||
gmail: {
|
||||
username: "user@example.com",
|
||||
password: "password"
|
||||
}
|
||||
},
|
||||
session: {
|
||||
domain: "example.com",
|
||||
secret: "secret"
|
||||
},
|
||||
ldap: {
|
||||
url: "http://ldap",
|
||||
base_dn: "cn=test,dc=example,dc=com",
|
||||
user: "user",
|
||||
password: "password"
|
||||
}
|
||||
};
|
||||
|
||||
const server = new Server();
|
||||
server.start(config, deps);
|
||||
|
||||
assert(deps.session.calledOnce);
|
||||
assert.equal(deps.session.getCall(0).args[0].cookie.domain, "example.com");
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue