mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
Move notifiers to typescript
This commit is contained in:
parent
b0c6c61df5
commit
57278a7306
|
@ -48,6 +48,7 @@
|
||||||
"@types/assert": "0.0.31",
|
"@types/assert": "0.0.31",
|
||||||
"@types/bluebird": "^3.5.3",
|
"@types/bluebird": "^3.5.3",
|
||||||
"@types/body-parser": "^1.16.3",
|
"@types/body-parser": "^1.16.3",
|
||||||
|
"@types/ejs": "^2.3.33",
|
||||||
"@types/express": "^4.0.35",
|
"@types/express": "^4.0.35",
|
||||||
"@types/express-session": "0.0.32",
|
"@types/express-session": "0.0.32",
|
||||||
"@types/ldapjs": "^1.0.0",
|
"@types/ldapjs": "^1.0.0",
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
"@types/nedb": "^1.8.3",
|
"@types/nedb": "^1.8.3",
|
||||||
"@types/nodemailer": "^1.3.32",
|
"@types/nodemailer": "^1.3.32",
|
||||||
"@types/object-path": "^0.9.28",
|
"@types/object-path": "^0.9.28",
|
||||||
|
"@types/proxyquire": "^1.3.27",
|
||||||
"@types/request": "0.0.43",
|
"@types/request": "0.0.43",
|
||||||
"@types/sinon": "^2.2.1",
|
"@types/sinon": "^2.2.1",
|
||||||
"@types/speakeasy": "^2.0.1",
|
"@types/speakeasy": "^2.0.1",
|
||||||
|
@ -67,6 +69,7 @@
|
||||||
"grunt-run": "^0.6.0",
|
"grunt-run": "^0.6.0",
|
||||||
"mocha": "^3.2.0",
|
"mocha": "^3.2.0",
|
||||||
"mockdate": "^2.0.1",
|
"mockdate": "^2.0.1",
|
||||||
|
"proxyquire": "^1.8.0",
|
||||||
"request": "^2.79.0",
|
"request": "^2.79.0",
|
||||||
"should": "^11.1.1",
|
"should": "^11.1.1",
|
||||||
"sinon": "^1.17.6",
|
"sinon": "^1.17.6",
|
||||||
|
|
|
@ -30,14 +30,18 @@ interface SessionCookieConfiguration {
|
||||||
domain?: string;
|
domain?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GMailNotifier {
|
export interface GmailNotifierConfiguration {
|
||||||
user: string;
|
username: string;
|
||||||
pass: string;
|
password: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type NotifierType = string;
|
export interface FileSystemNotifierConfiguration {
|
||||||
export interface NotifiersConfiguration {
|
filename: string;
|
||||||
gmail: GMailNotifier;
|
}
|
||||||
|
|
||||||
|
export interface NotifierConfiguration {
|
||||||
|
gmail?: GmailNotifierConfiguration;
|
||||||
|
filesystem?: FileSystemNotifierConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserConfiguration {
|
export interface UserConfiguration {
|
||||||
|
@ -46,7 +50,7 @@ export interface UserConfiguration {
|
||||||
ldap: LdapConfiguration;
|
ldap: LdapConfiguration;
|
||||||
session: SessionCookieConfiguration;
|
session: SessionCookieConfiguration;
|
||||||
store_directory?: string;
|
store_directory?: string;
|
||||||
notifier: NotifiersConfiguration;
|
notifier: NotifierConfiguration;
|
||||||
access_control?: ACLConfiguration;
|
access_control?: ACLConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +61,6 @@ export interface AppConfiguration {
|
||||||
session: SessionCookieConfiguration;
|
session: SessionCookieConfiguration;
|
||||||
store_in_memory?: boolean;
|
store_in_memory?: boolean;
|
||||||
store_directory?: string;
|
store_directory?: string;
|
||||||
notifier: NotifiersConfiguration;
|
notifier: NotifierConfiguration;
|
||||||
access_control?: ACLConfiguration;
|
access_control?: ACLConfiguration;
|
||||||
}
|
}
|
||||||
|
|
42
src/lib/ConfigurationAdapter.ts
Normal file
42
src/lib/ConfigurationAdapter.ts
Normal file
|
@ -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")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
22
src/lib/Dependencies.ts
Normal file
22
src/lib/Dependencies.ts
Normal file
|
@ -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;
|
|
||||||
}
|
|
6
src/lib/Identity.ts
Normal file
6
src/lib/Identity.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
export interface Identity {
|
||||||
|
userid: string;
|
||||||
|
email: string;
|
||||||
|
}
|
|
@ -1,16 +1,16 @@
|
||||||
|
|
||||||
import { UserConfiguration } from "./Configuration";
|
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 Express from "express";
|
||||||
import * as BodyParser from "body-parser";
|
import * as BodyParser from "body-parser";
|
||||||
import * as Path from "path";
|
import * as Path from "path";
|
||||||
import { AuthenticationRegulator } from "./AuthenticationRegulator";
|
|
||||||
import UserDataStore from "./UserDataStore";
|
|
||||||
import * as http from "http";
|
import * as http from "http";
|
||||||
|
|
||||||
import config_adapter = require("./config_adapter");
|
|
||||||
|
|
||||||
const Notifier = require("./notifier");
|
|
||||||
const setup_endpoints = require("./setup_endpoints");
|
const setup_endpoints = require("./setup_endpoints");
|
||||||
const Ldap = require("./ldap");
|
const Ldap = require("./ldap");
|
||||||
const AccessControl = require("./access_control");
|
const AccessControl = require("./access_control");
|
||||||
|
@ -19,7 +19,7 @@ export default class Server {
|
||||||
private httpServer: http.Server;
|
private httpServer: http.Server;
|
||||||
|
|
||||||
start(yaml_configuration: UserConfiguration, deps: GlobalDependencies): Promise<void> {
|
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 view_directory = Path.resolve(__dirname, "../views");
|
||||||
const public_html_directory = Path.resolve(__dirname, "../public_html");
|
const public_html_directory = Path.resolve(__dirname, "../public_html");
|
||||||
|
@ -54,7 +54,7 @@ export default class Server {
|
||||||
const five_minutes = 5 * 60;
|
const five_minutes = 5 * 60;
|
||||||
const data_store = new UserDataStore(datastore_options);
|
const data_store = new UserDataStore(datastore_options);
|
||||||
const regulator = new AuthenticationRegulator(data_store, five_minutes);
|
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 ldap = new Ldap(deps, config.ldap);
|
||||||
const access_control = AccessControl(deps.winston, config.access_control);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
25
src/lib/notifiers/FileSystemNotifier.ts
Normal file
25
src/lib/notifiers/FileSystemNotifier.ts
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
44
src/lib/notifiers/GMailNotifier.ts
Normal file
44
src/lib/notifiers/GMailNotifier.ts
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
7
src/lib/notifiers/INotifier.ts
Normal file
7
src/lib/notifiers/INotifier.ts
Normal file
|
@ -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>;
|
||||||
|
}
|
22
src/lib/notifiers/NotifierFactory.ts
Normal file
22
src/lib/notifiers/NotifierFactory.ts
Normal file
|
@ -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,
|
store_in_memory: true,
|
||||||
notifier: {
|
notifier: {
|
||||||
gmail: {
|
gmail: {
|
||||||
user: "user@example.com",
|
username: "user@example.com",
|
||||||
pass: "password"
|
password: "password"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import * as Assert from "assert";
|
import * as Assert from "assert";
|
||||||
import { UserConfiguration } from "../../src/lib/Configuration";
|
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() {
|
describe("test config adapter", function() {
|
||||||
function build_yaml_config(): UserConfiguration {
|
function build_yaml_config(): UserConfiguration {
|
||||||
|
@ -22,8 +21,8 @@ describe("test config adapter", function() {
|
||||||
logs_level: "debug",
|
logs_level: "debug",
|
||||||
notifier: {
|
notifier: {
|
||||||
gmail: {
|
gmail: {
|
||||||
user: "user",
|
username: "user",
|
||||||
pass: "password"
|
password: "password"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -33,14 +32,14 @@ describe("test config adapter", function() {
|
||||||
it("should read the port from the yaml file", function() {
|
it("should read the port from the yaml file", function() {
|
||||||
const yaml_config = build_yaml_config();
|
const yaml_config = build_yaml_config();
|
||||||
yaml_config.port = 7070;
|
yaml_config.port = 7070;
|
||||||
const config = config_adapter(yaml_config);
|
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||||
Assert.equal(config.port, 7070);
|
Assert.equal(config.port, 7070);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should default the port to 8080 if not provided", function() {
|
it("should default the port to 8080 if not provided", function() {
|
||||||
const yaml_config = build_yaml_config();
|
const yaml_config = build_yaml_config();
|
||||||
delete yaml_config.port;
|
delete yaml_config.port;
|
||||||
const config = config_adapter(yaml_config);
|
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||||
Assert.equal(config.port, 8080);
|
Assert.equal(config.port, 8080);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ describe("test config adapter", function() {
|
||||||
password: "pass"
|
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.url, "http://ldap");
|
||||||
Assert.equal(config.ldap.additional_user_dn, "ou=users");
|
Assert.equal(config.ldap.additional_user_dn, "ou=users");
|
||||||
|
@ -71,7 +70,7 @@ describe("test config adapter", function() {
|
||||||
secret: "secret",
|
secret: "secret",
|
||||||
expiration: 3600
|
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.domain, "example.com");
|
||||||
Assert.equal(config.session.secret, "secret");
|
Assert.equal(config.session.secret, "secret");
|
||||||
Assert.equal(config.session.expiration, 3600);
|
Assert.equal(config.session.expiration, 3600);
|
||||||
|
@ -80,7 +79,7 @@ describe("test config adapter", function() {
|
||||||
it("should get the log level", function() {
|
it("should get the log level", function() {
|
||||||
const yaml_config = build_yaml_config();
|
const yaml_config = build_yaml_config();
|
||||||
yaml_config.logs_level = "debug";
|
yaml_config.logs_level = "debug";
|
||||||
const config = config_adapter(yaml_config);
|
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||||
Assert.equal(config.logs_level, "debug");
|
Assert.equal(config.logs_level, "debug");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -88,15 +87,15 @@ describe("test config adapter", function() {
|
||||||
const yaml_config = build_yaml_config();
|
const yaml_config = build_yaml_config();
|
||||||
yaml_config.notifier = {
|
yaml_config.notifier = {
|
||||||
gmail: {
|
gmail: {
|
||||||
user: "user",
|
username: "user",
|
||||||
pass: "pass"
|
password: "pass"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const config = config_adapter(yaml_config);
|
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||||
Assert.deepEqual(config.notifier, {
|
Assert.deepEqual(config.notifier, {
|
||||||
gmail: {
|
gmail: {
|
||||||
user: "user",
|
username: "user",
|
||||||
pass: "pass"
|
password: "pass"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -108,7 +107,7 @@ describe("test config adapter", function() {
|
||||||
users: {},
|
users: {},
|
||||||
groups: {}
|
groups: {}
|
||||||
};
|
};
|
||||||
const config = config_adapter(yaml_config);
|
const config = ConfigurationAdapter.adapt(yaml_config);
|
||||||
Assert.deepEqual(config.access_control, {
|
Assert.deepEqual(config.access_control, {
|
||||||
default: [],
|
default: [],
|
||||||
users: {},
|
users: {},
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as request from "request";
|
||||||
|
|
||||||
import Server from "../../src/lib/Server";
|
import Server from "../../src/lib/Server";
|
||||||
import { UserConfiguration } from "../../src/lib/Configuration";
|
import { UserConfiguration } from "../../src/lib/Configuration";
|
||||||
import { GlobalDependencies } from "../../src/lib/GlobalDependencies";
|
import { GlobalDependencies } from "../../src/lib/Dependencies";
|
||||||
import * as tmp from "tmp";
|
import * as tmp from "tmp";
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,8 +77,8 @@ describe("test data persistence", function () {
|
||||||
store_directory: tmpDir.name,
|
store_directory: tmpDir.name,
|
||||||
notifier: {
|
notifier: {
|
||||||
gmail: {
|
gmail: {
|
||||||
user: "user@example.com",
|
username: "user@example.com",
|
||||||
pass: "password"
|
password: "password"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
7
test/unitary/mocks/nodemailer.ts
Normal file
7
test/unitary/mocks/nodemailer.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
import sinon = require("sinon");
|
||||||
|
import { Nodemailer } from "../../../src/lib/Dependencies";
|
||||||
|
|
||||||
|
export = {
|
||||||
|
createTransport: sinon.stub()
|
||||||
|
};
|
42
test/unitary/notifiers/FileSystemNotifier.test.ts
Normal file
42
test/unitary/notifiers/FileSystemNotifier.test.ts
Normal file
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
39
test/unitary/notifiers/GMailNotifier.test.ts
Normal file
39
test/unitary/notifiers/GMailNotifier.test.ts
Normal file
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
39
test/unitary/notifiers/NotifierFactory.test.ts
Normal file
39
test/unitary/notifiers/NotifierFactory.test.ts
Normal file
|
@ -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 * as u2f from "authdog";
|
||||||
|
|
||||||
import { AppConfiguration, UserConfiguration } from "../../src/lib/Configuration";
|
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";
|
import Server from "../../src/lib/Server";
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,18 +20,18 @@ describe("test server configuration", function () {
|
||||||
sendMail: sinon.stub().yields()
|
sendMail: sinon.stub().yields()
|
||||||
};
|
};
|
||||||
|
|
||||||
const nodemailer = {
|
const nodemailer: Nodemailer = {
|
||||||
createTransport: sinon.spy(function () {
|
createTransport: sinon.spy(function () {
|
||||||
return transporter;
|
return transporter;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
deps = {
|
deps = {
|
||||||
|
nodemailer: nodemailer,
|
||||||
speakeasy: speakeasy,
|
speakeasy: speakeasy,
|
||||||
u2f: u2f,
|
u2f: u2f,
|
||||||
nedb: nedb,
|
nedb: nedb,
|
||||||
winston: winston,
|
winston: winston,
|
||||||
nodemailer: nodemailer,
|
|
||||||
ldapjs: {
|
ldapjs: {
|
||||||
createClient: sinon.spy(function () {
|
createClient: sinon.spy(function () {
|
||||||
return { on: sinon.spy() };
|
return { on: sinon.spy() };
|
||||||
|
@ -57,8 +57,8 @@ describe("test server configuration", function () {
|
||||||
},
|
},
|
||||||
notifier: {
|
notifier: {
|
||||||
gmail: {
|
gmail: {
|
||||||
user: "user@example.com",
|
username: "user@example.com",
|
||||||
pass: "password"
|
password: "password"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} as UserConfiguration;
|
} as UserConfiguration;
|
||||||
|
|
69
test/unitary/test_server_config.ts
Normal file
69
test/unitary/test_server_config.ts
Normal file
|
@ -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
Block a user