This commit is contained in:
Wyatt Johnson
2017-01-30 18:21:04 -07:00
parent e6ef4b615f
commit 91cd2e9e86
8 changed files with 74 additions and 67 deletions
+6 -13
View File
@@ -4,7 +4,6 @@ const app = require('../app');
const program = require('./commander');
const debug = require('debug')('talk:server');
const http = require('http');
const init = require('../init');
const scraper = require('../services/scraper');
const mailer = require('../services/mailer');
const kue = require('../services/kue');
@@ -87,19 +86,13 @@ function onListening() {
* Start the app.
*/
function startApp() {
init().then(() => {
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
})
.catch((err) => {
console.error(err);
util.shutdown(1);
});
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
}
//==============================================================================
+10 -9
View File
@@ -31,20 +31,21 @@ program
console.log('We\'ll ask you some questions in order to setup your installation of Talk.\n');
SettingsService
.retrieve()
.catch(() => new SettingModel())
.init()
.then((settings) => {
if (settings && settings.id) {
console.log('We found preexisting settings in the database, we\'ll use it\'s values as defaults.\n');
}
return inquirer.prompt([
{
type: 'input',
name: 'organizationName',
message: 'Organization Name',
default: settings.organizationName
default: settings.organizationName,
validate: (input) => {
if (input && input.length > 0) {
return true;
}
return 'Organization Name is required.';
}
},
{
type: 'list',
@@ -69,7 +70,7 @@ SettingsService
}
});
return SettingsService.update(settings);
return settings.save();
});
})
.then(() => {
+23 -5
View File
@@ -12,8 +12,8 @@ const mongoose = require('../services/mongoose');
const util = require('../util');
const Table = require('cli-table');
const validateRequired = (msg = 'Field is required') => (input) => {
if (input && input.length > 0) {
const validateRequired = (msg = 'Field is required', len = 1) => (input) => {
if (input && input.length >= len) {
return true;
}
@@ -53,18 +53,36 @@ function getUserCreateAnswers(options) {
name: 'password',
message: 'Password',
type: 'password',
validate: validateRequired('Password is required')
filter: (password) => {
return UsersService
.isValidPassword(password)
.catch((err) => {
throw err.message;
});
}
},
{
name: 'confirmPassword',
message: 'Confirm Password',
type: 'password',
validate: validateRequired('Confirm Password is required')
filter: (confirmPassword) => {
return UsersService
.isValidPassword(confirmPassword)
.catch((err) => {
throw err.message;
});
}
},
{
name: 'displayName',
message: 'Display Name',
validate: validateRequired('Display Name is required')
filter: (displayName) => {
return UsersService
.isValidDisplayName(displayName)
.catch((err) => {
throw err.message;
});
}
},
{
name: 'roles',
-13
View File
@@ -1,13 +0,0 @@
const SettingsService = require('./services/settings');
module.exports = () => Promise.all([
// Upsert the settings object.
SettingsService.init({
moderation: 'POST',
wordlist: {
banned: [],
suspect: []
}
})
]);
+10 -8
View File
@@ -6,13 +6,6 @@ const MODERATION_OPTIONS = [
'POST'
];
const WordlistSchema = new Schema({
banned: [String],
suspect: [String]
}, {
_id: false
});
/**
* SettingSchema manages application settings that get used on front and backend.
* @type {Schema}
@@ -48,7 +41,16 @@ const SettingSchema = new Schema({
type: String,
default: 'Expired'
},
wordlist: WordlistSchema,
wordlist: {
banned: {
type: Array,
default: []
},
suspect: {
type: Array,
default: []
}
},
charCount: {
type: Number,
default: 5000
+7 -8
View File
@@ -44,15 +44,14 @@ module.exports = class SettingsService {
/**
* This is run once when the app starts to ensure settings are populated.
* @return {Promise} null initialize the global settings object
*/
static init(defaults) {
static init(defaults = {}) {
return SettingsService
.retrieve()
.catch(() => {
let settings = new SettingModel(defaults);
// Inject the defaults on top of the passed in defaults to ensure that the new
// settings conform to the required selector.
defaults = Object.assign({}, defaults, selector);
// Actually update the settings collection.
return SettingsService.update(defaults);
return settings.save();
});
}
};
+16 -9
View File
@@ -189,6 +189,18 @@ module.exports = class UsersService {
return Wordlist.displayNameCheck(displayName);
}
static isValidPassword(password) {
if (!password) {
return Promise.reject(errors.ErrMissingPassword);
}
if (password.length < 8) {
return Promise.reject(errors.ErrPasswordTooShort);
}
return Promise.resolve(password);
}
/**
* Creates the local user with a given email, password, and name.
* @param {String} email email of the new user
@@ -205,15 +217,10 @@ module.exports = class UsersService {
email = email.toLowerCase().trim();
displayName = displayName.toLowerCase().trim();
if (!password) {
return Promise.reject(errors.ErrMissingPassword);
}
if (password.length < 8) {
return Promise.reject(errors.ErrPasswordTooShort);
}
return UsersService.isValidDisplayName(displayName)
return Promise.all([
UsersService.isValidDisplayName(displayName),
UsersService.isValidPassword(password)
])
.then(() => { // displayName is valid
return new Promise((resolve, reject) => {
bcrypt.hash(password, SALT_ROUNDS, (err, hashedPassword) => {
+2 -2
View File
@@ -66,7 +66,7 @@ describe('/api/v1/auth/local', () => {
describe('email confirmation enabled', () => {
beforeEach(() => SettingsService.init({requireEmailConfirmation: true}));
beforeEach(() => SettingsService.update({requireEmailConfirmation: true}));
describe('#post', () => {
it('should not allow a login from a user that is not confirmed', () => {
@@ -74,7 +74,7 @@ describe('/api/v1/auth/local', () => {
.post('/api/v1/auth/local')
.send({email: 'maria@gmail.com', password: 'password!'})
.catch((err) => {
err.response.should.have.status(401);
expect(err).to.have.status(401);
return UsersService.createEmailConfirmToken(mockUser.id, mockUser.profiles[0].id);
})