From 5eee5685861a6c423340bdf7eaf1b64482e0ef4b Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Tue, 14 Apr 2015 22:27:07 -0600 Subject: [PATCH] * Apply now semi functional --- core/config.js | 6 +++ core/user.js | 36 +++++++++++-- mods/apply.js | 134 ++++++++++++++++++++++++++++--------------------- mods/menu.json | 6 ++- 4 files changed, 119 insertions(+), 63 deletions(-) diff --git a/core/config.js b/core/config.js index 5dd608b8..b8129993 100644 --- a/core/config.js +++ b/core/config.js @@ -27,6 +27,12 @@ module.exports = { preLoginTheme : '*', + users : { + usernameMin : 2, + usernameMax : 22, + passwordMin : 6, + }, + paths : { mods : paths.join(__dirname, './../mods/'), servers : paths.join(__dirname, './servers/'), diff --git a/core/user.js b/core/user.js index fae0dc66..a8415d8a 100644 --- a/core/user.js +++ b/core/user.js @@ -177,7 +177,7 @@ User.prototype.create = function(options, cb) { ); }, function genAuthCredentials(callback) { - generatePasswordDerivedKeySalt(options.password, function dkAndSalt(err, info) { + generatePasswordDerivedKeyAndSalt(options.password, function dkAndSalt(err, info) { if(err) { callback(err); } else { @@ -188,8 +188,9 @@ User.prototype.create = function(options, cb) { }); }, function saveAll(callback) { - // :TODO: persist all data - props/etc. - callback(null); + self.persist(false, function persisted(err) { + callback(err); + }); } ], function complete(err) { @@ -211,6 +212,8 @@ User.prototype.create = function(options, cb) { User.prototype.persist = function(useTransaction, cb) { assert(this.userId > 0); + var self = this; + async.series( [ function beginTransaction(callback) { @@ -223,7 +226,7 @@ User.prototype.persist = function(useTransaction, cb) { } }, function saveProps(callback) { - persistProperties(this, function persisted(err) { + persistProperties(self, function persisted(err) { callback(err); }); } @@ -250,6 +253,31 @@ User.prototype.persist = function(useTransaction, cb) { ); }; +User.prototype.persistProperties = function(cb) { + assert(this.userId > 0); + + var self = this; + + var stmt = userDb.prepare( + 'REPLACE INTO user_property (user_id, prop_name, prop_value) ' + + 'VALUES (?, ?, ?);'); + + async.each(Object.keys(this.properties), function property(propName, callback) { + stmt.run(self.userId, propName, self.properties[propName], function onRun(err) { + callback(err); + }); + }, function complete(err) { + if(err) { + cb(err); + } else { + stmt.finalize(function finalized() { + cb(null); + }); + } + }); +}; + + function createNew(user, cb) { assert(user.username && user.username.length > 1, 'Invalid userName'); diff --git a/mods/apply.js b/mods/apply.js index 96c26c47..f3e652b3 100644 --- a/mods/apply.js +++ b/mods/apply.js @@ -8,6 +8,9 @@ var theme = require('../core/theme.js'); var Log = require('../core/logger.js').log; var MenuModule = require('../core/menu_module.js').MenuModule; var ViewController = require('../core/view_controller.js').ViewController; +var Config = require('../core/config.js').config; + +var util = require('util'); //var async = require('async'); @@ -28,11 +31,81 @@ function ApplyModule(menuConfig) { var self = this; this.menuMethods.submitApplication = function(args) { - console.log('do submit') + var usernameView = self.viewController.getView(1); + var passwordView = self.viewController.getView(9); + var pwConfirmView = self.viewController.getView(10); + var statusView = self.viewController.getView(11); + + self.validateApplication(args, function validated(errString, clearFields) { + if(errString) { + statusView.setText(errString); + + clearFields.forEach(function formId(id) { + self.viewController.getView(id).setText(''); + }); + + self.viewController.switchFocus(clearFields[0]); + } else { + var newUser = new user.User(); + newUser.username = args.username; + newUser.properties = { + real_name : args.realName, + age : args.age, + sex : args.sex, + location : args.location, + affiliation : args.affils, + email_address : args.email, + web_address : args.web, + + // :TODO: Other defaults + // :TODO: should probably have a place to create defaults/etc. + // :TODO: set account_status to default based on Config.user... + }; + + newUser.create({ password : args.pw }, function created(err) { + if(err) { + console.log(err) + } else { + Log.info( { username : args.username, userId : newUser.userId }, 'New user created'); + } + }); + } + }); + }; + + this.validateApplication = function(args, cb) { + if(args.username.length < Config.users.usernameMin) { + cb('Handle too short!', [ 1 ]); + return; + } + + if(args.username.length > Config.users.usernameMax) { + cb('Handle too long!', [ 1 ]); + return; + } + + if(args.pw.length < Config.users.passwordMin) { + cb('Password too short!', [ 9, 10 ]); + return; + } + + if(args.pw !== args.pwConfirm) { + cb('Passwords do not match!', [ 9, 10 ]); + return; + } + + user.getUserIdAndName(args.username, function userIdAndName(err) { + var alreadyExists = !err; + if(alreadyExists) { + cb('Username unavailable!', [ 1 ] ); + } else { + cb(null); + } + }); }; } -require('util').inherits(ApplyModule, MenuModule); +util.inherits(ApplyModule, MenuModule); ApplyModule.prototype.enter = function(client) { ApplyModule.super_.prototype.enter.call(this, client); @@ -49,61 +122,6 @@ ApplyModule.prototype.mciReady = function(mciMap) { self.viewController = self.addViewController(new ViewController({ client : self.client } )); self.viewController.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) { - - var usernameView = self.viewController.getView(1); - var passwordView = self.viewController.getView(9); - var pwConfirmView = self.viewController.getView(10); - var statusView = self.viewController.getView(11); - - self.viewController.on('leave', function leaveView(view) { - switch(view.getId()) { - case 1 : - user.getUserIdAndName(view.getViewData(), function userIdAndName(err) { - var alreadyExists = !err; - if(alreadyExists) { - statusView.setText('Username unavailable!'); - self.viewController.switchFocus(1); // don't allow to leave - } else { - statusView.setText(''); - self.viewController.switchFocus(2); - } - }); - break; - } - }); -/* - usernameView.on('leave', function leaveUsername() { - user.getUserIdAndName(usernameView.getViewData(), function userIdAndName(err) { - var alreadyExists = !err; - if(alreadyExists) { - statusView.setText('Username unavailable!'); - self.viewController.switchFocus(1); // don't allow to leave - } else { - statusView.setText(''); - self.viewController.switchFocus(2); - } - }); - }); - - passwordView.on('leave', function leavePw() { - if(passwordView.getViewData().length < 3) { - statusView.setText('Password too short!'); - self.viewController.switchFocus(9); - } else { - statusView.setText(''); - } - }); - - pwConfirmView.on('leave', function leavePwConfirm() { - if(passwordView.getViewData() !== pwConfirmView.getViewData()) { - statusView.setText('Passwords must match!'); - self.viewController.switchFocus(9); - } else { - statusView.setText(''); - } - }); -*/ - - + }); }; \ No newline at end of file diff --git a/mods/menu.json b/mods/menu.json index 554328b0..3943ab02 100644 --- a/mods/menu.json +++ b/mods/menu.json @@ -124,6 +124,9 @@ { "value" : { "12" : null }, "action" : "@method:submitApplication", + // :TODO: Need a way to supply next menu based on data from @method + // @method:submitApplication|nextMenu1|nextMenu2|nextMenu3 ? method could cb(indexValue) + "args" : { "username" : "{1}", "realName" : "{2}", @@ -133,7 +136,8 @@ "affils" : "{6}", "email" : "{7}", "web" : "{8}", - "password" : "{9}" + "pw" : "{9}", + "pwConfirm" : "{10}" } } ],