Ghost/core/server/services/auth/setup.js
Naz Gargol 46706646e3
Refactored authentication controller v0.1 (#10893)
refs #10060

- Modules extractions done here are meant to make upcoming migration of authentication controller to v2 more manageable and reduce code repetition
- There were couple modules extracted for different areas that controller touches: passwordrest, accept (for invitation), setup 
- The aim was to keep changes to the minimum while making small readability improvements to new functions through async/await syntax
- The biggest barrier to make more encapsulated functions was the fact that we mutate options parameter on multiple levels in the controller. e.g mutations of options.data during validation on the password reset ties it up to the implementation of doReset function
2019-07-17 12:28:16 +02:00

127 lines
3.5 KiB
JavaScript

const _ = require('lodash');
const config = require('../../config');
const common = require('../../lib/common');
const models = require('../../models');
const mail = require('../mail');
/**
* Returns setup status
*
* @return {Promise<Boolean>}
*/
async function checkIsSetup() {
return models.User.isSetup();
}
/**
* Allows an assertion to be made about setup status.
*
* @param {Boolean} status True: setup must be complete. False: setup must not be complete.
* @return {Function} returns a "task ready" function
*/
function assertSetupCompleted(status) {
return async function checkPermission(__) {
const isSetup = await checkIsSetup();
if (isSetup === status) {
return __;
}
const completed = common.i18n.t('errors.api.authentication.setupAlreadyCompleted');
const notCompleted = common.i18n.t('errors.api.authentication.setupMustBeCompleted');
function throwReason(reason) {
throw new common.errors.NoPermissionError({message: reason});
}
if (isSetup) {
throwReason(completed);
} else {
throwReason(notCompleted);
}
};
}
async function setupUser(userData) {
const context = {context: {internal: true}};
const owner = await models.User.findOne({role: 'Owner', status: 'all'});
if (!owner) {
throw new common.errors.GhostError({
message: common.i18n.t('errors.api.authentication.setupUnableToRun')
});
}
const user = await models.User.setup(userData, _.extend({id: owner.id}, context));
return {
user: user,
userData: userData
};
}
async function doSettings(data, settingsAPI) {
const context = {context: {user: data.user.id}};
const user = data.user;
const blogTitle = data.userData.blogTitle;
let userSettings;
if (!blogTitle || typeof blogTitle !== 'string') {
return user;
}
userSettings = [
{key: 'title', value: blogTitle.trim()},
{key: 'description', value: common.i18n.t('common.api.authentication.sampleBlogDescription')}
];
await settingsAPI.edit({settings: userSettings}, context);
return user;
}
function sendNotification(setupUser, mailAPI) {
const data = {
ownerEmail: setupUser.email
};
common.events.emit('setup.completed', setupUser);
if (config.get('sendWelcomeEmail')) {
return mail.utils.generateContent({data: data, template: 'welcome'})
.then((content) => {
const message = {
to: setupUser.email,
subject: common.i18n.t('common.api.authentication.mail.yourNewGhostBlog'),
html: content.html,
text: content.text
},
payload = {
mail: [{
message: message,
options: {}
}]
};
mailAPI.send(payload, {context: {internal: true}})
.catch((err) => {
err.context = common.i18n.t('errors.api.authentication.unableToSendWelcomeEmail');
common.logging.error(err);
});
})
.return(setupUser);
}
return setupUser;
}
module.exports = {
checkIsSetup: checkIsSetup,
assertSetupCompleted: assertSetupCompleted,
setupUser: setupUser,
doSettings: doSettings,
sendNotification: sendNotification
};