Merge branch 'master' of ssh://numinibsd/git/base/enigma-bbs

This commit is contained in:
Bryan Ashby 2015-12-12 16:03:06 -07:00
commit 581b54cb37
16 changed files with 502 additions and 91 deletions

33
mods/art_pool.js Normal file
View file

@ -0,0 +1,33 @@
/* jslint node: true */
'use strict';
var MenuModule = require('../core/menu_module.js').MenuModule;
exports.getModule = ArtPoolModule;
exports.moduleInfo = {
name : 'Art Pool',
desc : 'Display art from a pool of options',
author : 'NuSkooler',
};
function ArtPoolModule(options) {
MenuModule.call(this, options);
var config = this.menuConfig.config;
//
// :TODO: General idea
// * Break up some of MenuModule initSequence's calls into methods
// * initSequence here basically has general "clear", "next", etc. as per normal
// * Display art -> ooptinal pause -> display more if requested, etc.
// * Finally exit & move on as per normal
}
require('util').inherits(ArtPoolModule, MenuModule);
MessageAreaModule.prototype.mciReady = function(mciData, cb) {
this.standardMCIReadyHandler(mciData, cb);
};

View file

@ -77,9 +77,7 @@
art: USERLOG
next: fullLoginSequenceLoginArt
config: {
tooNode: {
art: TOONODE
}
tooNodeMenu: loginAttemptTooNode
}
form: {
0: {
@ -114,6 +112,14 @@
}
}
loginAttemptTooNode: {
art: TOONODE
options: {
cls: true
nextTimeout: 2000
}
}
logoff: {
art: LOGOFF
next: @systemMethod:logoff
@ -122,6 +128,7 @@
TODO: display PRINT before this (Obv/2) or NEWUSER1 (Mystic)
*/
newUserApplication: {
module: nua
art: NUA
next: [
{
@ -141,23 +148,28 @@
focus: true
argName: username
maxLength: @config:users.usernameMax
validate: @systemMethod:validateUserNameAvail
}
ET2: {
argName: realName
maxLength: 32
validate: @systemMethod:validateNonEmpty
}
MET3: {
argName: birthdate
maskPattern: "####/##/##"
validate: @systemMethod:validateBirthdate
}
ME4: {
argName: sex
maskPattern: A
textStyle: upper
validate: @systemMethod:validateNonEmpty
}
ET5: {
argName: location
maxLength: 32
validate: @systemMethod:validateNonEmpty
}
ET6: {
argName: affils
@ -166,6 +178,7 @@
ET7: {
argName: email
maxLength: 255
validate: @systemMethod:validateEmailAvail
}
ET8: {
argName: web
@ -175,11 +188,13 @@
argName: password
password: true
maxLength: @config:users.passwordMax
validate: @systemMethod:validatePasswordSpec
}
ET10: {
argName: passwordConfirm
password: true
maxLength: @config:users.passwordMax
validate: @method:validatePassConfirmMatch
}
TM12: {
argName: submission
@ -192,7 +207,7 @@
*: [
{
value: { "submission" : 0 }
action: @method:apply/submitApplication
action: @method:submitApplication
extraArgs: {
inactive: userNeedsActivated
error: newUserCreateError
@ -227,23 +242,28 @@
focus: true
argName: username
maxLength: @config:users.usernameMax
validate: @systemMethod:validateUserNameAvail
}
ET2: {
argName: realName
maxLength: 32
validate: @systemMethod:validateNonEmpty
}
MET3: {
argName: birthdate
maskPattern: "####/##/##"
validate: @systemMethod:validateBirthdate
}
ME4: {
argName: sex
maskPattern: A
textStyle: upper
validate: @systemMethod:validateNonEmpty
}
ET5: {
argName: location
maxLength: 32
validate: @systemMethod:validateNonEmpty
}
ET6: {
argName: affils
@ -252,6 +272,7 @@
ET7: {
argName: email
maxLength: 255
validate: @systemMethod:validateEmailAvail
}
ET8: {
argName: web
@ -261,11 +282,13 @@
argName: password
password: true
maxLength: @config:users.passwordMax
validate: @systemMethod:validatePasswordSpec
}
ET10: {
argName: passwordConfirm
password: true
maxLength: @config:users.passwordMax
validate: @method:validatePassConfirmMatch
}
TM12: {
argName: submission
@ -278,7 +301,7 @@
*: [
{
value: { "submission" : 0 }
action: @method:apply/submitApplication
action: @method:submitApplication
extraArgs: {
inactive: userNeedsActivated
error: newUserCreateError
@ -350,6 +373,7 @@
maxLength: 72
submit: true
text: New user feedback
validate: @systemMethod:validateMessageSubject
}
}
submit: {
@ -445,7 +469,14 @@
module: last_callers
art: LASTCALL
options: { pause: true }
next: fullLoginSequenceSysStats
next: fullLoginSequenceWhosOnline
}
fullLoginSequenceWhosOnline: {
desc: Who's Online
module: whos_online
art: WHOSON
options: { pause: true }
next: fullLoginSequenceSysStats
}
fullLoginSequenceSysStats: {
desc: System Stats
@ -613,27 +644,31 @@
value: { command: "2" }
action: @menu:doorLORD
}
{
value: { command: "4" }
action: @menu:doorTradeWars2002BBSLink
}
]
}
/*
The 'abracadabra' module's config.args accepts the following format objects:
{dropFile} - Path to generated dropfile
{node} - Node number
*/
doorPimpWars: {
desc: Playing PimpWars
module: abracadabra
config: {
name: PimpWars
dropFileType: DORINFO
cmd: /usr/bin/dosemu
cmd: /home/nuskooler/DOS/scripts/pimpwars.sh
args: [
"-quiet", "-f", "/home/nuskooler/DOS/X/LORD/dosemu.conf", "X:\\PW\\START.BAT {dropFile} {node}"
"{node}",
"{dropFile}",
"{srvPort}",
],
nodeMax: 1
tooManyArt: DOORMANY
io: socket
}
},
}
doorLORD: {
desc: Playing L.O.R.D.
module: abracadabra
@ -646,6 +681,22 @@
]
}
}
//
// TradeWars 2000 example via BBSLink
//
// You will need to register with BBSLink to obtain sysCode, authCode and schemeCode
//
doorTradeWars2002BBSLink: {
desc: Playing TW 2002 (BBSLink)
module: bbs_link
config: {
sysCode: XXXXXXXX
authCode: XXXXXXXX
schemeCode: XXXXXXXX
door: tw
}
}
///////////////////////////////////////////////////////////////////////
// Message Area Menu
///////////////////////////////////////////////////////////////////////
@ -818,7 +869,7 @@
}
{
value: { 1: 3 }
action: @menu:messageArea
action: @systemMethod:prevMenu
}
{
value: { 1: 4 }
@ -882,11 +933,13 @@
ET2: {
argName: to
focus: true
validate: @systemMethod:validateNonEmpty
}
ET3: {
argName: subject
maxLength: 72
submit: true
validate: @systemMethod:validateNonEmpty
}
TL4: {
// :TODO: this is for RE: line (NYI)
@ -1029,11 +1082,14 @@
argName: to
focus: true
text: All
validate: @systemMethod:validateNonEmpty
}
ET3: {
argName: subject
maxLength: 72
submit: true
validate: @systemMethod:validateNonEmpty
// :TODO: Validate -> close/cancel if empty
}
}
submit: {

View file

@ -64,22 +64,3 @@ AreaPostFSEModule.prototype.enter = function(client) {
AreaPostFSEModule.super_.prototype.enter.call(this, client);
};
AreaPostFSEModule.prototype.validateToUserName = function(un, cb) {
var self = this;
if(!un) {
cb(new Error('Username must be supplied!'));
return;
}
if(!self.isLocalEmail()) {
cb(null);
return;
}
user.getUserIdAndName(un, function uidAndName(err, userId, userName) {
self.toUserId = userId;
cb(err);
});
};

136
mods/nua.js Normal file
View file

@ -0,0 +1,136 @@
/* jslint node: true */
'use strict';
var MenuModule = require('../core/menu_module.js').MenuModule;
var user = require('../core/user.js');
var theme = require('../core/theme.js');
var login = require('../core/system_menu_method.js').login;
var Config = require('../core/config.js').config;
var getDefaultMessageArea = require('../core/message_area.js').getDefaultMessageArea;
var async = require('async');
exports.getModule = NewUserAppModule;
exports.moduleInfo = {
name : 'NUA',
desc : 'New User Application',
}
var MciViewIds = {
userName : 1,
password : 9,
confirm : 10,
errMsg : 11,
};
function NewUserAppModule(options) {
MenuModule.call(this, options);
var self = this;
this.menuMethods = {
//
// Validation stuff
//
validatePassConfirmMatch : function(data, cb) {
var passwordView = self.viewControllers.menu.getView(MciViewIds.password);
cb(passwordView.getData() === data ? null : new Error('Passwords do not match'));
},
viewValidationListener : function(err, cb) {
var errMsgView = self.viewControllers.menu.getView(MciViewIds.errMsg);
var newFocusId;
if(err) {
errMsgView.setText(err.message);
err.view.clearText();
if(err.view.getId() === MciViewIds.confirm) {
newFocusId = MciViewIds.password;
var passwordView = self.viewControllers.menu.getView(MciViewIds.password);
passwordView.clearText();
}
} else {
errMsgView.clearText();
}
cb(newFocusId);
},
//
// Submit handlers
//
submitApplication : function(formData, extraArgs) {
var newUser = new user.User();
newUser.username = formData.value.username;
newUser.properties = {
real_name : formData.value.realName,
birthdate : new Date(Date.parse(formData.value.birthdate)).toISOString(),
sex : formData.value.sex,
location : formData.value.location,
affiliation : formData.value.affils,
email_address : formData.value.email,
web_address : formData.value.web,
account_created : new Date().toISOString(),
message_area_name : getDefaultMessageArea().name,
term_height : self.client.term.termHeight,
term_width : self.client.term.termWidth,
// :TODO: This is set in User.create() -- proabbly don't need it here:
//account_status : Config.users.requireActivation ? user.User.AccountStatus.inactive : user.User.AccountStatus.active,
// :TODO: Other defaults
// :TODO: should probably have a place to create defaults/etc.
};
if('*' === Config.defaults.theme) {
newUser.properties.theme_id = theme.getRandomTheme();
} else {
newUser.properties.theme_id = Config.defaults.theme;
}
// :TODO: .create() should also validate email uniqueness!
newUser.create( { password : formData.value.password }, function created(err) {
if(err) {
self.client.log.info( { error : err, username : formData.value.username }, 'New user creation failed');
self.gotoMenu(extraArgs.error, function result(err) {
if(err) {
self.prevMenu();
}
});
} else {
self.client.log.info( { username : formData.value.username, userId : newUser.userId }, 'New user created');
// Cache SysOp information now
// :TODO: Similar to bbs.js. DRY
if(newUser.isSysOp()) {
Config.general.sysOp = {
username : formData.value.username,
properties : newUser.properties,
};
}
if(user.User.AccountStatus.inactive === self.client.user.properties.account_status) {
self.gotoMenu(extraArgs.inactive);
} else {
//
// If active now, we need to call login() to authenticate
//
login(self, formData, extraArgs);
}
}
});
},
};
}
require('util').inherits(NewUserAppModule, MenuModule);
NewUserAppModule.prototype.mciReady = function(mciData, cb) {
this.standardMCIReadyHandler(mciData, cb);
};