Files
talk/bin/cli-setup
T
2018-01-25 16:18:05 -07:00

213 lines
5.5 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* Module dependencies.
*/
const util = require('./util');
const program = require('commander');
const inquirer = require('inquirer');
const mongoose = require('../services/mongoose');
const SettingModel = require('../models/setting');
const MODERATION_OPTIONS = require('../models/enum/moderation_options');
const SettingsService = require('../services/settings');
const SetupService = require('../services/setup');
const UsersService = require('../services/users');
const MigrationService = require('../services/migration');
const errors = require('../errors');
// Register the shutdown criteria.
util.onshutdown([() => mongoose.disconnect()]);
//==============================================================================
// Setting up the program command line arguments.
//==============================================================================
program
.description('runs the setup wizard to setup the application')
.option('--defaults', 'apply defaults for config instead of prompting')
.parse(process.argv);
//==============================================================================
// Setup the application
//==============================================================================
const performSetup = async () => {
// Get the current settings, we are expecing an error here.
try {
// Try to get the settings.
await SettingsService.retrieve();
// We should NOT have gotten a settings object, this means that the
// application is already setup. Error out here.
throw errors.ErrSettingsInit;
} catch (e) {
// If the error is `not init`, then we're good, otherwise, it's something
// else.
if (e !== errors.ErrSettingsNotInit) {
throw e;
}
}
if (program.defaults) {
await SettingsService.init();
// Get the migrations to run.
let migrations = await MigrationService.listPending();
// Perform all migrations.
await MigrationService.run(migrations);
console.log('Settings created.');
console.log('\nTalk is now installed!');
return;
}
// Create the base settings model.
let settings = new SettingModel();
console.log(
"\nWe'll ask you some questions in order to setup your installation of Talk.\n"
);
let answers = await inquirer.prompt([
{
type: 'input',
name: 'organizationName',
message: 'Organization Name',
default: settings.organizationName,
validate: input => {
if (input && input.length > 0) {
return true;
}
return 'Organization Name is required.';
},
},
{
type: 'list',
choices: MODERATION_OPTIONS,
name: 'moderation',
default: settings.moderation,
message: 'Select a moderation mode',
},
{
type: 'confirm',
name: 'requireEmailConfirmation',
default: settings.requireEmailConfirmation,
message: 'Should emails always be confirmed',
},
]);
// Update the settings that were changed.
Object.keys(answers).forEach(key => {
if (answers[key] !== undefined) {
settings[key] = answers[key];
}
});
answers = await inquirer.prompt([
{
type: 'confirm',
name: 'inputWhitelistedDomains',
default: true,
message: 'Would you like to specify a whitelisted domain',
},
{
type: 'input',
name: 'whitelistedDomain',
message: 'Whitelisted Domain',
when: ({ inputWhitelistedDomains }) => inputWhitelistedDomains,
validate: input => {
if (input && input.length > 0) {
return true;
}
return 'Whitelisted Domain cannot be empty.';
},
},
]);
if (answers.inputWhitelistedDomains) {
settings.domains.whitelist = [answers.whitelistedDomain];
}
console.log("\nWe'll ask you some questions about your first admin user.\n");
let user = await inquirer.prompt([
{
type: 'input',
name: 'username',
message: 'Username',
filter: username => {
return UsersService.isValidUsername(username, false).catch(err => {
throw err.message;
});
},
},
{
name: 'email',
message: 'Email',
format: 'email',
validate: value => {
if (value && value.length >= 3) {
return true;
}
return 'Email is required';
},
},
{
name: 'password',
message: 'Password',
type: 'password',
filter: password => {
return UsersService.isValidPassword(password).catch(err => {
throw err.message;
});
},
},
{
name: 'confirmPassword',
message: 'Confirm Password',
type: 'password',
filter: (confirmPassword, { password }) => {
if (password !== confirmPassword) {
return Promise.reject(new Error('Passwords do not match'));
}
return UsersService.isValidPassword(confirmPassword).catch(err => {
throw err.message;
});
},
},
]);
let { user: newUser } = await SetupService.setup({
settings: settings.toObject(),
user: {
email: user.email,
username: user.username,
password: user.password,
},
});
console.log('Settings created.');
console.log(`User ${newUser.id} created.`);
console.log('\nTalk is now installed!');
console.log(
'\nWe recommend adding TALK_INSTALL_LOCK=TRUE to your environment to turn off the dynamic setup.'
);
};
// Start the setup process.
performSetup()
.then(() => {
util.shutdown();
})
.catch(e => {
console.error(e);
util.shutdown(1);
});