diff --git a/lib/users/unlock-account-email.js b/lib/users/unlock-account-email.js new file mode 100644 index 00000000..81defc23 --- /dev/null +++ b/lib/users/unlock-account-email.js @@ -0,0 +1,29 @@ +const moment = require('moment'); + +const protocol = process.env.PROTOCOL || 'http'; +const zenHostname = process.env.HOSTNAME || '127.0.0.1:8000'; + +function unlockAccountEmail(args, done) { + const seneca = this; + const email = args.email; + + seneca.act({ role: 'cd-users', cmd: 'get_users_by_email', email }, (err, users) => { + if (err) return done(err); + seneca.act({ role: 'email-notifications', cmd: 'send' }, { + code: 'user-lockout-', + locality: args.locality || 'en_US', + to: email, + subject: 'CoderDojo Zen Account Lockout', + content: { + name: users[0].name, + resetlink: `${protocol}://${zenHostname}/reset_password`, + year: moment(new Date()).format('YYYY'), + }, + }, (err, response) => { + if (err) return done(err); + return done(null, { ok: true }); + }); + }); +} + +module.exports = unlockAccountEmail; diff --git a/package.json b/package.json index 4a929947..fa471974 100644 --- a/package.json +++ b/package.json @@ -50,13 +50,13 @@ "po2json": "0.4.2", "postgrator": "2.8.1", "request": "2.58.0", - "seneca": "1.4", - "seneca-auth": "1.0", + "seneca": "1.4.0", + "seneca-auth": "1.0.0", "seneca-mail": "^0.2.2", "seneca-newrelic": "Wardormeur/seneca-newrelic", "seneca-postgresql-store": "2.3", "seneca-store-query": "0.0.5", - "seneca-user": "1.0", + "seneca-user": "2.1.1", "shortid": "2.2.2", "util": "^0.10.3", "xoauth2": "1.1.0" diff --git a/scripts/database/pg/migrations/025.do.add-user-lock.sql b/scripts/database/pg/migrations/025.do.add-user-lock.sql new file mode 100644 index 00000000..8d1d02e0 --- /dev/null +++ b/scripts/database/pg/migrations/025.do.add-user-lock.sql @@ -0,0 +1,9 @@ +DO $$ + BEGIN + BEGIN + ALTER TABLE sys_user ADD COLUMN failed_login_count integer; + EXCEPTION + WHEN duplicate_column THEN RAISE NOTICE 'column failed_login_count already exists in sys_user.'; + END; + END; +$$ diff --git a/service.js b/service.js index a8fa83b4..26e082f2 100644 --- a/service.js +++ b/service.js @@ -58,7 +58,7 @@ require('./migrate-psql-db.js')(function (err) { logger: log.logger }); seneca.use(require('./oauth2.js'), {clients: config.oauth2.clients}); - seneca.use('user'); + seneca.use('user', { failedLoginCount: 3 }); seneca.use('auth'); seneca.use(require('./users.js'), { 'email-notifications': config['email-notifications'], diff --git a/users.js b/users.js index 8f8328d9..4447214d 100644 --- a/users.js +++ b/users.js @@ -43,6 +43,7 @@ module.exports = function (options) { seneca.add({role: plugin, cmd: 'is_self'}, require('./lib/users/is-self')); seneca.add({role: plugin, cmd: 'is_parent_of'}, require('./lib/users/is-parent-of')); seneca.add({role: plugin, cmd: 'can_accept_join_request'}, require('./lib/users/can-accept-join-request')); + seneca.add({role: plugin, cmd: 'unlock_account_email'}, require('./lib/users/unlock-account-email')); seneca.add({role: plugin, ctrl: 'user', cmd: 'load'}, require('./lib/controllers/users/load')); // LMS Integration seneca.add({role: plugin, cmd: 'get_lms_link'}, require('./lib/users/lms/get-lms-link'));