From c62b85e37d84cfaa38da2f23ba4cbeb227bc2c14 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Wed, 25 Oct 2017 19:28:56 +1100 Subject: [PATCH] Less restrictive email handler - replace gmail with generic --- config.template.yml | 6 ++++-- config.test.yml | 6 ++++-- server/src/lib/Server.ts | 8 ++++---- server/src/lib/configuration/Configuration.d.ts | 5 +++-- server/src/lib/configuration/Validator.ts | 8 ++++---- .../{GMailNotifier.ts => EMailNotifier.ts} | 6 +++--- server/src/lib/notifiers/IMailSenderBuilder.ts | 4 ++-- server/src/lib/notifiers/MailSenderBuilder.ts | 10 +++++----- server/src/lib/notifiers/NotifierFactory.ts | 8 ++++---- server/test/ServerConfiguration.test.ts | 5 +++-- .../configuration/ConfigurationParser.test.ts | 15 +++++++++------ .../LdapConfigurationAdaptation.test.ts | 5 +++-- server/test/configuration/Validator.test.ts | 7 ++++--- .../test/mocks/notifiers/MailSenderBuilderStub.ts | 10 +++++----- ...MailNotifier.test.ts => EMailNotifier.test.ts} | 14 ++++++++------ server/test/notifiers/MailSenderBuilder.test.ts | 8 +++++--- server/test/notifiers/NotifierFactory.test.ts | 11 ++++++----- server/test/server/PrivatePages.ts | 5 +++-- server/test/server/PublicPages.ts | 5 +++-- 19 files changed, 82 insertions(+), 64 deletions(-) rename server/src/lib/notifiers/{GMailNotifier.ts => EMailNotifier.ts} (75%) rename server/test/notifiers/{GMailNotifier.test.ts => EMailNotifier.test.ts} (80%) diff --git a/config.template.yml b/config.template.yml index 83f1fed72..80f277abe 100644 --- a/config.template.yml +++ b/config.template.yml @@ -203,11 +203,13 @@ notifier: # filesystem: # filename: /tmp/authelia/notification.txt - # Use your gmail account to send the notifications. You can use an app password. - # gmail: + # Use your email account to send the notifications. You can use an app password. + # List of valid services can be found here: https://nodemailer.com/smtp/well-known/ + # email: # username: user@example.com # password: yourpassword # sender: admin@example.com + # service: gmail # Use a SMTP server for sending notifications smtp: diff --git a/config.test.yml b/config.test.yml index ca70f5275..842e77656 100644 --- a/config.test.yml +++ b/config.test.yml @@ -178,11 +178,13 @@ storage: # registration or a TOTP registration. # Use only an available configuration: filesystem, gmail notifier: - # Use your gmail account to send the notifications. You can use an app password. - # gmail: + # Use your email account to send the notifications. You can use an app password. + # List of valid services can be found here: https://nodemailer.com/smtp/well-known/ + # email: # username: user@example.com # password: yourpassword # sender: admin@example.com + # service: gmail # Use a SMTP server for sending notifications smtp: diff --git a/server/src/lib/Server.ts b/server/src/lib/Server.ts index f043d4f33..a5e6162bd 100644 --- a/server/src/lib/Server.ts +++ b/server/src/lib/Server.ts @@ -71,15 +71,15 @@ export default class Server { displayableUserConfiguration.ldap.password = STARS; displayableUserConfiguration.session.secret = STARS; - if (displayableUserConfiguration.notifier && displayableUserConfiguration.notifier.gmail) - displayableUserConfiguration.notifier.gmail.password = STARS; + if (displayableUserConfiguration.notifier && displayableUserConfiguration.notifier.email) + displayableUserConfiguration.notifier.email.password = STARS; if (displayableUserConfiguration.notifier && displayableUserConfiguration.notifier.smtp) displayableUserConfiguration.notifier.smtp.password = STARS; displayableAppConfiguration.ldap.password = STARS; displayableAppConfiguration.session.secret = STARS; - if (displayableAppConfiguration.notifier && displayableAppConfiguration.notifier.gmail) - displayableAppConfiguration.notifier.gmail.password = STARS; + if (displayableAppConfiguration.notifier && displayableAppConfiguration.notifier.email) + displayableAppConfiguration.notifier.email.password = STARS; if (displayableAppConfiguration.notifier && displayableAppConfiguration.notifier.smtp) displayableAppConfiguration.notifier.smtp.password = STARS; diff --git a/server/src/lib/configuration/Configuration.d.ts b/server/src/lib/configuration/Configuration.d.ts index 199a84bc0..cda35e14f 100644 --- a/server/src/lib/configuration/Configuration.d.ts +++ b/server/src/lib/configuration/Configuration.d.ts @@ -66,10 +66,11 @@ interface SessionCookieConfiguration { redis?: SessionRedisOptions; } -export interface GmailNotifierConfiguration { +export interface EmailNotifierConfiguration { username: string; password: string; sender: string; + service: string; } export interface SmtpNotifierConfiguration { @@ -86,7 +87,7 @@ export interface FileSystemNotifierConfiguration { } export interface NotifierConfiguration { - gmail?: GmailNotifierConfiguration; + email?: EmailNotifierConfiguration; smtp?: SmtpNotifierConfiguration; filesystem?: FileSystemNotifierConfiguration; } diff --git a/server/src/lib/configuration/Validator.ts b/server/src/lib/configuration/Validator.ts index 5058d08d7..26a983948 100644 --- a/server/src/lib/configuration/Validator.ts +++ b/server/src/lib/configuration/Validator.ts @@ -54,19 +54,19 @@ function validateStorage(storage: any) { } function validateNotifier(notifier: NotifierConfiguration) { - const ERROR = "Notifier must be either 'filesystem', 'gmail' or 'smtp'"; + const ERROR = "Notifier must be either 'filesystem', 'email' or 'smtp'"; if (!notifier) return []; - const errors = validateUnknownKeys("notifier", notifier, ["filesystem", "gmail", "smtp"]); + const errors = validateUnknownKeys("notifier", notifier, ["filesystem", "email", "smtp"]); if (errors.length > 0) return errors; - if (notifier && notifier.filesystem && notifier.gmail && notifier.smtp) + if (notifier && notifier.filesystem && notifier.email && notifier.smtp) return [ERROR]; - if (notifier && !notifier.filesystem && !notifier.gmail && !notifier.smtp) + if (notifier && !notifier.filesystem && !notifier.email && !notifier.smtp) return [ERROR]; return []; diff --git a/server/src/lib/notifiers/GMailNotifier.ts b/server/src/lib/notifiers/EMailNotifier.ts similarity index 75% rename from server/src/lib/notifiers/GMailNotifier.ts rename to server/src/lib/notifiers/EMailNotifier.ts index caa81581c..5366dfae8 100644 --- a/server/src/lib/notifiers/GMailNotifier.ts +++ b/server/src/lib/notifiers/EMailNotifier.ts @@ -2,14 +2,14 @@ import * as BluebirdPromise from "bluebird"; import { AbstractEmailNotifier } from "../notifiers/AbstractEmailNotifier"; -import { GmailNotifierConfiguration } from "../configuration/Configuration"; +import { EmailNotifierConfiguration } from "../configuration/Configuration"; import { IMailSender } from "./IMailSender"; -export class GMailNotifier extends AbstractEmailNotifier { +export class EMailNotifier extends AbstractEmailNotifier { private mailSender: IMailSender; private sender: string; - constructor(options: GmailNotifierConfiguration, mailSender: IMailSender) { + constructor(options: EmailNotifierConfiguration, mailSender: IMailSender) { super(); this.mailSender = mailSender; this.sender = options.sender; diff --git a/server/src/lib/notifiers/IMailSenderBuilder.ts b/server/src/lib/notifiers/IMailSenderBuilder.ts index 25aff7e7e..59aa677b0 100644 --- a/server/src/lib/notifiers/IMailSenderBuilder.ts +++ b/server/src/lib/notifiers/IMailSenderBuilder.ts @@ -1,7 +1,7 @@ import { IMailSender } from "./IMailSender"; -import { SmtpNotifierConfiguration, GmailNotifierConfiguration } from "../configuration/Configuration"; +import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../configuration/Configuration"; export interface IMailSenderBuilder { - buildGmail(options: GmailNotifierConfiguration): IMailSender; + buildEmail(options: EmailNotifierConfiguration): IMailSender; buildSmtp(options: SmtpNotifierConfiguration): IMailSender; } \ No newline at end of file diff --git a/server/src/lib/notifiers/MailSenderBuilder.ts b/server/src/lib/notifiers/MailSenderBuilder.ts index 1b44f7b4c..4b22ad743 100644 --- a/server/src/lib/notifiers/MailSenderBuilder.ts +++ b/server/src/lib/notifiers/MailSenderBuilder.ts @@ -3,7 +3,7 @@ import { IMailSenderBuilder } from "./IMailSenderBuilder"; import { MailSender } from "./MailSender"; import Nodemailer = require("nodemailer"); import NodemailerSmtpTransport = require("nodemailer-smtp-transport"); -import { SmtpNotifierConfiguration, GmailNotifierConfiguration } from "../configuration/Configuration"; +import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../configuration/Configuration"; export class MailSenderBuilder implements IMailSenderBuilder { private nodemailer: typeof Nodemailer; @@ -12,15 +12,15 @@ export class MailSenderBuilder implements IMailSenderBuilder { this.nodemailer = nodemailer; } - buildGmail(options: GmailNotifierConfiguration): IMailSender { - const gmailOptions = { - service: "gmail", + buildEmail(options: EmailNotifierConfiguration): IMailSender { + const emailOptions = { + service: options.service, auth: { user: options.username, pass: options.password } }; - return new MailSender(gmailOptions, this.nodemailer); + return new MailSender(emailOptions, this.nodemailer); } buildSmtp(options: SmtpNotifierConfiguration): IMailSender { diff --git a/server/src/lib/notifiers/NotifierFactory.ts b/server/src/lib/notifiers/NotifierFactory.ts index 0b200cd34..c03de76ad 100644 --- a/server/src/lib/notifiers/NotifierFactory.ts +++ b/server/src/lib/notifiers/NotifierFactory.ts @@ -4,16 +4,16 @@ import Nodemailer = require("nodemailer"); import { INotifier } from "./INotifier"; import { FileSystemNotifier } from "./FileSystemNotifier"; -import { GMailNotifier } from "./GMailNotifier"; +import { EMailNotifier } from "./EMailNotifier"; import { SmtpNotifier } from "./SmtpNotifier"; import { IMailSender } from "./IMailSender"; import { IMailSenderBuilder } from "./IMailSenderBuilder"; export class NotifierFactory { static build(options: NotifierConfiguration, mailSenderBuilder: IMailSenderBuilder): INotifier { - if ("gmail" in options) { - const mailSender = mailSenderBuilder.buildGmail(options.gmail); - return new GMailNotifier(options.gmail, mailSender); + if ("email" in options) { + const mailSender = mailSenderBuilder.buildEmail(options.email); + return new EMailNotifier(options.email, mailSender); } else if ("smtp" in options) { const mailSender = mailSenderBuilder.buildSmtp(options.smtp); diff --git a/server/test/ServerConfiguration.test.ts b/server/test/ServerConfiguration.test.ts index e33277655..715363520 100644 --- a/server/test/ServerConfiguration.test.ts +++ b/server/test/ServerConfiguration.test.ts @@ -53,10 +53,11 @@ describe("test server configuration", function () { base_dn: "dc=example,dc=com" }, notifier: { - gmail: { + email: { username: "user@example.com", password: "password", - sender: "test@authelia.com" + sender: "test@authelia.com", + service: "gmail" } }, regulation: { diff --git a/server/test/configuration/ConfigurationParser.test.ts b/server/test/configuration/ConfigurationParser.test.ts index f851dde02..4134cec38 100644 --- a/server/test/configuration/ConfigurationParser.test.ts +++ b/server/test/configuration/ConfigurationParser.test.ts @@ -34,10 +34,11 @@ describe("test config parser", function () { }, logs_level: "debug", notifier: { - gmail: { + email: { username: "user", password: "password", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" } } }; @@ -83,18 +84,20 @@ describe("test config parser", function () { it("should get the notifier config", function () { const userConfig = buildYamlConfig(); userConfig.notifier = { - gmail: { + email: { username: "user", password: "pass", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" } }; const config = ConfigurationParser.parse(userConfig); Assert.deepEqual(config.notifier, { - gmail: { + email: { username: "user", password: "pass", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" } }); }); diff --git a/server/test/configuration/LdapConfigurationAdaptation.test.ts b/server/test/configuration/LdapConfigurationAdaptation.test.ts index 2d91a4ba9..bfcc8fc00 100644 --- a/server/test/configuration/LdapConfigurationAdaptation.test.ts +++ b/server/test/configuration/LdapConfigurationAdaptation.test.ts @@ -31,10 +31,11 @@ describe("test ldap configuration adaptation", function () { }, logs_level: "debug", notifier: { - gmail: { + email: { username: "user", password: "password", - sender: "admin@example.com" + sender: "admin@example.com", + service: "email" } } }; diff --git a/server/test/configuration/Validator.test.ts b/server/test/configuration/Validator.test.ts index 69d3afca5..a797a12f5 100644 --- a/server/test/configuration/Validator.test.ts +++ b/server/test/configuration/Validator.test.ts @@ -28,7 +28,7 @@ describe("test validator", function () { "data.regulation should have required property 'max_retries'", "data.session should have required property 'secret'", "Storage must be either 'local' or 'mongo'", - "Notifier must be either 'filesystem', 'gmail' or 'smtp'" + "Notifier must be either 'filesystem', 'email' or 'smtp'" ]); Assert.deepStrictEqual(Validator.isValid({ @@ -67,10 +67,11 @@ describe("test validator", function () { user: "user" }, notifier: { - gmail: { + email: { username: "user@gmail.com", password: "pass", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" } }, regulation: { diff --git a/server/test/mocks/notifiers/MailSenderBuilderStub.ts b/server/test/mocks/notifiers/MailSenderBuilderStub.ts index ac701c7d8..fa38b0684 100644 --- a/server/test/mocks/notifiers/MailSenderBuilderStub.ts +++ b/server/test/mocks/notifiers/MailSenderBuilderStub.ts @@ -3,19 +3,19 @@ import BluebirdPromise = require("bluebird"); import Nodemailer = require("nodemailer"); import Sinon = require("sinon"); import { IMailSender } from "../../../src/lib/notifiers/IMailSender"; -import { SmtpNotifierConfiguration, GmailNotifierConfiguration } from "../../../src/lib/configuration/Configuration"; +import { SmtpNotifierConfiguration, EmailNotifierConfiguration } from "../../../src/lib/configuration/Configuration"; export class MailSenderBuilderStub implements IMailSenderBuilder { - buildGmailStub: Sinon.SinonStub; + buildEmailStub: Sinon.SinonStub; buildSmtpStub: Sinon.SinonStub; constructor() { - this.buildGmailStub = Sinon.stub(); + this.buildEmailStub = Sinon.stub(); this.buildSmtpStub = Sinon.stub(); } - buildGmail(options: GmailNotifierConfiguration): IMailSender { - return this.buildGmailStub(options); + buildEmail(options: EmailNotifierConfiguration): IMailSender { + return this.buildEmailStub(options); } buildSmtp(options: SmtpNotifierConfiguration): IMailSender { diff --git a/server/test/notifiers/GMailNotifier.test.ts b/server/test/notifiers/EMailNotifier.test.ts similarity index 80% rename from server/test/notifiers/GMailNotifier.test.ts rename to server/test/notifiers/EMailNotifier.test.ts index 8d598d5da..ca796fca9 100644 --- a/server/test/notifiers/GMailNotifier.test.ts +++ b/server/test/notifiers/EMailNotifier.test.ts @@ -3,20 +3,21 @@ import * as Assert from "assert"; import BluebirdPromise = require("bluebird"); import { MailSenderStub } from "../mocks/notifiers/MailSenderStub"; -import GMailNotifier = require("../../src/lib/notifiers/GMailNotifier"); +import EMailNotifier = require("../../src/lib/notifiers/EMailNotifier"); -describe("test gmail notifier", function () { +describe("test email notifier", function () { it("should send an email to given user", function () { const mailSender = new MailSenderStub(); const options = { username: "user_gmail", password: "pass_gmail", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" }; mailSender.sendStub.returns(BluebirdPromise.resolve()); - const sender = new GMailNotifier.GMailNotifier(options, mailSender); + const sender = new EMailNotifier.EMailNotifier(options, mailSender); const subject = "subject"; const url = "http://test.com"; @@ -33,11 +34,12 @@ describe("test gmail notifier", function () { const options = { username: "user_gmail", password: "pass_gmail", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" }; mailSender.sendStub.returns(BluebirdPromise.reject(new Error("Failed to send mail"))); - const sender = new GMailNotifier.GMailNotifier(options, mailSender); + const sender = new EMailNotifier.EMailNotifier(options, mailSender); const subject = "subject"; const url = "http://test.com"; diff --git a/server/test/notifiers/MailSenderBuilder.test.ts b/server/test/notifiers/MailSenderBuilder.test.ts index 6bdc0f5fc..e328ac563 100644 --- a/server/test/notifiers/MailSenderBuilder.test.ts +++ b/server/test/notifiers/MailSenderBuilder.test.ts @@ -14,15 +14,17 @@ describe("test MailSenderBuilder", function() { createTransportStub.restore(); }); - it("should create a gmail mail sender", function() { + it("should create a email mail sender", function() { const mailSenderBuilder = new MailSenderBuilder(Nodemailer); - mailSenderBuilder.buildGmail({ + mailSenderBuilder.buildEmail({ username: "user_gmail", password: "pass_gmail", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" }); Assert.equal(createTransportStub.getCall(0).args[0].auth.user, "user_gmail"); Assert.equal(createTransportStub.getCall(0).args[0].auth.pass, "pass_gmail"); + Assert.equal(createTransportStub.getCall(0).args[0].service, "gmail"); }); describe("build smtp mail sender", function() { diff --git a/server/test/notifiers/NotifierFactory.test.ts b/server/test/notifiers/NotifierFactory.test.ts index 6dd25d4ac..7ae7d0c38 100644 --- a/server/test/notifiers/NotifierFactory.test.ts +++ b/server/test/notifiers/NotifierFactory.test.ts @@ -4,23 +4,24 @@ import * as BluebirdPromise from "bluebird"; import * as assert from "assert"; import { NotifierFactory } from "../../src/lib/notifiers/NotifierFactory"; -import { GMailNotifier } from "../../src/lib/notifiers/GMailNotifier"; +import { EMailNotifier } from "../../src/lib/notifiers/EMailNotifier"; import { SmtpNotifier } from "../../src/lib/notifiers/SmtpNotifier"; import { MailSenderBuilderStub } from "../mocks/notifiers/MailSenderBuilderStub"; describe("test notifier factory", function () { let mailSenderBuilderStub: MailSenderBuilderStub; - it("should build a Gmail Notifier", function () { + it("should build a Email Notifier", function () { const options = { - gmail: { + email: { username: "abc", password: "password", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" } }; mailSenderBuilderStub = new MailSenderBuilderStub(); - assert(NotifierFactory.build(options, mailSenderBuilderStub) instanceof GMailNotifier); + assert(NotifierFactory.build(options, mailSenderBuilderStub) instanceof EMailNotifier); }); it("should build a SMTP Notifier", function () { diff --git a/server/test/server/PrivatePages.ts b/server/test/server/PrivatePages.ts index 8fd9f698a..a44211605 100644 --- a/server/test/server/PrivatePages.ts +++ b/server/test/server/PrivatePages.ts @@ -52,10 +52,11 @@ describe("Private pages of the server must not be accessible without session", f } }, notifier: { - gmail: { + email: { username: "user@example.com", password: "password", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" } } }; diff --git a/server/test/server/PublicPages.ts b/server/test/server/PublicPages.ts index 21f099176..12e4cc32f 100644 --- a/server/test/server/PublicPages.ts +++ b/server/test/server/PublicPages.ts @@ -52,10 +52,11 @@ describe("Public pages of the server must be accessible without session", functi find_time: 5 * 60 }, notifier: { - gmail: { + email: { username: "user@example.com", password: "password", - sender: "admin@example.com" + sender: "admin@example.com", + service: "gmail" } } };