Merge pull request #97 from clems4ever/smtp-notifier
Add SMTP notifier as an available option in configurationpull/98/head
commit
92ef190202
|
@ -29,3 +29,5 @@ dist/
|
|||
|
||||
# Specific files
|
||||
/config.yml
|
||||
|
||||
example/ldap/private.ldif
|
||||
|
|
25
README.md
25
README.md
|
@ -39,14 +39,15 @@ as 2nd factor.
|
|||
address.
|
||||
* Access restriction after too many authentication attempts.
|
||||
* Session management using Redis key/value store.
|
||||
* User-defined access control per subdomain and resource.
|
||||
|
||||
## Deployment
|
||||
|
||||
If you don't have any LDAP and/or nginx setup yet, I advise you to follow the
|
||||
[Getting Started](#Getting-started) section. That way, you can test it right away
|
||||
without even configure anything.
|
||||
without even configuring anything.
|
||||
|
||||
Otherwise here are the available steps to deploy **Authelia** on your machine given
|
||||
Otherwise, here are the available steps to deploy **Authelia** on your machine given
|
||||
your configuration file is **/path/to/your/config.yml**. Note that you can create your
|
||||
own the configuration file from [config.template.yml] at the root of the repo.
|
||||
|
||||
|
@ -85,7 +86,7 @@ gave *Docker version 17.03.1-ce, build c6d412e*.
|
|||
gave *docker-compose version 1.14.0, build c7bdf9e*.
|
||||
|
||||
#### Available port
|
||||
Make sure you don't have anything listening on port 8080.
|
||||
Make sure you don't have anything listening on port 8080 (webserver) and 8085 (webmail).
|
||||
|
||||
#### Subdomain aliases
|
||||
|
||||
|
@ -141,10 +142,16 @@ You can find an example of the configuration of the LDAP backend in [config.temp
|
|||
### Second factor with TOTP
|
||||
In **Authelia**, you can register a per user TOTP (Time-Based One Time Password) secret before
|
||||
authenticating. To do that, you need to click on the register button. It will
|
||||
<<<<<<< 7a2b45a66fba8ad1862f25cfa727df03d218ba83
|
||||
send a link to the user email address defined in the LDAP.
|
||||
Since this is an example, no email will be sent, the link is rather delivered in the file
|
||||
**/tmp/notifications/notification.txt**. Paste the link in your browser and you'll get
|
||||
your secret in QRCode and Base32 format. You can use
|
||||
=======
|
||||
send a link to the user email address stored in LDAP. Since this is an example, the email is sent
|
||||
to a fake email address you can access from the webmail at [http://localhost:8085](http://localhost:8085).
|
||||
Click on **Continue** and you'll get your secret in QRCode and Base32 formats. You can use
|
||||
>>>>>>> Add SMTP notifier as an available option in configuration
|
||||
[Google Authenticator]
|
||||
to store them and get the generated tokens with the app.
|
||||
|
||||
|
@ -155,11 +162,19 @@ to store them and get the generated tokens with the app.
|
|||
USB security keys. U2F is one of the most secure authentication protocol and is
|
||||
already available for Google, Facebook, Github accounts and more.
|
||||
|
||||
<<<<<<< 7a2b45a66fba8ad1862f25cfa727df03d218ba83
|
||||
Like TOTP, U2F requires you register a security key before authenticating.
|
||||
To do so, click on the register link. This will send a link to the
|
||||
user email address. Since this is an example, no email will be sent, the
|
||||
link is rather delivered in the file **/tmp/notifications/notification.txt**. Paste
|
||||
the link in your browser and you'll be asking to touch the token of your device
|
||||
=======
|
||||
Like TOTP, U2F requires you register your security key before authenticating.
|
||||
To do so, click on the register button. This will send a link to the
|
||||
user email address. Since this is an example, the email is sent
|
||||
to a fake email address you can access from the webmail at [http://localhost:8085](http://localhost:8085).
|
||||
Click on **Continue** and you'll be asking to touch the token of your device
|
||||
>>>>>>> Add SMTP notifier as an available option in configuration
|
||||
to register. Upon successful registration, you can authenticate using your U2F
|
||||
device by simply touching the token. Easy, right?!
|
||||
|
||||
|
@ -169,8 +184,8 @@ device by simply touching the token. Easy, right?!
|
|||
With **Authelia**, you can also reset your password in no time. Click on the
|
||||
**Forgot password?** link in the login page, provide the username of the user requiring
|
||||
a password reset and **Authelia** will send an email with an link to the user
|
||||
email address. For the sake of the example, the email is delivered in the file
|
||||
**/tmp/notifications/notification.txt**.
|
||||
email address. For the sake of the example, the email is delivered in a fake webmail deployed
|
||||
for you and accessible at [http://localhost:8085](http://localhost:8085).
|
||||
Paste the link in your browser and you should be able to reset the password.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/clems4ever/authelia/master/images/reset_password.png" width="400">
|
||||
|
|
|
@ -182,12 +182,15 @@ storage:
|
|||
# registration or a TOTP registration.
|
||||
# Use only an available configuration: filesystem, gmail
|
||||
notifier:
|
||||
# For testing purpose, notifications can be sent in a file
|
||||
filesystem:
|
||||
filename: /var/lib/authelia/notifications/notification.txt
|
||||
|
||||
# Use your gmail account to send the notifications. You can use an app password.
|
||||
# gmail:
|
||||
# username: user@example.com
|
||||
# password: yourpassword
|
||||
|
||||
# Use a SMTP server for sending notifications
|
||||
smtp:
|
||||
username: test
|
||||
password: test
|
||||
secure: false
|
||||
host: 'smtp'
|
||||
port: 1025
|
||||
|
|
|
@ -162,12 +162,16 @@ storage:
|
|||
# registration or a TOTP registration.
|
||||
# Use only an available configuration: filesystem, gmail
|
||||
notifier:
|
||||
# For testing purpose, notifications can be sent in a file
|
||||
filesystem:
|
||||
filename: /var/lib/authelia/notifications/notification.txt
|
||||
|
||||
# Use your gmail account to send the notifications. You can use an app password.
|
||||
# gmail:
|
||||
# username: user@example.com
|
||||
# password: yourpassword
|
||||
|
||||
# Use a SMTP server for sending notifications
|
||||
smtp:
|
||||
username: test
|
||||
password: test
|
||||
secure: false
|
||||
host: 'smtp'
|
||||
port: 1025
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ services:
|
|||
restart: always
|
||||
volumes:
|
||||
- ./config.template.yml:/etc/authelia/config.yml:ro
|
||||
- /tmp/notifications:/var/lib/authelia/notifications
|
||||
depends_on:
|
||||
- redis
|
||||
networks:
|
||||
|
|
|
@ -25,7 +25,7 @@ dn: cn=john,ou=users,dc=example,dc=com
|
|||
cn: john
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
mail: john.doe@example.com
|
||||
mail: john.doe@authelia.com
|
||||
sn: John Doe
|
||||
userpassword: {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
|
||||
|
||||
|
@ -33,7 +33,7 @@ dn: cn=harry,ou=users,dc=example,dc=com
|
|||
cn: harry
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
mail: harry.potter@example.com
|
||||
mail: harry.potter@authelia.com
|
||||
sn: Harry Potter
|
||||
userpassword: {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
|
||||
|
||||
|
@ -41,7 +41,7 @@ dn: cn=bob,ou=users,dc=example,dc=com
|
|||
cn: bob
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
mail: bob.dylan@example.com
|
||||
mail: bob.dylan@authelia.com
|
||||
sn: Bob Dylan
|
||||
userpassword: {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
|
||||
|
||||
|
@ -49,7 +49,7 @@ dn: cn=james,ou=users,dc=example,dc=com
|
|||
cn: james
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
mail: james.dean@example.com
|
||||
mail: james.dean@authelia.com
|
||||
sn: James Dean
|
||||
userpassword: {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
|
||||
|
||||
|
@ -57,6 +57,6 @@ dn: cn=blackhat,ou=users,dc=example,dc=com
|
|||
cn: blackhat
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
mail: billy.blackhat@example.com
|
||||
mail: billy.blackhat@authelia.com
|
||||
sn: Billy BlackHat
|
||||
userpassword: {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
version: '2'
|
||||
services:
|
||||
smtp:
|
||||
image: schickling/mailcatcher
|
||||
ports:
|
||||
- "8085:1080"
|
||||
networks:
|
||||
- example-network
|
|
@ -66,6 +66,7 @@
|
|||
"@types/randomstring": "^1.1.5",
|
||||
"@types/redis": "^2.6.0",
|
||||
"@types/request": "0.0.46",
|
||||
"@types/request-promise": "^4.1.37",
|
||||
"@types/selenium-webdriver": "^3.0.4",
|
||||
"@types/sinon": "^2.2.1",
|
||||
"@types/speakeasy": "^2.0.1",
|
||||
|
@ -94,6 +95,7 @@
|
|||
"proxyquire": "^1.8.0",
|
||||
"query-string": "^4.3.4",
|
||||
"request": "^2.81.0",
|
||||
"request-promise": "^4.2.2",
|
||||
"selenium-webdriver": "^3.5.0",
|
||||
"should": "^11.1.1",
|
||||
"sinon": "^2.3.8",
|
||||
|
|
|
@ -9,5 +9,6 @@ docker-compose \
|
|||
-f example/mongo/docker-compose.yml \
|
||||
-f example/redis/docker-compose.yml \
|
||||
-f example/nginx/docker-compose.yml \
|
||||
-f example/smtp/docker-compose.yml \
|
||||
-f example/ldap/docker-compose.admin.yml \
|
||||
-f example/ldap/docker-compose.yml $*
|
||||
|
|
|
@ -8,4 +8,5 @@ docker-compose \
|
|||
-f example/mongo/docker-compose.yml \
|
||||
-f example/redis/docker-compose.yml \
|
||||
-f example/nginx/docker-compose.yml \
|
||||
-f example/smtp/docker-compose.yml \
|
||||
-f example/ldap/docker-compose.yml $*
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
DC_SCRIPT=./scripts/example-commit/dc-example.sh
|
||||
|
||||
$DC_SCRIPT build
|
||||
$DC_SCRIPT up -d mongo redis openldap authelia nginx
|
||||
$DC_SCRIPT up -d mongo redis openldap authelia nginx smtp
|
||||
|
|
|
@ -8,4 +8,5 @@ docker-compose \
|
|||
-f example/mongo/docker-compose.yml \
|
||||
-f example/redis/docker-compose.yml \
|
||||
-f example/nginx/docker-compose.yml \
|
||||
-f example/smtp/docker-compose.yml \
|
||||
-f example/ldap/docker-compose.yml $*
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
DC_SCRIPT=./scripts/example-dockerhub/dc-example.sh
|
||||
|
||||
#$DC_SCRIPT build
|
||||
$DC_SCRIPT up -d mongo redis openldap authelia nginx
|
||||
$DC_SCRIPT up -d mongo redis openldap authelia nginx smtp
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
DC_SCRIPT=./scripts/example-commit/dc-example.sh
|
||||
EXPECTED_SERVICES_COUNT=5
|
||||
EXPECTED_SERVICES_COUNT=6
|
||||
|
||||
start_services() {
|
||||
$DC_SCRIPT up -d mongo redis openldap authelia nginx
|
||||
$DC_SCRIPT up -d mongo redis openldap authelia nginx smtp
|
||||
sleep 3
|
||||
}
|
||||
|
||||
|
@ -41,13 +41,13 @@ run_other_tests() {
|
|||
npm install --only=dev
|
||||
./node_modules/.bin/grunt build-dist
|
||||
./scripts/example-commit/deploy-example.sh
|
||||
expect_services_count 5
|
||||
expect_services_count $EXPECTED_SERVICES_COUNT
|
||||
}
|
||||
|
||||
run_other_tests_docker() {
|
||||
echo "Test dev docker deployment (commands in README)"
|
||||
./scripts/example-dockerhub/deploy-example.sh
|
||||
expect_services_count 5
|
||||
expect_services_count $EXPECTED_SERVICES_COUNT
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -71,12 +71,21 @@ export interface GmailNotifierConfiguration {
|
|||
password: string;
|
||||
}
|
||||
|
||||
export interface SmtpNotifierConfiguration {
|
||||
username: string;
|
||||
password: string;
|
||||
host: string;
|
||||
port: number;
|
||||
secure: boolean;
|
||||
}
|
||||
|
||||
export interface FileSystemNotifierConfiguration {
|
||||
filename: string;
|
||||
}
|
||||
|
||||
export interface NotifierConfiguration {
|
||||
gmail?: GmailNotifierConfiguration;
|
||||
smtp?: SmtpNotifierConfiguration;
|
||||
filesystem?: FileSystemNotifierConfiguration;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
import { INotifier } from "../notifiers/INotifier";
|
||||
import { Identity } from "../../../types/Identity";
|
||||
|
||||
import Fs = require("fs");
|
||||
import Path = require("path");
|
||||
import Ejs = require("ejs");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
|
||||
const email_template = Fs.readFileSync(Path.join(__dirname, "../../resources/email-template.ejs"), "UTF-8");
|
||||
|
||||
export abstract class AbstractEmailNotifier implements INotifier {
|
||||
|
||||
notify(identity: Identity, subject: string, link: string): BluebirdPromise<void> {
|
||||
const d = {
|
||||
url: link,
|
||||
button_title: "Continue",
|
||||
title: subject
|
||||
};
|
||||
return this.sendEmail(identity.email, subject, Ejs.render(email_template, d));
|
||||
}
|
||||
|
||||
abstract sendEmail(email: string, subject: string, content: string): BluebirdPromise<void>;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
import * as BluebirdPromise from "bluebird";
|
||||
import * as util from "util";
|
||||
import * as Fs from "fs";
|
||||
import { INotifier } from "./INotifier";
|
||||
import { Identity } from "../../../types/Identity";
|
||||
|
||||
import { FileSystemNotifierConfiguration } from "../configuration/Configuration";
|
||||
|
||||
export class FileSystemNotifier implements INotifier {
|
||||
private filename: string;
|
||||
|
||||
constructor(options: FileSystemNotifierConfiguration) {
|
||||
this.filename = options.filename;
|
||||
}
|
||||
|
||||
notify(identity: Identity, subject: string, link: string): BluebirdPromise<void> {
|
||||
const content = util.format("Date: %s\nUser: %s\nSubject: %s\nLink: %s", new Date().toString(), identity.userid,
|
||||
subject, link);
|
||||
const writeFilePromised: any = BluebirdPromise.promisify(Fs.writeFile);
|
||||
return writeFilePromised(this.filename, content);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,16 @@
|
|||
|
||||
import * as BluebirdPromise from "bluebird";
|
||||
import * as fs from "fs";
|
||||
import * as ejs from "ejs";
|
||||
import nodemailer = require("nodemailer");
|
||||
|
||||
import { Nodemailer } from "../../../types/Dependencies";
|
||||
import { Identity } from "../../../types/Identity";
|
||||
import { INotifier } from "../notifiers/INotifier";
|
||||
import { AbstractEmailNotifier } from "../notifiers/AbstractEmailNotifier";
|
||||
import { GmailNotifierConfiguration } from "../configuration/Configuration";
|
||||
import path = require("path");
|
||||
|
||||
const email_template = fs.readFileSync(path.join(__dirname, "../../resources/email-template.ejs"), "UTF-8");
|
||||
|
||||
export class GMailNotifier implements INotifier {
|
||||
export class GMailNotifier extends AbstractEmailNotifier {
|
||||
private transporter: any;
|
||||
|
||||
constructor(options: GmailNotifierConfiguration, nodemailer: Nodemailer) {
|
||||
super();
|
||||
const transporter = nodemailer.createTransport({
|
||||
service: "gmail",
|
||||
auth: {
|
||||
|
@ -26,18 +21,12 @@ export class GMailNotifier implements INotifier {
|
|||
this.transporter = BluebirdPromise.promisifyAll(transporter);
|
||||
}
|
||||
|
||||
notify(identity: Identity, subject: string, link: string): BluebirdPromise<void> {
|
||||
const d = {
|
||||
url: link,
|
||||
button_title: "Continue",
|
||||
title: subject
|
||||
};
|
||||
|
||||
sendEmail(email: string, subject: string, content: string) {
|
||||
const mailOptions = {
|
||||
from: "authelia@authelia.com",
|
||||
to: identity.email,
|
||||
to: email,
|
||||
subject: subject,
|
||||
html: ejs.render(email_template, d)
|
||||
html: content
|
||||
};
|
||||
return this.transporter.sendMailAsync(mailOptions);
|
||||
}
|
||||
|
|
|
@ -4,15 +4,18 @@ import { Nodemailer } from "../../../types/Dependencies";
|
|||
import { INotifier } from "./INotifier";
|
||||
|
||||
import { GMailNotifier } from "./GMailNotifier";
|
||||
import { FileSystemNotifier } from "./FileSystemNotifier";
|
||||
import { SmtpNotifier } from "./SmtpNotifier";
|
||||
|
||||
export class NotifierFactory {
|
||||
static build(options: NotifierConfiguration, nodemailer: Nodemailer): INotifier {
|
||||
if ("gmail" in options) {
|
||||
return new GMailNotifier(options.gmail, nodemailer);
|
||||
}
|
||||
else if ("filesystem" in options) {
|
||||
return new FileSystemNotifier(options.filesystem);
|
||||
else if ("smtp" in options) {
|
||||
return new SmtpNotifier(options.smtp, nodemailer);
|
||||
}
|
||||
else {
|
||||
throw new Error("No available notifier option detected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
|
||||
import * as BluebirdPromise from "bluebird";
|
||||
import Nodemailer = require("nodemailer");
|
||||
|
||||
import { AbstractEmailNotifier } from "../notifiers/AbstractEmailNotifier";
|
||||
import { SmtpNotifierConfiguration } from "../configuration/Configuration";
|
||||
|
||||
export class SmtpNotifier extends AbstractEmailNotifier {
|
||||
private transporter: any;
|
||||
|
||||
constructor(options: SmtpNotifierConfiguration, nodemailer: typeof Nodemailer) {
|
||||
super();
|
||||
const smtpOptions = {
|
||||
host: options.host,
|
||||
port: options.port,
|
||||
secure: options.secure, // upgrade later with STARTTLS
|
||||
auth: {
|
||||
user: options.username,
|
||||
pass: options.password
|
||||
}
|
||||
};
|
||||
console.log(smtpOptions);
|
||||
const transporter = nodemailer.createTransport(smtpOptions);
|
||||
this.transporter = BluebirdPromise.promisifyAll(transporter);
|
||||
|
||||
// verify connection configuration
|
||||
console.log("Checking SMTP server connection.");
|
||||
transporter.verify(function (error, success) {
|
||||
if (error) {
|
||||
throw new Error("Unable to connect to SMTP server. \
|
||||
Please check the service is running and your credentials are correct.");
|
||||
} else {
|
||||
console.log("SMTP Server is ready to take our messages");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sendEmail(email: string, subject: string, content: string) {
|
||||
const mailOptions = {
|
||||
from: "authelia@authelia.com",
|
||||
to: email,
|
||||
subject: subject,
|
||||
html: content
|
||||
};
|
||||
return this.transporter.sendMail(mailOptions, (error: Error, data: string) => {
|
||||
if (error) {
|
||||
return console.log(error);
|
||||
}
|
||||
console.log("Message sent: %s", JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -9,12 +9,10 @@ Cucumber.defineSupportCode(function ({ Given, When, Then }) {
|
|||
});
|
||||
|
||||
When("I click on the link of the email", function () {
|
||||
const notif = Fs.readFileSync("/tmp/notifications/notification.txt").toString();
|
||||
const regexp = new RegExp(/Link: (.+)/);
|
||||
const match = regexp.exec(notif);
|
||||
const link = match[1];
|
||||
const that = this;
|
||||
|
||||
return this.driver.get(link);
|
||||
return this.retrieveLatestMail()
|
||||
.then(function (link: string) {
|
||||
return that.driver.get(link);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -4,6 +4,8 @@ import Cucumber = require("cucumber");
|
|||
import Fs = require("fs");
|
||||
import Speakeasy = require("speakeasy");
|
||||
import Assert = require("assert");
|
||||
import Request = require("request-promise");
|
||||
import BluebirdPromise = require("bluebird");
|
||||
|
||||
function CustomWorld() {
|
||||
const that = this;
|
||||
|
@ -49,7 +51,7 @@ function CustomWorld() {
|
|||
.click();
|
||||
})
|
||||
.then(function () {
|
||||
return that.driver.sleep(500);
|
||||
return that.driver.sleep(1000);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -69,18 +71,37 @@ function CustomWorld() {
|
|||
});
|
||||
};
|
||||
|
||||
this.retrieveLatestMail = function () {
|
||||
return Request({
|
||||
method: "GET",
|
||||
uri: "http://localhost:8085/messages",
|
||||
json: true
|
||||
})
|
||||
.then(function (data: any) {
|
||||
const messageId = data[data.length - 1].id;
|
||||
return Request({
|
||||
method: "GET",
|
||||
uri: `http://localhost:8085/messages/${messageId}.html`
|
||||
});
|
||||
})
|
||||
.then(function (data: any) {
|
||||
const regexp = new RegExp(/<a href="(.+)" class="button">Continue<\/a>/);
|
||||
const match = regexp.exec(data);
|
||||
const link = match[1];
|
||||
return BluebirdPromise.resolve(link);
|
||||
});
|
||||
};
|
||||
|
||||
this.registerTotpSecret = function (totpSecretHandle: string) {
|
||||
return that.driver.wait(seleniumWebdriver.until.elementLocated(seleniumWebdriver.By.className("register-totp")), 4000)
|
||||
.then(function () {
|
||||
return that.driver.findElement(seleniumWebdriver.By.className("register-totp")).click();
|
||||
})
|
||||
.then(function () {
|
||||
const notif = Fs.readFileSync("/tmp/notifications/notification.txt").toString();
|
||||
const regexp = new RegExp(/Link: (.+)/);
|
||||
const match = regexp.exec(notif);
|
||||
const link = match[1];
|
||||
console.log("Link: " + link);
|
||||
return that.driver.get(link);
|
||||
return that.retrieveLatestMail();
|
||||
})
|
||||
.then(function (url: string) {
|
||||
return that.driver.get(url);
|
||||
})
|
||||
.then(function () {
|
||||
return that.driver.wait(seleniumWebdriver.until.elementLocated(seleniumWebdriver.By.id("secret")), 5000);
|
||||
|
|
|
@ -13,10 +13,12 @@ export function NodemailerMock(): NodemailerMock {
|
|||
|
||||
export interface NodemailerTransporterMock {
|
||||
sendMail: sinon.SinonStub;
|
||||
verify: sinon.SinonStub;
|
||||
}
|
||||
|
||||
export function NodemailerTransporterMock() {
|
||||
return {
|
||||
sendMail: sinon.stub()
|
||||
sendMail: sinon.stub(),
|
||||
verify: sinon.stub()
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
|
||||
import * as sinon from "sinon";
|
||||
import * as assert from "assert";
|
||||
import { FileSystemNotifier } from "../../../../src/server/lib/notifiers/FileSystemNotifier";
|
||||
import * as tmp from "tmp";
|
||||
import * as fs from "fs";
|
||||
import BluebirdPromise = require("bluebird");
|
||||
|
||||
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 BluebirdPromise.resolve();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -5,7 +5,7 @@ import * as assert from "assert";
|
|||
|
||||
import { NotifierFactory } from "../../../../src/server/lib/notifiers/NotifierFactory";
|
||||
import { GMailNotifier } from "../../../../src/server/lib/notifiers/GMailNotifier";
|
||||
import { FileSystemNotifier } from "../../../../src/server/lib/notifiers/FileSystemNotifier";
|
||||
import { SmtpNotifier } from "../../../../src/server/lib/notifiers/SmtpNotifier";
|
||||
|
||||
import NodemailerMock = require("../mocks/nodemailer");
|
||||
|
||||
|
@ -20,17 +20,25 @@ describe("test notifier factory", function() {
|
|||
}
|
||||
};
|
||||
nodemailerMock = NodemailerMock.NodemailerMock();
|
||||
nodemailerMock.createTransport.returns(sinon.spy());
|
||||
const transporterMock = NodemailerMock.NodemailerTransporterMock();
|
||||
nodemailerMock.createTransport.returns(transporterMock);
|
||||
assert(NotifierFactory.build(options, nodemailerMock) instanceof GMailNotifier);
|
||||
});
|
||||
|
||||
it("should build a FS Notifier", function() {
|
||||
it("should build a SMTP Notifier", function() {
|
||||
const options = {
|
||||
filesystem: {
|
||||
filename: "abc"
|
||||
smtp: {
|
||||
username: "user",
|
||||
password: "pass",
|
||||
secure: true,
|
||||
host: "localhost",
|
||||
port: 25
|
||||
}
|
||||
};
|
||||
|
||||
assert(NotifierFactory.build(options, nodemailerMock) instanceof FileSystemNotifier);
|
||||
nodemailerMock = NodemailerMock.NodemailerMock();
|
||||
const transporterMock = NodemailerMock.NodemailerTransporterMock();
|
||||
nodemailerMock.createTransport.returns(transporterMock);
|
||||
assert(NotifierFactory.build(options, nodemailerMock) instanceof SmtpNotifier);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue