diff --git a/README.md b/README.md index b0cf78752..e23c53912 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Note that this example creates the `fullchain.pem` and `privkey.pem` files in a directory one level higher from the current, so that you don't accidentally commit your certificates to `solid` while you're developing. -If you would like to get rid of the browser warnings, import your fullchain.pem certificate into your 'Trusted Root Certificate' store. +If you would like to get rid of the browser warnings, import your fullchain.pem certificate into your 'Trusted Root Certificate' store. ### Run multi-user server (intermediate) @@ -375,6 +375,12 @@ In order to test a single component, you can run npm run test-(acl|formats|params|patch) ``` +## Blacklisted usernames + +By default Solid will not allow [certain usernames as they might cause +confusion or allow vulnerabilies for social engineering](https://github.com/marteinn/The-Big-Username-Blacklist). +This list is configurable via `config/usernames-blacklist.json`. Solid does not +blacklist profanities by default. ## Contributing diff --git a/bin/lib/options.js b/bin/lib/options.js index 4efbf07d2..245225cba 100644 --- a/bin/lib/options.js +++ b/bin/lib/options.js @@ -334,6 +334,21 @@ module.exports = [ name: 'server-logo', help: 'A logo that represents you, your brand, or your server (not required)', prompt: true + }, + { + name: 'enforceToc', + help: 'Do you want to enforce Terms & Conditions for your service?', + flag: true, + prompt: true, + default: true, + when: answers => answers.multiuser + }, + { + name: 'tocUri', + help: 'URI to your Terms & Conditions', + prompt: true, + validate: validUri, + when: answers => answers.enforceToc } ] diff --git a/config.json-default b/config.json-default index 8c6d3ddda..db1176248 100644 --- a/config.json-default +++ b/config.json-default @@ -14,5 +14,7 @@ "name": "", "description": "", "logo": "" - } + }, + "enforceToc": true, + "tocUri": "https://your-toc" } diff --git a/config/usernames-blacklist.json b/config/usernames-blacklist.json new file mode 100644 index 000000000..c1b469a1e --- /dev/null +++ b/config/usernames-blacklist.json @@ -0,0 +1,4 @@ +{ + "useTheBigUsernameBlacklist": true, + "customBlacklistedUsernames": [] +} diff --git a/default-views/account/register-form.hbs b/default-views/account/register-form.hbs index 12166f888..2bc5a2086 100644 --- a/default-views/account/register-form.hbs +++ b/default-views/account/register-form.hbs @@ -71,6 +71,17 @@ + {{#if enforceToc}} + {{#if tocUri}} +
+ +
+ {{/if}} + {{/if}} + diff --git a/lib/create-app.js b/lib/create-app.js index 2a0b15da7..db448d20b 100644 --- a/lib/create-app.js +++ b/lib/create-app.js @@ -12,8 +12,8 @@ const authProxy = require('./handlers/auth-proxy') const SolidHost = require('./models/solid-host') const AccountManager = require('./models/account-manager') const vhost = require('vhost') -const EmailService = require('./models/email-service') -const TokenService = require('./models/token-service') +const EmailService = require('./services/email-service') +const TokenService = require('./services/token-service') const capabilityDiscovery = require('./capability-discovery') const API = require('./api') const errorPages = require('./handlers/error-pages') @@ -123,6 +123,8 @@ function initAppLocals (app, argv, ldp) { app.locals.authMethod = argv.auth app.locals.localAuth = argv.localAuth app.locals.tokenService = new TokenService() + app.locals.enforceToc = argv.enforceToc + app.locals.tocUri = argv.tocUri if (argv.email && argv.email.host) { app.locals.emailService = new EmailService(argv.templates.email, argv.email) diff --git a/lib/requests/auth-request.js b/lib/requests/auth-request.js index cb8a532de..deb9d9bc0 100644 --- a/lib/requests/auth-request.js +++ b/lib/requests/auth-request.js @@ -25,6 +25,8 @@ class AuthRequest { * @param [options.returnToUrl] {string} * @param [options.authQueryParams] {Object} Key/value hashmap of parsed query * parameters that will be passed through to the /authorize endpoint. + * @param [options.enforceToc] {boolean} Whether or not to enforce the service provider's T&C + * @param [options.tocUri] {string} URI to the service provider's T&C */ constructor (options) { this.response = options.response @@ -34,6 +36,8 @@ class AuthRequest { this.returnToUrl = options.returnToUrl this.authQueryParams = options.authQueryParams || {} this.localAuth = options.localAuth + this.enforceToc = options.enforceToc + this.tocUri = options.tocUri } /** @@ -84,6 +88,7 @@ class AuthRequest { let authQueryParams = AuthRequest.extractAuthParams(req) let returnToUrl = AuthRequest.parseParameter(req, 'returnToUrl') + const acceptToc = AuthRequest.parseParameter(req, 'acceptToc') === 'true' let options = { response: res, @@ -92,7 +97,8 @@ class AuthRequest { accountManager, returnToUrl, authQueryParams, - localAuth + localAuth, + acceptToc } return options diff --git a/lib/requests/create-account-request.js b/lib/requests/create-account-request.js index 68997822c..d8f493b88 100644 --- a/lib/requests/create-account-request.js +++ b/lib/requests/create-account-request.js @@ -3,6 +3,7 @@ const AuthRequest = require('./auth-request') const WebIdTlsCertificate = require('../models/webid-tls-certificate') const debug = require('../debug').accounts +const blacklistService = require('../services/blacklist-service') /** * Represents a 'create new user account' http request (either a POST to the @@ -26,12 +27,16 @@ class CreateAccountRequest extends AuthRequest { * @param [options.response] {HttpResponse} * @param [options.returnToUrl] {string} If present, redirect the agent to * this url on successful account creation + * @param [options.enforceToc] {boolean} Whether or not to enforce the service provider's T&C + * @param [options.tocUri] {string} URI to the service provider's T&C + * @param [options.acceptToc] {boolean} Whether or not user has accepted T&C */ constructor (options) { super(options) this.username = options.username this.userAccount = options.userAccount + this.acceptToc = options.acceptToc } /** @@ -45,7 +50,7 @@ class CreateAccountRequest extends AuthRequest { * `userAccountFrom()`), or it encounters an unsupported authentication * scheme. * - * @return {CreateAccountRequest|CreateTlsAccountRequest} + * @return {CreateOidcAccountRequest|CreateTlsAccountRequest} */ static fromParams (req, res) { let options = AuthRequest.requestOptions(req, res) @@ -61,6 +66,9 @@ class CreateAccountRequest extends AuthRequest { options.userAccount = accountManager.userAccountFrom(body) } + options.enforceToc = locals.enforceToc + options.tocUri = locals.tocUri + switch (authMethod) { case 'oidc': options.password = body.password @@ -73,13 +81,15 @@ class CreateAccountRequest extends AuthRequest { } } - static post (req, res) { + static async post (req, res) { let request = CreateAccountRequest.fromParams(req, res) - return Promise.resolve() - .then(() => request.validate()) - .then(() => request.createAccount()) - .catch(error => request.error(error)) + try { + request.validate() + await request.createAccount() + } catch (error) { + request.error(error) + } } static get (req, res) { @@ -96,13 +106,14 @@ class CreateAccountRequest extends AuthRequest { renderForm (error) { let authMethod = this.accountManager.authMethod - let params = Object.assign({}, this.authQueryParams, - { - returnToUrl: this.returnToUrl, - loginUrl: this.loginUrl(), - registerDisabled: authMethod === 'tls', - multiuser: this.accountManager.multiuser - }) + let params = Object.assign({}, this.authQueryParams, { + enforceToc: this.enforceToc, + loginUrl: this.loginUrl(), + multiuser: this.accountManager.multiuser, + registerDisabled: authMethod === 'tls', + returnToUrl: this.returnToUrl, + tocUri: this.tocUri + }) if (error) { params.error = error.message @@ -115,30 +126,28 @@ class CreateAccountRequest extends AuthRequest { /** * Creates an account for a given user (from a POST to `/api/accounts/new`) * - * @throws {Error} An http 400 error if an account already exists + * @throws {Error} If errors were encountering while validating the username. * * @return {Promise} Resolves with newly created account instance */ - createAccount () { + async createAccount () { let userAccount = this.userAccount let accountManager = this.accountManager - return Promise.resolve(userAccount) - .then(this.cancelIfUsernameInvalid.bind(this)) - .then(this.cancelIfAccountExists.bind(this)) - .then(this.createAccountStorage.bind(this)) - .then(this.saveCredentialsFor.bind(this)) - .then(this.sendResponse.bind(this)) - .then(userAccount => { - // 'return' not used deliberately, no need to block and wait for email - if (userAccount && userAccount.email) { - debug('Sending Welcome email') - accountManager.sendWelcomeEmail(userAccount) - } - }) - .then(() => { - return userAccount - }) + this.cancelIfUsernameInvalid(userAccount) + this.cancelIfBlacklistedUsername(userAccount) + await this.cancelIfAccountExists(userAccount) + await this.createAccountStorage(userAccount) + await this.saveCredentialsFor(userAccount) + await this.sendResponse(userAccount) + + // 'return' not used deliberately, no need to block and wait for email + if (userAccount && userAccount.email) { + debug('Sending Welcome email') + accountManager.sendWelcomeEmail(userAccount) + } + + return userAccount } /** @@ -196,12 +205,33 @@ class CreateAccountRequest extends AuthRequest { * @throws {Error} If errors were encountering while validating the * username. * - * @return {Promise} Chainable + * @return {UserAccount} Chainable */ cancelIfUsernameInvalid (userAccount) { if (!userAccount.username || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(userAccount.username)) { debug('Invalid username ' + userAccount.username) - const error = new Error('Invalid username') + const error = new Error('Invalid username (contains invalid characters)') + error.status = 400 + throw error + } + + return userAccount + } + + /** + * Check if a username is a valid slug. + * + * @param userAccount {UserAccount} Instance of the account to be created + * + * @throws {Error} If username is blacklisted + * + * @return {UserAccount} Chainable + */ + cancelIfBlacklistedUsername (userAccount) { + const validUsername = blacklistService.validate(userAccount.username) + if (!validUsername) { + debug('Invalid username ' + userAccount.username) + const error = new Error('Invalid username (username is blacklisted)') error.status = 400 throw error } @@ -224,6 +254,7 @@ class CreateOidcAccountRequest extends CreateAccountRequest { * * @param [options={}] {Object} See `CreateAccountRequest` constructor docstring * @param [options.password] {string} Password, as entered by the user at signup + * @param [options.acceptToc] {boolean} Whether or not user has accepted T&C */ constructor (options) { super(options) @@ -251,6 +282,12 @@ class CreateOidcAccountRequest extends CreateAccountRequest { error.statusCode = 400 throw error } + + if (this.enforceToc && !this.acceptToc) { + error = new Error('Accepting Terms & Conditions is required for this service') + error.statusCode = 400 + throw error + } } /** @@ -290,6 +327,7 @@ class CreateTlsAccountRequest extends CreateAccountRequest { * * @param [options={}] {Object} See `CreateAccountRequest` constructor docstring * @param [options.spkac] {string} + * @param [options.acceptToc] {boolean} Whether or not user has accepted T&C */ constructor (options) { super(options) @@ -299,7 +337,7 @@ class CreateTlsAccountRequest extends CreateAccountRequest { } /** - * Validates the Login request (makes sure required parameters are present), + * Validates the Signup request (makes sure required parameters are present), * and throws an error if not. * * @throws {Error} If missing required params @@ -312,6 +350,12 @@ class CreateTlsAccountRequest extends CreateAccountRequest { error.statusCode = 400 throw error } + + if (this.enforceToc && !this.acceptToc) { + error = new Error('Accepting Terms & Conditions is required for this service') + error.statusCode = 400 + throw error + } } /** diff --git a/lib/services/blacklist-service.js b/lib/services/blacklist-service.js new file mode 100644 index 000000000..caef80ba7 --- /dev/null +++ b/lib/services/blacklist-service.js @@ -0,0 +1,33 @@ +const blacklistConfig = require('../../config/usernames-blacklist.json') +const blacklist = require('the-big-username-blacklist').list + +class BlacklistService { + constructor () { + this.reset() + } + + addWord (word) { + this.list.push(BlacklistService._prepareWord(word)) + } + + reset (config) { + this.list = BlacklistService._initList(config) + } + + validate (word) { + return this.list.indexOf(BlacklistService._prepareWord(word)) === -1 + } + + static _initList (config = blacklistConfig) { + return [ + ...(config.useTheBigUsernameBlacklist ? blacklist : []), + ...config.customBlacklistedUsernames + ] + } + + static _prepareWord (word) { + return word.trim().toLocaleLowerCase() + } +} + +module.exports = new BlacklistService() diff --git a/lib/models/email-service.js b/lib/services/email-service.js similarity index 99% rename from lib/models/email-service.js rename to lib/services/email-service.js index 69166793a..d0fe448f7 100644 --- a/lib/models/email-service.js +++ b/lib/services/email-service.js @@ -2,7 +2,7 @@ const nodemailer = require('nodemailer') const path = require('path') -const debug = require('./../debug').email +const debug = require('../debug').email /** * Models a Nodemailer-based email sending service. diff --git a/lib/models/token-service.js b/lib/services/token-service.js similarity index 100% rename from lib/models/token-service.js rename to lib/services/token-service.js diff --git a/package-lock.json b/package-lock.json index 5bd3d23cb..e1def6b06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8366,6 +8366,11 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "the-big-username-blacklist": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/the-big-username-blacklist/-/the-big-username-blacklist-1.5.1.tgz", + "integrity": "sha1-uqanyWHRpJo1OdFUJMNMjTPHdtU=" + }, "then-fs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/then-fs/-/then-fs-2.0.0.tgz", diff --git a/package.json b/package.json index 626ae6f8f..5f7bc16c3 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "solid-permissions": "^0.6.0", "solid-ws": "^0.2.3", "text-encoder-lite": "^1.0.1", + "the-big-username-blacklist": "^1.5.1", "ulid": "^0.1.0", "uuid": "^3.0.0", "valid-url": "^1.0.9", diff --git a/test/integration/account-creation-oidc-test.js b/test/integration/account-creation-oidc-test.js index ed0d08846..fa757d2c2 100644 --- a/test/integration/account-creation-oidc-test.js +++ b/test/integration/account-creation-oidc-test.js @@ -8,15 +8,17 @@ const path = require('path') const fs = require('fs-extra') describe('AccountManager (OIDC account creation tests)', function () { - var serverUri = 'https://localhost:3457' - var host = 'localhost:3457' - var ldpHttpsServer - let rootPath = path.join(__dirname, '../resources/accounts/') - let configPath = path.join(__dirname, '../resources/config') - let dbPath = path.join(__dirname, '../resources/accounts/db') + const port = 3457 + const serverUri = `https://localhost:${port}` + const host = `localhost:${port}` + const root = path.join(__dirname, '../resources/accounts/') + const configPath = path.join(__dirname, '../resources/config') + const dbPath = path.join(__dirname, '../resources/accounts/db') + + let ldpHttpsServer var ldp = ldnode.createServer({ - root: rootPath, + root, configPath, sslKey: path.join(__dirname, '../keys/key.pem'), sslCert: path.join(__dirname, '../keys/cert.pem'), @@ -25,19 +27,20 @@ describe('AccountManager (OIDC account creation tests)', function () { multiuser: true, strictOrigin: true, dbPath, - serverUri + serverUri, + enforceToc: true }) before(checkDnsSettings) before(function (done) { - ldpHttpsServer = ldp.listen(3457, done) + ldpHttpsServer = ldp.listen(port, done) }) after(function () { if (ldpHttpsServer) ldpHttpsServer.close() fs.removeSync(path.join(dbPath, 'oidc/users/users')) - cleanDir(path.join(rootPath, 'localhost')) + cleanDir(path.join(root, 'localhost')) }) var server = supertest(serverUri) @@ -93,14 +96,14 @@ describe('AccountManager (OIDC account creation tests)', function () { it('should not create a WebID if it already exists', function (done) { var subdomain = supertest('https://nicola.' + host) subdomain.post('/api/accounts/new') - .send('username=nicola&password=12345') + .send('username=nicola&password=12345&acceptToc=true') .expect(302) .end((err, res) => { if (err) { return done(err) } subdomain.post('/api/accounts/new') - .send('username=nicola&password=12345') + .send('username=nicola&password=12345&acceptToc=true') .expect(400) .end((err) => { done(err) @@ -108,10 +111,17 @@ describe('AccountManager (OIDC account creation tests)', function () { }) }) + it('should not create WebID if T&C is not accepted', (done) => { + let subdomain = supertest('https://nicola.' + host) + subdomain.post('/api/accounts/new') + .send('username=nicola&password=12345&acceptToc=false') + .expect(400, done) + }) + it('should create the default folders', function (done) { var subdomain = supertest('https://nicola.' + host) subdomain.post('/api/accounts/new') - .send('username=nicola&password=12345') + .send('username=nicola&password=12345&acceptToc=true') .expect(302) .end(function (err) { if (err) { @@ -119,19 +129,19 @@ describe('AccountManager (OIDC account creation tests)', function () { } var domain = host.split(':')[0] var card = read(path.join('accounts/nicola.' + domain, - 'profile/card')) + 'profile/card')) var cardAcl = read(path.join('accounts/nicola.' + domain, - 'profile/card.acl')) + 'profile/card.acl')) var prefs = read(path.join('accounts/nicola.' + domain, - 'settings/prefs.ttl')) + 'settings/prefs.ttl')) var inboxAcl = read(path.join('accounts/nicola.' + domain, - 'inbox/.acl')) + 'inbox/.acl')) var rootMeta = read(path.join('accounts/nicola.' + domain, '.meta')) var rootMetaAcl = read(path.join('accounts/nicola.' + domain, - '.meta.acl')) + '.meta.acl')) if (domain && card && cardAcl && prefs && inboxAcl && rootMeta && - rootMetaAcl) { + rootMetaAcl) { done() } else { done(new Error('failed to create default files')) @@ -142,7 +152,7 @@ describe('AccountManager (OIDC account creation tests)', function () { it('should link WebID to the root account', function (done) { var subdomain = supertest('https://nicola.' + host) subdomain.post('/api/accounts/new') - .send('username=nicola&password=12345') + .send('username=nicola&password=12345&acceptToc=true') .expect(302) .end(function (err) { if (err) { @@ -236,3 +246,46 @@ describe('Single User signup page', () => { .end(done) }) }) + +describe('Signup page where Terms & Conditions are not being enforced', () => { + const port = 3457 + const host = `localhost:${port}` + const root = path.join(__dirname, '../resources/accounts/') + const configPath = path.join(__dirname, '../resources/config') + const dbPath = path.join(__dirname, '../resources/accounts/db') + const ldp = ldnode.createServer({ + port, + root, + configPath, + sslKey: path.join(__dirname, '../keys/key.pem'), + sslCert: path.join(__dirname, '../keys/cert.pem'), + auth: 'oidc', + webid: true, + multiuser: true, + strictOrigin: true, + enforceToc: false + }) + let ldpHttpsServer + + before(function (done) { + ldpHttpsServer = ldp.listen(port, done) + }) + + after(function () { + if (ldpHttpsServer) ldpHttpsServer.close() + fs.removeSync(path.join(dbPath, 'oidc/users/users')) + cleanDir(path.join(root, 'localhost')) + rm('accounts/nicola.localhost') + }) + + beforeEach(function () { + rm('accounts/nicola.localhost') + }) + + it('should not enforce T&C upon creating account', function (done) { + var subdomain = supertest('https://nicola.' + host) + subdomain.post('/api/accounts/new') + .send('username=nicola&password=12345') + .expect(302, done) + }) +}) diff --git a/test/unit/account-manager-test.js b/test/unit/account-manager-test.js index 90cb8d639..6d69bd391 100644 --- a/test/unit/account-manager-test.js +++ b/test/unit/account-manager-test.js @@ -15,7 +15,7 @@ const LDP = require('../../lib/ldp') const SolidHost = require('../../lib/models/solid-host') const AccountManager = require('../../lib/models/account-manager') const UserAccount = require('../../lib/models/user-account') -const TokenService = require('../../lib/models/token-service') +const TokenService = require('../../lib/services/token-service') const WebIdTlsCertificate = require('../../lib/models/webid-tls-certificate') const testAccountsDir = path.join(__dirname, '../resources/accounts') diff --git a/test/unit/blacklist-service-test.js b/test/unit/blacklist-service-test.js new file mode 100644 index 000000000..a2db974ca --- /dev/null +++ b/test/unit/blacklist-service-test.js @@ -0,0 +1,49 @@ +'use strict' + +const chai = require('chai') +const expect = chai.expect + +const blacklist = require('the-big-username-blacklist').list +const blacklistService = require('../../lib/services/blacklist-service') + +describe('BlacklistService', () => { + afterEach(() => blacklistService.reset()) + + describe('addWord', () => { + it('allows adding words', () => { + const numberOfBlacklistedWords = blacklistService.list.length + blacklistService.addWord('foo') + expect(blacklistService.list.length).to.equal(numberOfBlacklistedWords + 1) + }) + }) + + describe('reset', () => { + it('will reset list of blacklisted words', () => { + blacklistService.addWord('foo') + blacklistService.reset() + expect(blacklistService.list.length).to.equal(blacklist.length) + }) + + it('can configure service via reset', () => { + blacklistService.reset({ + useTheBigUsernameBlacklist: false, + customBlacklistedUsernames: ['foo'] + }) + expect(blacklistService.list.length).to.equal(1) + expect(blacklistService.validate('admin')).to.equal(true) + }) + + it('is a singleton', () => { + const instanceA = blacklistService + blacklistService.reset({ customBlacklistedUsernames: ['foo'] }) + expect(instanceA.validate('foo')).to.equal(blacklistService.validate('foo')) + }) + }) + + describe('validate', () => { + it('validates given a default list of blacklisted usernames', () => { + const validWords = blacklist.reduce((memo, word) => memo + (blacklistService.validate(word) ? 1 : 0), 0) + expect(validWords).to.equal(0) + }) + }) +}) diff --git a/test/unit/create-account-request-test.js b/test/unit/create-account-request-test.js index 469fe7822..892219b37 100644 --- a/test/unit/create-account-request-test.js +++ b/test/unit/create-account-request-test.js @@ -7,12 +7,14 @@ const sinonChai = require('sinon-chai') chai.use(sinonChai) chai.should() const HttpMocks = require('node-mocks-http') +const blacklist = require('the-big-username-blacklist') const LDP = require('../../lib/ldp') const AccountManager = require('../../lib/models/account-manager') const SolidHost = require('../../lib/models/solid-host') const defaults = require('../../config/defaults') const { CreateAccountRequest } = require('../../lib/requests/create-account-request') +const blacklistService = require('../../lib/services/blacklist-service') describe('CreateAccountRequest', () => { let host, store, accountManager @@ -127,6 +129,45 @@ describe('CreateAccountRequest', () => { expect(invalidUsernamesCount).to.eq(invalidUsernames.length) }) }) + + describe('Blacklisted usernames', () => { + const invalidUsernames = [...blacklist.list, 'foo'] + + before(() => { + const accountManager = AccountManager.from({ host }) + accountManager.accountExists = sinon.stub().returns(Promise.resolve(false)) + blacklistService.addWord('foo') + }) + + after(() => blacklistService.reset()) + + it('should return a 400 error if a username is blacklisted', async () => { + const locals = { authMethod: defaults.auth, accountManager, oidc: { users: {} } } + + let invalidUsernamesCount = 0 + + const requests = invalidUsernames.map((username) => { + let req = HttpMocks.createRequest({ + app: { locals }, + body: { username, password: '1234' } + }) + let request = CreateAccountRequest.fromParams(req, res) + + return request.createAccount() + .then(() => { + throw new Error('should not happen') + }) + .catch(err => { + invalidUsernamesCount++ + expect(err.message).to.match(/Invalid username/) + expect(err.status).to.equal(400) + }) + }) + + await Promise.all(requests) + expect(invalidUsernamesCount).to.eq(invalidUsernames.length) + }) + }) }) }) diff --git a/test/unit/email-service-test.js b/test/unit/email-service-test.js index 97de0ca80..27f08da26 100644 --- a/test/unit/email-service-test.js +++ b/test/unit/email-service-test.js @@ -1,4 +1,4 @@ -const EmailService = require('../../lib/models/email-service') +const EmailService = require('../../lib/services/email-service') const path = require('path') const sinon = require('sinon') const chai = require('chai') diff --git a/test/unit/email-welcome-test.js b/test/unit/email-welcome-test.js index 86e3935b2..7317a48c3 100644 --- a/test/unit/email-welcome-test.js +++ b/test/unit/email-welcome-test.js @@ -10,7 +10,7 @@ chai.should() const SolidHost = require('../../lib/models/solid-host') const AccountManager = require('../../lib/models/account-manager') -const EmailService = require('../../lib/models/email-service') +const EmailService = require('../../lib/services/email-service') const templatePath = path.join(__dirname, '../../default-templates/emails') diff --git a/test/unit/token-service-test.js b/test/unit/token-service-test.js index ea84fe9a7..2751a2abb 100644 --- a/test/unit/token-service-test.js +++ b/test/unit/token-service-test.js @@ -6,7 +6,7 @@ const dirtyChai = require('dirty-chai') chai.use(dirtyChai) chai.should() -const TokenService = require('../../lib/models/token-service') +const TokenService = require('../../lib/services/token-service') describe('TokenService', () => { describe('constructor()', () => {