UNPKG

ghost

Version:

The professional publishing platform

220 lines (203 loc) 7.01 kB
const api = require('./index'); const config = require('../../../shared/config'); const tpl = require('@tryghost/tpl'); const errors = require('@tryghost/errors'); const logging = require('@tryghost/logging'); const web = require('../../web'); const models = require('../../models'); const auth = require('../../services/auth'); const invitations = require('../../services/invitations'); const dbBackup = require('../../data/db/backup'); const apiMail = require('./index').mail; const apiSettings = require('./index').settings; const UsersService = require('../../services/Users'); const userService = new UsersService({dbBackup, models, auth, apiMail, apiSettings}); const {deleteAllSessions} = require('../../services/auth/session'); const messages = { notTheBlogOwner: 'You are not the site owner.' }; /** @type {import('@tryghost/api-framework').Controller} */ const controller = { docName: 'authentication', setup: { statusCode: 201, permissions: false, headers: { cacheInvalidate: true }, validation: { docName: 'setup' }, query(frame) { return Promise.resolve() .then(() => { return auth.setup.assertSetupCompleted(false)(); }) .then(() => { const setupDetails = { name: frame.data.setup[0].name, email: frame.data.setup[0].email, password: frame.data.setup[0].password, blogTitle: frame.data.setup[0].blogTitle, theme: frame.data.setup[0].theme, accentColor: frame.data.setup[0].accentColor, description: frame.data.setup[0].description, status: 'active' }; return auth.setup.setupUser(setupDetails); }) .then((data) => { try { return auth.setup.doFixtures(data); } catch (e) { return data; } }) .then((data) => { try { return auth.setup.doProductAndNewsletter(data, api); } catch (e) { return data; } }) .then((data) => { return auth.setup.installTheme(data, api); }) .then((data) => { return auth.setup.doSettings(data, api.settings); }) .then((user) => { auth.setup.sendWelcomeEmail(user.get('email'), api.mail) .catch((err) => { logging.error(err); }); return user; }); } }, updateSetup: { headers: { cacheInvalidate: true }, permissions: async (frame) => { const owner = await models.User.findOne({role: 'Owner', status: 'all'}); if (owner.id !== frame.options.context.user) { throw new errors.NoPermissionError({message: tpl(messages.notTheBlogOwner)}); } }, validation: { docName: 'setup' }, async query(frame) { await auth.setup.assertSetupCompleted(true)(); const setupDetails = { name: frame.data.setup[0].name, email: frame.data.setup[0].email, password: frame.data.setup[0].password, blogTitle: frame.data.setup[0].blogTitle, status: 'active' }; const data = await auth.setup.setupUser(setupDetails); return auth.setup.doSettings(data, api.settings); } }, isSetup: { headers: { cacheInvalidate: false }, permissions: false, async query() { const isSetup = await auth.setup.checkIsSetup(); return { status: isSetup, title: config.title, name: config.user_name, email: config.user_email }; } }, generateResetToken: { headers: { cacheInvalidate: false }, validation: { docName: 'password_reset' }, permissions: true, options: [ 'email' ], async query(frame) { await auth.setup.assertSetupCompleted(true)(); const token = await auth.passwordreset.generateToken(frame.data.password_reset[0].email, api.settings); return auth.passwordreset.sendResetNotification(token, api.mail); } }, resetPassword: { headers: { cacheInvalidate: false }, validation: { docName: 'password_reset', data: { newPassword: {required: true}, ne2Password: {required: true} } }, permissions: false, options: [ 'ip' ], async query(frame) { await auth.setup.assertSetupCompleted(true)(); const params = await auth.passwordreset.extractTokenParts(frame); const {options, tokenParts} = await auth.passwordreset.protectBruteForce(params); const internalOptions = Object.assign(options, {context: {internal: true}}); const doResetParams = await auth.passwordreset.doReset(internalOptions, tokenParts, api.settings); web.shared.middleware.api.spamPrevention.userLogin().reset(frame.options.ip, `${tokenParts.email}login`); return doResetParams; } }, acceptInvitation: { headers: { cacheInvalidate: false }, validation: { docName: 'invitations' }, permissions: false, async query(frame) { await auth.setup.assertSetupCompleted(true)(); return invitations.accept(frame.data); } }, isInvitation: { headers: { cacheInvalidate: false }, data: [ 'email' ], validation: { docName: 'invitations' }, permissions: false, async query(frame) { await auth.setup.assertSetupCompleted(true)(); const email = frame.data.email; return models.Invite.findOne({email, status: 'sent'}, frame.options); } }, resetAllPasswords: { statusCode: 204, headers: { cacheInvalidate: false }, permissions: true, async query(frame) { await userService.resetAllPasswords(frame.options); await deleteAllSessions(); } } }; module.exports = controller;