Re-apply some Prettier formatting after merge
This commit is contained in:
parent
c93b8cda81
commit
9172fdda9d
|
@ -108,14 +108,22 @@ exports.getModule = class AbracadabraModule extends MenuModule {
|
|||
name: self.config.name,
|
||||
activeCount: activeDoorNodeInstances[self.config.name],
|
||||
},
|
||||
`Too many active instances of door "${self.config.name}"`);
|
||||
`Too many active instances of door "${self.config.name}"`
|
||||
);
|
||||
|
||||
if (_.isString(self.config.tooManyArt)) {
|
||||
theme.displayThemeArt( { client : self.client, name : self.config.tooManyArt }, function displayed() {
|
||||
theme.displayThemeArt(
|
||||
{ client: self.client, name: self.config.tooManyArt },
|
||||
function displayed() {
|
||||
self.pausePrompt(() => {
|
||||
return callback(Errors.AccessDenied('Too many active instances'));
|
||||
});
|
||||
return callback(
|
||||
Errors.AccessDenied(
|
||||
'Too many active instances'
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
} else {
|
||||
self.client.term.write(
|
||||
'\nToo many active instances. Try again later.\n'
|
||||
|
|
33
core/bbs.js
33
core/bbs.js
|
@ -152,7 +152,9 @@ function shutdownSystem() {
|
|||
[
|
||||
function closeConnections(callback) {
|
||||
const ClientConns = require('./client_connections.js');
|
||||
const activeConnections = ClientConns.getActiveConnections(ClientConns.AllConnections);
|
||||
const activeConnections = ClientConns.getActiveConnections(
|
||||
ClientConns.AllConnections
|
||||
);
|
||||
let i = activeConnections.length;
|
||||
while (i--) {
|
||||
const activeTerm = activeConnections[i].term;
|
||||
|
@ -334,7 +336,9 @@ function initialize(cb) {
|
|||
[UserLogNames.NewUser, [SysProps.NewUsersTodayCount, 'count']],
|
||||
];
|
||||
|
||||
async.each(entries, (entry, nextEntry) => {
|
||||
async.each(
|
||||
entries,
|
||||
(entry, nextEntry) => {
|
||||
const [logName, [sysPropName, resultType]] = entry;
|
||||
|
||||
const filter = {
|
||||
|
@ -346,7 +350,11 @@ function initialize(cb) {
|
|||
StatLog.findUserLogEntries(filter, (err, stat) => {
|
||||
if (!err) {
|
||||
if (resultType === 'obj') {
|
||||
stat = stat.reduce( (bytes, entry) => bytes + parseInt(entry.log_value) || 0, 0);
|
||||
stat = stat.reduce(
|
||||
(bytes, entry) =>
|
||||
bytes + parseInt(entry.log_value) || 0,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
StatLog.setNonPersistentSystemStat(sysPropName, stat);
|
||||
|
@ -356,23 +364,25 @@ function initialize(cb) {
|
|||
},
|
||||
() => {
|
||||
return callback(null);
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
function initLastLogin(callback) {
|
||||
const StatLog = require('./stat_log');
|
||||
StatLog.getSystemLogEntries(SysLogKeys.UserLoginHistory, 'timestamp_desc', 1, (err, lastLogin) => {
|
||||
StatLog.getSystemLogEntries(
|
||||
SysLogKeys.UserLoginHistory,
|
||||
'timestamp_desc',
|
||||
1,
|
||||
(err, lastLogin) => {
|
||||
if (err) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
let loginObj;
|
||||
try
|
||||
{
|
||||
try {
|
||||
loginObj = JSON.parse(lastLogin[0].log_value);
|
||||
loginObj.timestamp = moment(lastLogin[0].timestamp);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
} catch (e) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
|
@ -383,7 +393,8 @@ function initialize(cb) {
|
|||
StatLog.setNonPersistentSystemStat(SysProps.LastLogin, stat);
|
||||
return callback(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
function initUserCount(callback) {
|
||||
const User = require('./user.js');
|
||||
|
|
|
@ -594,10 +594,8 @@ Client.prototype.isLocal = function () {
|
|||
|
||||
Client.prototype.friendlyRemoteAddress = function () {
|
||||
// convert any :ffff: IPv4's to 32bit version
|
||||
return this.remoteAddress
|
||||
.replace(/^::ffff:/, '')
|
||||
.replace(/^::1$/, 'localhost');
|
||||
}
|
||||
return this.remoteAddress.replace(/^::ffff:/, '').replace(/^::1$/, 'localhost');
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Default error handlers
|
||||
|
|
|
@ -24,13 +24,23 @@ exports.clientConnections = clientConnections;
|
|||
const AllConnections = { authUsersOnly: false, visibleOnly: false, availOnly: false };
|
||||
exports.AllConnections = AllConnections;
|
||||
|
||||
const UserVisibleConnections = { authUsersOnly: false, visibleOnly: true, availOnly: false };
|
||||
const UserVisibleConnections = {
|
||||
authUsersOnly: false,
|
||||
visibleOnly: true,
|
||||
availOnly: false,
|
||||
};
|
||||
exports.UserVisibleConnections = UserVisibleConnections;
|
||||
|
||||
const UserMessageableConnections = { authUsersOnly: true, visibleOnly: true, availOnly: true };
|
||||
const UserMessageableConnections = {
|
||||
authUsersOnly: true,
|
||||
visibleOnly: true,
|
||||
availOnly: true,
|
||||
};
|
||||
exports.UserMessageableConnections = UserMessageableConnections;
|
||||
|
||||
function getActiveConnections(options = { authUsersOnly: true, visibleOnly: true, availOnly: false }) {
|
||||
function getActiveConnections(
|
||||
options = { authUsersOnly: true, visibleOnly: true, availOnly: false }
|
||||
) {
|
||||
return clientConnections.filter(conn => {
|
||||
if (options.authUsersOnly && !conn.user.isAuthenticated()) {
|
||||
return false;
|
||||
|
@ -46,7 +56,9 @@ function getActiveConnections(options = { authUsersOnly: true, visibleOnly: true
|
|||
});
|
||||
}
|
||||
|
||||
function getActiveConnectionList(options = { authUsersOnly: true, visibleOnly: true, availOnly: false }) {
|
||||
function getActiveConnectionList(
|
||||
options = { authUsersOnly: true, visibleOnly: true, availOnly: false }
|
||||
) {
|
||||
const now = moment();
|
||||
|
||||
return _.map(getActiveConnections(options), ac => {
|
||||
|
@ -79,7 +91,10 @@ function getActiveConnectionList(options = { authUsersOnly: true, visibleOnly: t
|
|||
entry.location = ac.user.properties[UserProps.Location];
|
||||
entry.affils = entry.affiliation = ac.user.properties[UserProps.Affiliations];
|
||||
|
||||
const diff = now.diff(moment(ac.user.properties[UserProps.LastLoginTs]), 'minutes');
|
||||
const diff = now.diff(
|
||||
moment(ac.user.properties[UserProps.LastLoginTs]),
|
||||
'minutes'
|
||||
);
|
||||
entry.timeOn = moment.duration(diff, 'minutes');
|
||||
}
|
||||
|
||||
|
@ -126,7 +141,10 @@ function addNewClient(client, clientSock) {
|
|||
connInfo.family = clientSock.localFamily;
|
||||
}
|
||||
|
||||
client.log.info(connInfo, `Client connected (${connInfo.serverName}/${connInfo.port})`);
|
||||
client.log.info(
|
||||
connInfo,
|
||||
`Client connected (${connInfo.serverName}/${connInfo.port})`
|
||||
);
|
||||
|
||||
Events.emit(Events.getSystemEvents().ClientConnected, {
|
||||
client: client,
|
||||
|
|
|
@ -32,7 +32,10 @@ module.exports = class Door {
|
|||
});
|
||||
|
||||
conn.once('error', err => {
|
||||
this.client.log.warn( { error : err.message }, 'Door socket server connection');
|
||||
this.client.log.warn(
|
||||
{ error: err.message },
|
||||
'Door socket server connection'
|
||||
);
|
||||
return this.restoreIo(conn);
|
||||
});
|
||||
|
||||
|
|
|
@ -112,7 +112,10 @@ class ScheduledEvent {
|
|||
}
|
||||
|
||||
executeAction(reason, cb) {
|
||||
Log.info( { eventName : this.name, action : this.action, reason : reason }, `Executing scheduled event "${this.name}"...`);
|
||||
Log.info(
|
||||
{ eventName: this.name, action: this.action, reason: reason },
|
||||
`Executing scheduled event "${this.name}"...`
|
||||
);
|
||||
|
||||
if ('method' === this.action.type) {
|
||||
const modulePath = path.join(__dirname, '../', this.action.location); // enigma-bbs base + supplied location (path/file.js')
|
||||
|
|
|
@ -380,7 +380,10 @@ exports.getModule = class FileAreaList extends MenuModule {
|
|||
return self.displayArtAndPrepViewController(
|
||||
'browse',
|
||||
FormIds.browse,
|
||||
{ clearScreen : clearScreen, artDataPrep: self.displayArtDataPrepCallback.bind(self) },
|
||||
{
|
||||
clearScreen: clearScreen,
|
||||
artDataPrep: self.displayArtDataPrepCallback.bind(self),
|
||||
},
|
||||
callback
|
||||
);
|
||||
},
|
||||
|
@ -473,7 +476,10 @@ exports.getModule = class FileAreaList extends MenuModule {
|
|||
return self.displayArtAndPrepViewController(
|
||||
'details',
|
||||
FormIds.details,
|
||||
{ clearScreen : true, artDataPrep: self.displayArtDataPrepCallback.bind(self) },
|
||||
{
|
||||
clearScreen: true,
|
||||
artDataPrep: self.displayArtDataPrepCallback.bind(self),
|
||||
},
|
||||
callback
|
||||
);
|
||||
},
|
||||
|
@ -727,7 +733,7 @@ exports.getModule = class FileAreaList extends MenuModule {
|
|||
{
|
||||
clearScreen: false,
|
||||
noInput: true,
|
||||
artDataPrep: self.displayArtDataPrepCallback.bind(self)
|
||||
artDataPrep: self.displayArtDataPrepCallback.bind(self),
|
||||
},
|
||||
callback
|
||||
);
|
||||
|
|
|
@ -535,22 +535,21 @@ class FileAreaWebAccess {
|
|||
StatLog.incrementSystemStat(SysProps.FileDlTotalBytes, dlBytes);
|
||||
|
||||
StatLog.incrementNonPersistentSystemStat(SysProps.FileDlTodayCount, 1);
|
||||
StatLog.incrementNonPersistentSystemStat(SysProps.FileDlTodayBytes, dlBytes);
|
||||
StatLog.incrementNonPersistentSystemStat(
|
||||
SysProps.FileDlTodayBytes,
|
||||
dlBytes
|
||||
);
|
||||
|
||||
return callback(null, user);
|
||||
},
|
||||
function sendEvent(user, callback) {
|
||||
Events.emit(
|
||||
Events.getSystemEvents().UserDownload,
|
||||
{
|
||||
Events.emit(Events.getSystemEvents().UserDownload, {
|
||||
user: user,
|
||||
files: fileEntries,
|
||||
}
|
||||
);
|
||||
});
|
||||
return callback(null);
|
||||
}
|
||||
]
|
||||
);
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,8 @@ exports.getModule = class FileBaseDownloadQueueManager extends MenuModule {
|
|||
[
|
||||
function prepArtAndViewController(callback) {
|
||||
return self.displayArtAndPrepViewController(
|
||||
'queueManager', FormIds.queueManager,
|
||||
'queueManager',
|
||||
FormIds.queueManager,
|
||||
{ clearScreen: clearScreen },
|
||||
callback
|
||||
);
|
||||
|
|
|
@ -148,7 +148,10 @@ exports.getModule = class TransferFileModule extends MenuModule {
|
|||
sentFiles.push(f.path);
|
||||
});
|
||||
|
||||
this.client.log.info( { sentFiles : sentFiles }, `User "${self.client.user.username}" uploaded ${sentFiles.length} file(s)` );
|
||||
this.client.log.info(
|
||||
{ sentFiles: sentFiles },
|
||||
`User "${self.client.user.username}" uploaded ${sentFiles.length} file(s)`
|
||||
);
|
||||
}
|
||||
return cb(err);
|
||||
});
|
||||
|
|
|
@ -613,7 +613,7 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
|||
|
||||
async.waterfall(
|
||||
[
|
||||
(callback) => {
|
||||
callback => {
|
||||
if (options.clearScreen) {
|
||||
this.client.term.rawWrite(ansi.resetScreen());
|
||||
}
|
||||
|
@ -638,7 +638,10 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
|||
vcOpts.noInput = options.noInput;
|
||||
}
|
||||
|
||||
const vc = this.addViewController(name, new ViewController(vcOpts));
|
||||
const vc = this.addViewController(
|
||||
name,
|
||||
new ViewController(vcOpts)
|
||||
);
|
||||
|
||||
if (_.isFunction(options.artDataPrep)) {
|
||||
try {
|
||||
|
@ -816,17 +819,23 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
|||
|
||||
// Various common helpers
|
||||
getDateFormat(defaultStyle = 'short') {
|
||||
return this.config.dateFormat ||
|
||||
this.client.currentTheme.helpers.getDateFormat(defaultStyle);
|
||||
return (
|
||||
this.config.dateFormat ||
|
||||
this.client.currentTheme.helpers.getDateFormat(defaultStyle)
|
||||
);
|
||||
}
|
||||
|
||||
getTimeFormat(defaultStyle = 'short') {
|
||||
return this.config.timeFormat ||
|
||||
this.client.currentTheme.helpers.getTimeFormat(defaultStyle);
|
||||
return (
|
||||
this.config.timeFormat ||
|
||||
this.client.currentTheme.helpers.getTimeFormat(defaultStyle)
|
||||
);
|
||||
}
|
||||
|
||||
getDateTimeFormat(defaultStyle = 'short') {
|
||||
return this.config.dateTimeFormat ||
|
||||
this.client.currentTheme.helpers.getDateTimeFormat(defaultStyle);
|
||||
return (
|
||||
this.config.dateTimeFormat ||
|
||||
this.client.currentTheme.helpers.getDateTimeFormat(defaultStyle)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -536,20 +536,30 @@ function getNewMessageCountInAreaForUser(userId, areaTag, cb) {
|
|||
// that are addressed to that user (ie: matching username)
|
||||
// Does NOT Include private messages.
|
||||
function getNewMessageCountAddressedToUser(client, cb) {
|
||||
const areaTags = getAllAvailableMessageAreaTags(client).filter(areaTag => areaTag !== Message.WellKnownAreaTags.Private);
|
||||
const areaTags = getAllAvailableMessageAreaTags(client).filter(
|
||||
areaTag => areaTag !== Message.WellKnownAreaTags.Private
|
||||
);
|
||||
|
||||
let newMessageCount = 0;
|
||||
async.forEach(areaTags, (areaTag, nextAreaTag) => {
|
||||
async.forEach(
|
||||
areaTags,
|
||||
(areaTag, nextAreaTag) => {
|
||||
getMessageAreaLastReadId(client.user.userId, areaTag, (_, lastMessageId) => {
|
||||
lastMessageId = lastMessageId || 0;
|
||||
getNewMessageCountInAreaForUser(client.user.userId, areaTag, (err, count) => {
|
||||
getNewMessageCountInAreaForUser(
|
||||
client.user.userId,
|
||||
areaTag,
|
||||
(err, count) => {
|
||||
newMessageCount += count;
|
||||
return nextAreaTag(err);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}, () => {
|
||||
},
|
||||
() => {
|
||||
return cb(null, newMessageCount);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getNewMessagesInAreaForUser(userId, areaTag, cb) {
|
||||
|
@ -572,9 +582,7 @@ function getNewMessagesInAreaForUser(userId, areaTag, cb) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
function getMessageListForArea(client, areaTag, filter, cb)
|
||||
{
|
||||
function getMessageListForArea(client, areaTag, filter, cb) {
|
||||
if (!cb && _.isFunction(filter)) {
|
||||
cb = filter;
|
||||
filter = {
|
||||
|
|
|
@ -12,7 +12,9 @@ function dailyMaintenanceScheduledEvent(args, cb) {
|
|||
//
|
||||
// :TODO: files/etc. here
|
||||
const resetProps = [
|
||||
SysProps.LoginsToday, SysProps.MessagesToday, SysProps.NewUsersTodayCount,
|
||||
SysProps.LoginsToday,
|
||||
SysProps.MessagesToday,
|
||||
SysProps.NewUsersTodayCount,
|
||||
];
|
||||
|
||||
resetProps.forEach(prop => {
|
||||
|
|
|
@ -46,7 +46,11 @@ exports.getModule = class AreaPostFSEModule extends FullScreenEditorModule {
|
|||
} else {
|
||||
// note: not logging 'from' here as it's part of client.log.xxxx()
|
||||
self.client.log.info(
|
||||
{ to : msg.toUserName, subject : msg.subject, uuid : msg.messageUuid },
|
||||
{
|
||||
to: msg.toUserName,
|
||||
subject: msg.subject,
|
||||
uuid: msg.messageUuid,
|
||||
},
|
||||
`User "${self.client.user.username}" posted message to "${msg.toUserName}" (${msg.areaTag})`
|
||||
);
|
||||
}
|
||||
|
|
|
@ -221,7 +221,8 @@ exports.getModule = class NodeMessageModule extends MenuModule {
|
|||
|
||||
prepareNodeList() {
|
||||
// standard node list with {text} field added for compliance
|
||||
this.nodeList = [{
|
||||
this.nodeList = [
|
||||
{
|
||||
text: '-ALL-',
|
||||
// dummy fields:
|
||||
node: -1,
|
||||
|
@ -233,9 +234,16 @@ exports.getModule = class NodeMessageModule extends MenuModule {
|
|||
location: 'N/A',
|
||||
affils: 'N/A',
|
||||
timeOn: 'N/A',
|
||||
}].concat(getActiveConnectionList(UserMessageableConnections)
|
||||
.map(node => Object.assign(node, { text : -1 == node.node ? '-ALL-' : node.node.toString() } ))
|
||||
).filter(node => node.node !== this.client.node); // remove our client's node
|
||||
},
|
||||
]
|
||||
.concat(
|
||||
getActiveConnectionList(UserMessageableConnections).map(node =>
|
||||
Object.assign(node, {
|
||||
text: -1 == node.node ? '-ALL-' : node.node.toString(),
|
||||
})
|
||||
)
|
||||
)
|
||||
.filter(node => node.node !== this.client.node); // remove our client's node
|
||||
this.nodeList.sort((a, b) => a.node - b.node); // sort by node
|
||||
}
|
||||
|
||||
|
|
10
core/nua.js
10
core/nua.js
|
@ -130,7 +130,10 @@ exports.getModule = class NewUserAppModule extends MenuModule {
|
|||
};
|
||||
newUser.create(createUserInfo, err => {
|
||||
if (err) {
|
||||
self.client.log.warn( { error : err, username : formData.value.username }, 'New user creation failed');
|
||||
self.client.log.warn(
|
||||
{ error: err, username: formData.value.username },
|
||||
'New user creation failed'
|
||||
);
|
||||
|
||||
self.gotoMenu(extraArgs.error, err => {
|
||||
if (err) {
|
||||
|
@ -139,7 +142,10 @@ exports.getModule = class NewUserAppModule extends MenuModule {
|
|||
return cb(null);
|
||||
});
|
||||
} else {
|
||||
self.client.log.info( { username : formData.value.username, userId : newUser.userId }, `New user "${formData.value.username}" created`);
|
||||
self.client.log.info(
|
||||
{ username: formData.value.username, userId: newUser.userId },
|
||||
`New user "${formData.value.username}" created`
|
||||
);
|
||||
|
||||
// Cache SysOp information now
|
||||
// :TODO: Similar to bbs.js. DRY
|
||||
|
|
|
@ -27,14 +27,14 @@ exports.init = init;
|
|||
function init(cb) {
|
||||
async.series(
|
||||
[
|
||||
(callback) => {
|
||||
callback => {
|
||||
return setNextRandomRumor(callback);
|
||||
},
|
||||
(callback) => {
|
||||
callback => {
|
||||
// by fetching a memory or load we'll force a refresh now
|
||||
StatLog.getSystemStat(SysProps.SystemMemoryStats);
|
||||
return callback(null);
|
||||
}
|
||||
},
|
||||
],
|
||||
err => {
|
||||
return cb(err);
|
||||
|
@ -98,37 +98,86 @@ const PREDEFINED_MCI_GENERATORS = {
|
|||
},
|
||||
|
||||
// +op info
|
||||
SN : function opUserName() { return StatLog.getSystemStat(SysProps.SysOpUsername); },
|
||||
SR : function opRealName() { return StatLog.getSystemStat(SysProps.SysOpRealName); },
|
||||
SL : function opLocation() { return StatLog.getSystemStat(SysProps.SysOpLocation); },
|
||||
SA : function opAffils() { return StatLog.getSystemStat(SysProps.SysOpAffiliations); },
|
||||
SS : function opSex() { return StatLog.getSystemStat(SysProps.SysOpSex); },
|
||||
SE : function opEmail() { return StatLog.getSystemStat(SysProps.SysOpEmailAddress); },
|
||||
SN: function opUserName() {
|
||||
return StatLog.getSystemStat(SysProps.SysOpUsername);
|
||||
},
|
||||
SR: function opRealName() {
|
||||
return StatLog.getSystemStat(SysProps.SysOpRealName);
|
||||
},
|
||||
SL: function opLocation() {
|
||||
return StatLog.getSystemStat(SysProps.SysOpLocation);
|
||||
},
|
||||
SA: function opAffils() {
|
||||
return StatLog.getSystemStat(SysProps.SysOpAffiliations);
|
||||
},
|
||||
SS: function opSex() {
|
||||
return StatLog.getSystemStat(SysProps.SysOpSex);
|
||||
},
|
||||
SE: function opEmail() {
|
||||
return StatLog.getSystemStat(SysProps.SysOpEmailAddress);
|
||||
},
|
||||
|
||||
//
|
||||
// Current user / session
|
||||
//
|
||||
UN : function userName(client) { return client.user.username; },
|
||||
UI : function userId(client) { return client.user.userId.toString(); },
|
||||
UG : function groups(client) { return _.values(client.user.groups).join(', '); },
|
||||
UR : function realName(client) { return userStatAsString(client, UserProps.RealName, ''); },
|
||||
LO : function location(client) { return userStatAsString(client, UserProps.Location, ''); },
|
||||
UA : function age(client) { return client.user.getAge().toString(); },
|
||||
BD : function birthdate(client) { // iNiQUiTY
|
||||
return moment(client.user.properties[UserProps.Birthdate]).format(client.currentTheme.helpers.getDateFormat());
|
||||
UN: function userName(client) {
|
||||
return client.user.username;
|
||||
},
|
||||
UI: function userId(client) {
|
||||
return client.user.userId.toString();
|
||||
},
|
||||
UG: function groups(client) {
|
||||
return _.values(client.user.groups).join(', ');
|
||||
},
|
||||
UR: function realName(client) {
|
||||
return userStatAsString(client, UserProps.RealName, '');
|
||||
},
|
||||
LO: function location(client) {
|
||||
return userStatAsString(client, UserProps.Location, '');
|
||||
},
|
||||
UA: function age(client) {
|
||||
return client.user.getAge().toString();
|
||||
},
|
||||
BD: function birthdate(client) {
|
||||
// iNiQUiTY
|
||||
return moment(client.user.properties[UserProps.Birthdate]).format(
|
||||
client.currentTheme.helpers.getDateFormat()
|
||||
);
|
||||
},
|
||||
US: function sex(client) {
|
||||
return userStatAsString(client, UserProps.Sex, '');
|
||||
},
|
||||
UE: function emailAddress(client) {
|
||||
return userStatAsString(client, UserProps.EmailAddress, '');
|
||||
},
|
||||
UW: function webAddress(client) {
|
||||
return userStatAsString(client, UserProps.WebAddress, '');
|
||||
},
|
||||
UF: function affils(client) {
|
||||
return userStatAsString(client, UserProps.Affiliations, '');
|
||||
},
|
||||
US : function sex(client) { return userStatAsString(client, UserProps.Sex, ''); },
|
||||
UE : function emailAddress(client) { return userStatAsString(client, UserProps.EmailAddress, ''); },
|
||||
UW : function webAddress(client) { return userStatAsString(client, UserProps.WebAddress, ''); },
|
||||
UF : function affils(client) { return userStatAsString(client, UserProps.Affiliations, ''); },
|
||||
UT: function themeName(client) {
|
||||
return _.get(client, 'currentTheme.info.name', userStatAsString(client, UserProps.ThemeId, ''));
|
||||
return _.get(
|
||||
client,
|
||||
'currentTheme.info.name',
|
||||
userStatAsString(client, UserProps.ThemeId, '')
|
||||
);
|
||||
},
|
||||
UD: function themeId(client) {
|
||||
return userStatAsString(client, UserProps.ThemeId, '');
|
||||
},
|
||||
UC: function loginCount(client) {
|
||||
return userStatAsCountString(client, UserProps.LoginCount, 0);
|
||||
},
|
||||
ND: function connectedNode(client) {
|
||||
return client.node.toString();
|
||||
},
|
||||
IP: function clientIpAddress(client) {
|
||||
return client.friendlyRemoteAddress();
|
||||
},
|
||||
ST: function serverName(client) {
|
||||
return client.session.serverName;
|
||||
},
|
||||
UD : function themeId(client) { return userStatAsString(client, UserProps.ThemeId, ''); },
|
||||
UC : function loginCount(client) { return userStatAsCountString(client, UserProps.LoginCount, 0); },
|
||||
ND : function connectedNode(client) { return client.node.toString(); },
|
||||
IP : function clientIpAddress(client) { return client.friendlyRemoteAddress() },
|
||||
ST : function serverName(client) { return client.session.serverName; },
|
||||
FN: function activeFileBaseFilterName(client) {
|
||||
const activeFilter = FileBaseFilters.getActiveFilter(client);
|
||||
return activeFilter ? activeFilter.name : '(Unknown)';
|
||||
|
@ -235,18 +284,21 @@ const PREDEFINED_MCI_GENERATORS = {
|
|||
return moment.duration(minutes, 'minutes').humanize();
|
||||
},
|
||||
NM: function userNewMessagesAddressedToCount(client) {
|
||||
return StatLog.getUserStatNumByClient(client, UserProps.NewAddressedToMessageCount);
|
||||
return StatLog.getUserStatNumByClient(
|
||||
client,
|
||||
UserProps.NewAddressedToMessageCount
|
||||
);
|
||||
},
|
||||
NP: function userNewPrivateMailCount(client) {
|
||||
return StatLog.getUserStatNumByClient(client, UserProps.NewPrivateMailCount);
|
||||
},
|
||||
IA: function userStatusAvailableIndicator(client) {
|
||||
const indicators = client.currentTheme.helpers.getStatusAvailIndicators();
|
||||
return client.user.isAvailable() ? (indicators[0] || 'Y') : (indicators[1] || 'N');
|
||||
return client.user.isAvailable() ? indicators[0] || 'Y' : indicators[1] || 'N';
|
||||
},
|
||||
IV: function userStatusVisibleIndicator(client) {
|
||||
const indicators = client.currentTheme.helpers.getStatusVisibleIndicators();
|
||||
return client.user.isVisible() ? (indicators[0] || 'Y') : (indicators[1] || 'N');
|
||||
return client.user.isVisible() ? indicators[0] || 'Y' : indicators[1] || 'N';
|
||||
},
|
||||
|
||||
//
|
||||
|
@ -295,11 +347,15 @@ const PREDEFINED_MCI_GENERATORS = {
|
|||
},
|
||||
|
||||
MB: function totalMemoryBytes() {
|
||||
const stats = StatLog.getSystemStat(SysProps.SystemMemoryStats) || { totalBytes : 0 };
|
||||
const stats = StatLog.getSystemStat(SysProps.SystemMemoryStats) || {
|
||||
totalBytes: 0,
|
||||
};
|
||||
return formatByteSize(stats.totalBytes, true); // true=withAbbr
|
||||
},
|
||||
MF: function totalMemoryFreeBytes() {
|
||||
const stats = StatLog.getSystemStat(SysProps.SystemMemoryStats) || { freeBytes : 0 };
|
||||
const stats = StatLog.getSystemStat(SysProps.SystemMemoryStats) || {
|
||||
freeBytes: 0,
|
||||
};
|
||||
return formatByteSize(stats.freeBytes, true); // true=withAbbr
|
||||
},
|
||||
LA: function systemLoadAverage() {
|
||||
|
@ -313,8 +369,14 @@ const PREDEFINED_MCI_GENERATORS = {
|
|||
UU: function systemUptime() {
|
||||
return moment.duration(process.uptime(), 'seconds').humanize();
|
||||
},
|
||||
NV : function nodeVersion() { return process.version; },
|
||||
AN : function activeNodes() { return clientConnections.getActiveConnections(clientConnections.UserVisibleConnections).length.toString(); },
|
||||
NV: function nodeVersion() {
|
||||
return process.version;
|
||||
},
|
||||
AN: function activeNodes() {
|
||||
return clientConnections
|
||||
.getActiveConnections(clientConnections.UserVisibleConnections)
|
||||
.length.toString();
|
||||
},
|
||||
|
||||
TC: function totalCalls() {
|
||||
return StatLog.getSystemStat(SysProps.LoginCount).toLocaleString();
|
||||
|
@ -333,12 +395,16 @@ const PREDEFINED_MCI_GENERATORS = {
|
|||
//
|
||||
// System File Base, Up/Download Info
|
||||
//
|
||||
SD : function systemNumDownloads() { return StatLog.getFriendlySystemStat(SysProps.FileDlTotalCount, 0); },
|
||||
SD: function systemNumDownloads() {
|
||||
return StatLog.getFriendlySystemStat(SysProps.FileDlTotalCount, 0);
|
||||
},
|
||||
SO: function systemByteDownload() {
|
||||
const byteSize = StatLog.getSystemStatNum(SysProps.FileDlTotalBytes);
|
||||
return formatByteSize(byteSize, true); // true=withAbbr
|
||||
},
|
||||
SU : function systemNumUploads() { return StatLog.getFriendlySystemStat(SysProps.FileUlTotalCount, 0); },
|
||||
SU: function systemNumUploads() {
|
||||
return StatLog.getFriendlySystemStat(SysProps.FileUlTotalCount, 0);
|
||||
},
|
||||
SP: function systemByteUpload() {
|
||||
const byteSize = StatLog.getSystemStatNum(SysProps.FileUlTotalBytes);
|
||||
return formatByteSize(byteSize, true); // true=withAbbr
|
||||
|
@ -352,27 +418,32 @@ const PREDEFINED_MCI_GENERATORS = {
|
|||
const totalBytes = parseInt(_.get(areaStats, 'totalBytes', 0));
|
||||
return formatByteSize(totalBytes, true); // true=withAbbr
|
||||
},
|
||||
PT : function messagesPostedToday() { // Obv/2
|
||||
PT: function messagesPostedToday() {
|
||||
// Obv/2
|
||||
return StatLog.getFriendlySystemStat(SysProps.MessagesToday, 0);
|
||||
},
|
||||
TP : function totalMessagesOnSystem() { // Obv/2
|
||||
TP: function totalMessagesOnSystem() {
|
||||
// Obv/2
|
||||
return StatLog.getFriendlySystemStat(SysProps.MessageTotalCount, 0);
|
||||
},
|
||||
FT : function totalUploadsToday() { // Obv/2
|
||||
FT: function totalUploadsToday() {
|
||||
// Obv/2
|
||||
return StatLog.getFriendlySystemStat(SysProps.FileUlTodayCount, 0);
|
||||
},
|
||||
FB: function totalUploadBytesToday() {
|
||||
const byteSize = StatLog.getSystemStatNum(SysProps.FileUlTodayBytes);
|
||||
return formatByteSize(byteSize, true); // true=withAbbr
|
||||
},
|
||||
DD : function totalDownloadsToday() { // iNiQUiTY
|
||||
DD: function totalDownloadsToday() {
|
||||
// iNiQUiTY
|
||||
return StatLog.getFriendlySystemStat(SysProps.FileDlTodayCount, 0);
|
||||
},
|
||||
DB: function totalDownloadBytesToday() {
|
||||
const byteSize = StatLog.getSystemStatNum(SysProps.FileDlTodayBytes);
|
||||
return formatByteSize(byteSize, true); // true=withAbbr
|
||||
},
|
||||
NT : function totalNewUsersToday() { // Obv/2
|
||||
NT: function totalNewUsersToday() {
|
||||
// Obv/2
|
||||
return StatLog.getSystemStatNum(SysProps.NewUsersTodayCount);
|
||||
},
|
||||
|
||||
|
@ -383,7 +454,8 @@ const PREDEFINED_MCI_GENERATORS = {
|
|||
return StatLog.getSystemStatNum(SysProps.TotalUserCount) || 1;
|
||||
},
|
||||
|
||||
LC : function lastCallerUserName() { // Obv/2
|
||||
LC: function lastCallerUserName() {
|
||||
// Obv/2
|
||||
const lastLogin = StatLog.getSystemStat(SysProps.LastLogin) || {};
|
||||
return lastLogin.userName || 'N/A';
|
||||
},
|
||||
|
@ -438,7 +510,10 @@ function getPredefinedMCIValue(client, code, extra) {
|
|||
try {
|
||||
value = generator(client, extra);
|
||||
} catch (e) {
|
||||
Log.error( { code : code, exception : e.message }, `Failed generating predefined MCI value (${code})` );
|
||||
Log.error(
|
||||
{ code: code, exception: e.message },
|
||||
`Failed generating predefined MCI value (${code})`
|
||||
);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
'use strict';
|
||||
|
||||
const sysDb = require('./database.js').dbs.system;
|
||||
const {
|
||||
getISOTimestampString
|
||||
} = require('./database.js');
|
||||
const { getISOTimestampString } = require('./database.js');
|
||||
const Errors = require('./enig_error.js');
|
||||
const SysProps = require('./system_property.js');
|
||||
const UserProps = require('./user_property');
|
||||
|
@ -389,8 +387,12 @@ class StatLog {
|
|||
|
||||
const loadStats = {
|
||||
// Not avail on BSD, yet.
|
||||
average : parseFloat(_.get(sysInfo, 'currentLoad.avgLoad', 0).toFixed(2)),
|
||||
current : parseFloat(_.get(sysInfo, 'currentLoad.currentLoad', 0).toFixed(2)),
|
||||
average: parseFloat(
|
||||
_.get(sysInfo, 'currentLoad.avgLoad', 0).toFixed(2)
|
||||
),
|
||||
current: parseFloat(
|
||||
_.get(sysInfo, 'currentLoad.currentLoad', 0).toFixed(2)
|
||||
),
|
||||
};
|
||||
|
||||
this.setNonPersistentSystemStat(SysProps.SystemLoadStats, loadStats);
|
||||
|
@ -403,11 +405,21 @@ class StatLog {
|
|||
_refreshUserStat(client, statName, ttlSeconds) {
|
||||
switch (statName) {
|
||||
case UserProps.NewPrivateMailCount:
|
||||
this._wrapUserRefreshWithCachedTTL(client, statName, this._refreshUserPrivateMailCount, ttlSeconds);
|
||||
this._wrapUserRefreshWithCachedTTL(
|
||||
client,
|
||||
statName,
|
||||
this._refreshUserPrivateMailCount,
|
||||
ttlSeconds
|
||||
);
|
||||
break;
|
||||
|
||||
case UserProps.NewAddressedToMessageCount:
|
||||
this._wrapUserRefreshWithCachedTTL(client, statName, this._refreshUserNewAddressedToMessageCount, ttlSeconds);
|
||||
this._wrapUserRefreshWithCachedTTL(
|
||||
client,
|
||||
statName,
|
||||
this._refreshUserNewAddressedToMessageCount,
|
||||
ttlSeconds
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -427,11 +439,15 @@ class StatLog {
|
|||
|
||||
_refreshUserPrivateMailCount(client) {
|
||||
const MsgArea = require('./message_area');
|
||||
MsgArea.getNewMessageCountInAreaForUser(client.user.userId, Message.WellKnownAreaTags.Private, (err, count) => {
|
||||
MsgArea.getNewMessageCountInAreaForUser(
|
||||
client.user.userId,
|
||||
Message.WellKnownAreaTags.Private,
|
||||
(err, count) => {
|
||||
if (!err) {
|
||||
client.user.setProperty(UserProps.NewPrivateMailCount, count);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_refreshUserNewAddressedToMessageCount(client) {
|
||||
|
@ -454,12 +470,10 @@ class StatLog {
|
|||
|
||||
let sql;
|
||||
if ('count' === filter.resultType) {
|
||||
sql =
|
||||
`SELECT COUNT() AS count
|
||||
sql = `SELECT COUNT() AS count
|
||||
FROM ${logTable}`;
|
||||
} else {
|
||||
sql =
|
||||
`SELECT timestamp, log_value
|
||||
sql = `SELECT timestamp, log_value
|
||||
FROM ${logTable}`;
|
||||
}
|
||||
|
||||
|
@ -475,7 +489,9 @@ class StatLog {
|
|||
|
||||
if (filter.date) {
|
||||
filter.date = moment(filter.date);
|
||||
sql += ` AND DATE(timestamp, "localtime") = DATE("${filter.date.format('YYYY-MM-DD')}")`;
|
||||
sql += ` AND DATE(timestamp, "localtime") = DATE("${filter.date.format(
|
||||
'YYYY-MM-DD'
|
||||
)}")`;
|
||||
}
|
||||
|
||||
if ('count' !== filter.resultType) {
|
||||
|
|
|
@ -217,10 +217,15 @@ exports.getModule = class TelnetBridgeModule extends MenuModule {
|
|||
});
|
||||
|
||||
telnetConnection.on('end', err => {
|
||||
self.client.removeListener('key press', connectionKeyPressHandler);
|
||||
self.client.removeListener(
|
||||
'key press',
|
||||
connectionKeyPressHandler
|
||||
);
|
||||
|
||||
if (err) {
|
||||
self.client.log.warn(`Telnet bridge connection error: ${err.message}`);
|
||||
self.client.log.warn(
|
||||
`Telnet bridge connection error: ${err.message}`
|
||||
);
|
||||
}
|
||||
|
||||
callback(
|
||||
|
|
|
@ -365,16 +365,29 @@ exports.ThemeManager = class ThemeManager {
|
|||
return _.get(theme, `customization.defaults.timeFormat.${style}`, format);
|
||||
},
|
||||
getDateTimeFormat: function (style = 'short') {
|
||||
const format = Config().theme.dateTimeFormat[style] || 'MM/DD/YYYY h:mm a';
|
||||
return _.get(theme, `customization.defaults.dateTimeFormat.${style}`, format);
|
||||
const format =
|
||||
Config().theme.dateTimeFormat[style] || 'MM/DD/YYYY h:mm a';
|
||||
return _.get(
|
||||
theme,
|
||||
`customization.defaults.dateTimeFormat.${style}`,
|
||||
format
|
||||
);
|
||||
},
|
||||
getStatusAvailIndicators: function () {
|
||||
const format = Config().theme.statusAvailableIndicators || ['Y', 'N'];
|
||||
return _.get(theme, 'customization.defaults.statusAvailableIndicators', format);
|
||||
return _.get(
|
||||
theme,
|
||||
'customization.defaults.statusAvailableIndicators',
|
||||
format
|
||||
);
|
||||
},
|
||||
getStatusVisibleIndicators: function () {
|
||||
const format = Config().theme.statusVisibleIndicators || ['Y', 'N'];
|
||||
return _.get(theme, 'customization.defaults.statusVisibleIndicators', format);
|
||||
return _.get(
|
||||
theme,
|
||||
'customization.defaults.statusVisibleIndicators',
|
||||
format
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
18
core/user.js
18
core/user.js
|
@ -75,7 +75,7 @@ module.exports = class User {
|
|||
None: 0x00000000,
|
||||
NotAvailable: 0x00000001, // Not currently available for chat, message, page, etc.
|
||||
NotVisible: 0x00000002, // Invisible -- does not show online, last callers, etc.
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
isAuthenticated() {
|
||||
|
@ -736,21 +736,27 @@ module.exports = class User {
|
|||
if (!cb && _.isFunction(propsList)) {
|
||||
cb = propsList;
|
||||
propsList = [
|
||||
UserProps.RealName, UserProps.Sex, UserProps.EmailAddress,
|
||||
UserProps.Location, UserProps.Affiliations,
|
||||
UserProps.RealName,
|
||||
UserProps.Sex,
|
||||
UserProps.EmailAddress,
|
||||
UserProps.Location,
|
||||
UserProps.Affiliations,
|
||||
];
|
||||
}
|
||||
|
||||
async.waterfall(
|
||||
[
|
||||
(callback) => {
|
||||
callback => {
|
||||
return User.getUserName(userId, callback);
|
||||
},
|
||||
(userName, callback) => {
|
||||
User.loadProperties(userId, { names: propsList }, (err, props) => {
|
||||
return callback(err, Object.assign({}, props, { user_name : userName }));
|
||||
return callback(
|
||||
err,
|
||||
Object.assign({}, props, { user_name: userName })
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
],
|
||||
(err, userProps) => {
|
||||
if (err) {
|
||||
|
|
|
@ -140,20 +140,30 @@ exports.getModule = class UserConfigModule extends MenuModule {
|
|||
return self.prevMenu(cb);
|
||||
}
|
||||
|
||||
self.client.log.info(`User "${self.client.user.username}" updated configuration`);
|
||||
self.client.log.info(
|
||||
`User "${self.client.user.username}" updated configuration`
|
||||
);
|
||||
|
||||
//
|
||||
// New password if it's not empty
|
||||
//
|
||||
if (formData.value.password.length > 0) {
|
||||
self.client.user.setNewAuthCredentials(formData.value.password, err => {
|
||||
self.client.user.setNewAuthCredentials(
|
||||
formData.value.password,
|
||||
err => {
|
||||
if (err) {
|
||||
self.client.log.error( { err : err }, 'Failed storing new authentication credentials');
|
||||
self.client.log.error(
|
||||
{ err: err },
|
||||
'Failed storing new authentication credentials'
|
||||
);
|
||||
} else {
|
||||
self.client.log.info(`User "${self.client.user.username}" updated authentication credentials`);
|
||||
self.client.log.info(
|
||||
`User "${self.client.user.username}" updated authentication credentials`
|
||||
);
|
||||
}
|
||||
return self.prevMenu(cb);
|
||||
});
|
||||
}
|
||||
);
|
||||
} else {
|
||||
return self.prevMenu(cb);
|
||||
}
|
||||
|
|
|
@ -25,13 +25,15 @@ module.exports = class UserInterruptQueue {
|
|||
} else if (opts.omit) {
|
||||
omitNodes = [opts.omit];
|
||||
}
|
||||
omitNodes = omitNodes.map(n => _.isNumber(n) ? n : n.node);
|
||||
omitNodes = omitNodes.map(n => (_.isNumber(n) ? n : n.node));
|
||||
const connOpts = {
|
||||
authUsersOnly: true,
|
||||
visibleOnly: true,
|
||||
availOnly: true,
|
||||
};
|
||||
opts.clients = getActiveConnections(connOpts).filter(ac => !omitNodes.includes(ac.node));
|
||||
opts.clients = getActiveConnections(connOpts).filter(
|
||||
ac => !omitNodes.includes(ac.node)
|
||||
);
|
||||
}
|
||||
if (!Array.isArray(opts.clients)) {
|
||||
opts.clients = [opts.clients];
|
||||
|
|
|
@ -39,7 +39,10 @@ function userLogin(client, username, password, options, cb) {
|
|||
const config = Config();
|
||||
|
||||
if (config.users.badUserNames.includes(username.toLowerCase())) {
|
||||
client.log.info( { username, ip : client.remoteAddress }, `Attempt to login with banned username "${username}"`);
|
||||
client.log.info(
|
||||
{ username, ip: client.remoteAddress },
|
||||
`Attempt to login with banned username "${username}"`
|
||||
);
|
||||
|
||||
// slow down a bit to thwart brute force attacks
|
||||
return setTimeout(() => {
|
||||
|
@ -193,8 +196,13 @@ function recordLogin(client, cb) {
|
|||
StatLog.incrementNonPersistentSystemStat(SysProps.LoginsToday, 1);
|
||||
return StatLog.incrementSystemStat(SysProps.LoginCount, 1, callback);
|
||||
},
|
||||
(callback) => {
|
||||
return StatLog.setUserStat(user, UserProps.LastLoginTs, loginTimestamp, callback);
|
||||
callback => {
|
||||
return StatLog.setUserStat(
|
||||
user,
|
||||
UserProps.LastLoginTs,
|
||||
loginTimestamp,
|
||||
callback
|
||||
);
|
||||
},
|
||||
callback => {
|
||||
return StatLog.incrementUserStat(user, UserProps.LoginCount, 1, callback);
|
||||
|
@ -214,7 +222,7 @@ function recordLogin(client, cb) {
|
|||
callback
|
||||
);
|
||||
},
|
||||
(callback) => {
|
||||
callback => {
|
||||
// Update live last login information which includes additional
|
||||
// (pre-resolved) information such as user name/etc.
|
||||
const lastLogin = {
|
||||
|
@ -231,7 +239,7 @@ function recordLogin(client, cb) {
|
|||
|
||||
StatLog.setNonPersistentSystemStat(SysProps.LastLogin, lastLogin);
|
||||
return callback(null);
|
||||
}
|
||||
},
|
||||
],
|
||||
err => {
|
||||
return cb(err);
|
||||
|
@ -247,6 +255,9 @@ function transformLoginError(err, client, username) {
|
|||
err = Errors.BadLogin('To many failed login attempts', ErrorReasons.TooMany);
|
||||
}
|
||||
|
||||
client.log.warn( { username, ip : client.remoteAddress, reason : err.message }, `Failed login attempt for user "${username}", ${client.friendlyRemoteAddress()}`);
|
||||
client.log.warn(
|
||||
{ username, ip: client.remoteAddress, reason: err.message },
|
||||
`Failed login attempt for user "${username}", ${client.friendlyRemoteAddress()}`
|
||||
);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -114,9 +114,12 @@ function VerticalMenuView(options) {
|
|||
return;
|
||||
}
|
||||
const row = this.position.row + index;
|
||||
this.client.term.rawWrite(`${ansi.goto(row, this.position.col)}${ansi.normal()}${this.fillChar.repeat(this.dimens.width)}`)
|
||||
this.client.term.rawWrite(
|
||||
`${ansi.goto(row, this.position.col)}${ansi.normal()}${this.fillChar.repeat(
|
||||
this.dimens.width
|
||||
)}`
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
util.inherits(VerticalMenuView, MenuView);
|
||||
|
@ -188,15 +191,15 @@ VerticalMenuView.prototype.setFocus = function (focused) {
|
|||
VerticalMenuView.prototype.setFocusItemIndex = function (index) {
|
||||
VerticalMenuView.super_.prototype.setFocusItemIndex.call(this, index); // sets this.focusedItemIndex
|
||||
|
||||
const remainAfterFocus = this.focusItemAtTop ?
|
||||
this.items.length - index :
|
||||
this.items.length;
|
||||
const remainAfterFocus = this.focusItemAtTop
|
||||
? this.items.length - index
|
||||
: this.items.length;
|
||||
if (remainAfterFocus >= this.maxVisibleItems) {
|
||||
const topIndex = (this.focusItemAtTop ? throws.focusedItemIndex : 0) || 0;
|
||||
|
||||
this.viewWindow = {
|
||||
top: topIndex,
|
||||
bottom : Math.min(topIndex + this.maxVisibleItems, this.items.length) - 1
|
||||
bottom: Math.min(topIndex + this.maxVisibleItems, this.items.length) - 1,
|
||||
};
|
||||
|
||||
this.positionCacheExpired = false; // skip standard behavior
|
||||
|
|
|
@ -262,7 +262,9 @@ function ViewController(options) {
|
|||
let submitId;
|
||||
let initialFocusId = 1;
|
||||
|
||||
async.each(Object.keys(config.mci || {}), function entry(mci, nextItem) {
|
||||
async.each(
|
||||
Object.keys(config.mci || {}),
|
||||
function entry(mci, nextItem) {
|
||||
const mciMatch = mci.match(MCI_REGEXP); // :TODO: How to handle auto-generated IDs????
|
||||
if (null === mciMatch) {
|
||||
self.client.log.warn({ mci: mci }, 'Unable to parse MCI code');
|
||||
|
@ -306,7 +308,8 @@ function ViewController(options) {
|
|||
}
|
||||
|
||||
return cb(err, { initialFocusId: initialFocusId });
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// method for comparing submitted form data to configuration entries
|
||||
|
|
151
core/wfc.js
151
core/wfc.js
|
@ -2,10 +2,7 @@
|
|||
const { MenuModule } = require('./menu_module');
|
||||
const stringFormat = require('./string_format');
|
||||
|
||||
const {
|
||||
getActiveConnectionList,
|
||||
AllConnections
|
||||
} = require('./client_connections');
|
||||
const { getActiveConnectionList, AllConnections } = require('./client_connections');
|
||||
const StatLog = require('./stat_log');
|
||||
const SysProps = require('./system_property');
|
||||
const UserProps = require('./user_property');
|
||||
|
@ -37,7 +34,7 @@ const MciViewIds = {
|
|||
nodeStatusSelection: 3,
|
||||
|
||||
customRangeStart: 10,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Secure + 2FA + root user + 'wfc' group.
|
||||
|
@ -49,7 +46,9 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
this.config = Object.assign({}, _.get(options, 'menuConfig.config'), { extraArgs : options.extraArgs });
|
||||
this.config = Object.assign({}, _.get(options, 'menuConfig.config'), {
|
||||
extraArgs: options.extraArgs,
|
||||
});
|
||||
|
||||
this.config.acs = this.config.acs || DefaultACS;
|
||||
if (!this.config.acs.includes('SC')) {
|
||||
|
@ -89,19 +88,19 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
this._selectNodeByIndex(nodeStatusView, this.selectedNodeStatusIndex);
|
||||
}
|
||||
return cb(null);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
initSequence() {
|
||||
async.series(
|
||||
[
|
||||
(callback) => {
|
||||
callback => {
|
||||
return this.beforeArt(callback);
|
||||
},
|
||||
(callback) => {
|
||||
callback => {
|
||||
return this._displayMainPage(false, callback);
|
||||
}
|
||||
},
|
||||
],
|
||||
() => {
|
||||
this.finishedLoading();
|
||||
|
@ -112,7 +111,7 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
_displayMainPage(clearScreen, cb) {
|
||||
async.series(
|
||||
[
|
||||
(callback) => {
|
||||
callback => {
|
||||
return this.displayArtAndPrepViewController(
|
||||
'main',
|
||||
FormIds.main,
|
||||
|
@ -120,34 +119,49 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
callback
|
||||
);
|
||||
},
|
||||
(callback) => {
|
||||
const quickLogView = this.getView('main', MciViewIds.main.quickLogView);
|
||||
callback => {
|
||||
const quickLogView = this.getView(
|
||||
'main',
|
||||
MciViewIds.main.quickLogView
|
||||
);
|
||||
if (!quickLogView) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
if (!this.logRingBuffer) {
|
||||
const logLevel = this.config.quickLogLevel || // WFC specific
|
||||
const logLevel =
|
||||
this.config.quickLogLevel || // WFC specific
|
||||
_.get(Config(), 'logging.rotatingFile.level') || // ...or system setting
|
||||
'info'; // ...or default to info
|
||||
|
||||
this.logRingBuffer = new bunyan.RingBuffer({ limit : quickLogView.dimens.height || 24 });
|
||||
this.logRingBuffer = new bunyan.RingBuffer({
|
||||
limit: quickLogView.dimens.height || 24,
|
||||
});
|
||||
Log.log.addStream({
|
||||
name: 'wfc-ringbuffer',
|
||||
type: 'raw',
|
||||
level: logLevel,
|
||||
stream : this.logRingBuffer
|
||||
stream: this.logRingBuffer,
|
||||
});
|
||||
}
|
||||
|
||||
const nodeStatusView = this.getView('main', MciViewIds.main.nodeStatus);
|
||||
const nodeStatusSelectionView = this.getView('main', MciViewIds.main.nodeStatusSelection);
|
||||
const nodeStatusSelectionFormat = this.config.nodeStatusSelectionFormat || '{text}';
|
||||
const nodeStatusView = this.getView(
|
||||
'main',
|
||||
MciViewIds.main.nodeStatus
|
||||
);
|
||||
const nodeStatusSelectionView = this.getView(
|
||||
'main',
|
||||
MciViewIds.main.nodeStatusSelection
|
||||
);
|
||||
const nodeStatusSelectionFormat =
|
||||
this.config.nodeStatusSelectionFormat || '{text}';
|
||||
if (nodeStatusView && nodeStatusSelectionView) {
|
||||
nodeStatusView.on('index update', index => {
|
||||
const item = nodeStatusView.getItems()[index];
|
||||
if (item) {
|
||||
nodeStatusSelectionView.setText(stringFormat(nodeStatusSelectionFormat, item));
|
||||
nodeStatusSelectionView.setText(
|
||||
stringFormat(nodeStatusSelectionFormat, item)
|
||||
);
|
||||
// :TODO: Update view
|
||||
// :TODO: this is not triggered by key-presses (1, 2, ...) -- we need to handle that as well
|
||||
}
|
||||
|
@ -156,9 +170,9 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
|
||||
return callback(null);
|
||||
},
|
||||
(callback) => {
|
||||
callback => {
|
||||
return this._refreshAll(callback);
|
||||
}
|
||||
},
|
||||
],
|
||||
err => {
|
||||
if (!err) {
|
||||
|
@ -172,15 +186,11 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
_displayHelpPage(cb) {
|
||||
this._stopRefreshing();
|
||||
|
||||
this.displayAsset(
|
||||
this.menuConfig.config.art.help,
|
||||
{ clearScreen : true },
|
||||
() => {
|
||||
this.displayAsset(this.menuConfig.config.art.help, { clearScreen: true }, () => {
|
||||
this.client.waitForKeyPress(() => {
|
||||
return this._displayMainPage(true, cb);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
enter() {
|
||||
|
@ -207,11 +217,15 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
|
||||
const vis = this.config.opVisibility || 'current';
|
||||
switch (vis) {
|
||||
case 'hidden' : this.client.user.setVisibility(false); break;
|
||||
case 'visible' : this.client.user.setVisibility(true); break;
|
||||
default : break;
|
||||
case 'hidden':
|
||||
this.client.user.setVisibility(false);
|
||||
break;
|
||||
case 'visible':
|
||||
this.client.user.setVisibility(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_restoreOpVisibility() {
|
||||
|
@ -238,23 +252,23 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
_refreshAll(cb) {
|
||||
async.series(
|
||||
[
|
||||
(callback) => {
|
||||
callback => {
|
||||
return this._refreshStats(callback);
|
||||
},
|
||||
(callback) => {
|
||||
callback => {
|
||||
return this._refreshNodeStatus(callback);
|
||||
},
|
||||
(callback) => {
|
||||
callback => {
|
||||
return this._refreshQuickLog(callback);
|
||||
},
|
||||
(callback) => {
|
||||
callback => {
|
||||
this.updateCustomViewTextsWithFilter(
|
||||
'main',
|
||||
MciViewIds.main.customRangeStart,
|
||||
this.stats
|
||||
);
|
||||
return callback(null);
|
||||
}
|
||||
},
|
||||
],
|
||||
err => {
|
||||
if (cb) {
|
||||
|
@ -265,16 +279,16 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
}
|
||||
|
||||
_getStatusStrings(isAvailable, isVisible) {
|
||||
const availIndicators = Array.isArray(this.config.statusAvailableIndicators) ?
|
||||
this.config.statusAvailableIndicators :
|
||||
this.client.currentTheme.helpers.getStatusAvailableIndicators();
|
||||
const visIndicators = Array.isArray(this.config.statusVisibleIndicators) ?
|
||||
this.config.statusVisibleIndicators :
|
||||
this.client.currentTheme.helpers.getStatusVisibleIndicators();
|
||||
const availIndicators = Array.isArray(this.config.statusAvailableIndicators)
|
||||
? this.config.statusAvailableIndicators
|
||||
: this.client.currentTheme.helpers.getStatusAvailableIndicators();
|
||||
const visIndicators = Array.isArray(this.config.statusVisibleIndicators)
|
||||
? this.config.statusVisibleIndicators
|
||||
: this.client.currentTheme.helpers.getStatusVisibleIndicators();
|
||||
|
||||
return [
|
||||
isAvailable ? (availIndicators[1] || 'Y') : (availIndicators[0] || 'N'),
|
||||
isVisible ? (visIndicators[1] || 'Y') : (visIndicators[0] || 'N'),
|
||||
isAvailable ? availIndicators[1] || 'Y' : availIndicators[0] || 'N',
|
||||
isVisible ? visIndicators[1] || 'Y' : visIndicators[0] || 'N',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -287,7 +301,8 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
const now = moment();
|
||||
|
||||
const [availIndicator, visIndicator] = this._getStatusStrings(
|
||||
this.client.user.isAvailable(), this.client.user.isVisible()
|
||||
this.client.user.isAvailable(),
|
||||
this.client.user.isVisible()
|
||||
);
|
||||
|
||||
this.stats = {
|
||||
|
@ -322,20 +337,32 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
|
||||
// Current
|
||||
currentUserName: this.client.user.username,
|
||||
currentUserRealName : this.client.user.getProperty(UserProps.RealName) || this.client.user.username,
|
||||
currentUserRealName:
|
||||
this.client.user.getProperty(UserProps.RealName) ||
|
||||
this.client.user.username,
|
||||
availIndicator: availIndicator,
|
||||
visIndicator: visIndicator,
|
||||
lastLoginUserName: lastLoginStats.userName,
|
||||
lastLoginRealName: lastLoginStats.realName,
|
||||
lastLoginDate: moment(lastLoginStats.timestamp).format(this.getDateFormat()),
|
||||
lastLoginTime: moment(lastLoginStats.timestamp).format(this.getTimeFormat()),
|
||||
lastLogin : moment(lastLoginStats.timestamp).format(this._dateTimeFormat('lastLogin')),
|
||||
lastLogin: moment(lastLoginStats.timestamp).format(
|
||||
this._dateTimeFormat('lastLogin')
|
||||
),
|
||||
totalMemoryBytes: sysMemStats.totalBytes || 0,
|
||||
freeMemoryBytes: sysMemStats.freeBytes || 0,
|
||||
systemAvgLoad: sysLoadStats.average || 0,
|
||||
systemCurrentLoad: sysLoadStats.current || 0,
|
||||
newPrivateMail : StatLog.getUserStatNumByClient(this.client, UserProps.NewPrivateMailCount, MailCountTTLSeconds),
|
||||
newMessagesAddrTo : StatLog.getUserStatNumByClient(this.client, UserProps.NewAddressedToMessageCount, MailCountTTLSeconds),
|
||||
newPrivateMail: StatLog.getUserStatNumByClient(
|
||||
this.client,
|
||||
UserProps.NewPrivateMailCount,
|
||||
MailCountTTLSeconds
|
||||
),
|
||||
newMessagesAddrTo: StatLog.getUserStatNumByClient(
|
||||
this.client,
|
||||
UserProps.NewAddressedToMessageCount,
|
||||
MailCountTTLSeconds
|
||||
),
|
||||
};
|
||||
|
||||
return cb(null);
|
||||
|
@ -368,7 +395,10 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
ac.action = 'Logging In';
|
||||
}
|
||||
|
||||
const [availIndicator, visIndicator] = this._getStatusStrings(ac.isAvailable, ac.isVisible);
|
||||
const [availIndicator, visIndicator] = this._getStatusStrings(
|
||||
ac.isAvailable,
|
||||
ac.isVisible
|
||||
);
|
||||
|
||||
const timeOn = ac.timeOn || moment.duration(0);
|
||||
|
||||
|
@ -389,7 +419,9 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
}
|
||||
|
||||
_refreshQuickLog(cb) {
|
||||
const quickLogView = this.viewControllers.main.getView(MciViewIds.main.quickLogView);
|
||||
const quickLogView = this.viewControllers.main.getView(
|
||||
MciViewIds.main.quickLogView
|
||||
);
|
||||
if (!quickLogView) {
|
||||
return cb(null);
|
||||
}
|
||||
|
@ -407,11 +439,9 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
}
|
||||
|
||||
const quickLogTimestampFormat =
|
||||
this.config.quickLogTimestampFormat ||
|
||||
this.getDateTimeFormat('short');
|
||||
this.config.quickLogTimestampFormat || this.getDateTimeFormat('short');
|
||||
|
||||
const levelIndicators = this.config.quickLogLevelIndicators ||
|
||||
{
|
||||
const levelIndicators = this.config.quickLogLevelIndicators || {
|
||||
trace: 'T',
|
||||
debug: 'D',
|
||||
info: 'I',
|
||||
|
@ -420,12 +450,12 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
fatal: 'F',
|
||||
};
|
||||
|
||||
|
||||
const makeLevelIndicator = (level) => {
|
||||
const makeLevelIndicator = level => {
|
||||
return levelIndicators[level] || '?';
|
||||
};
|
||||
|
||||
const quickLogLevelMessagePrefixes = this.config.quickLogLevelMessagePrefixes || {};
|
||||
const quickLogLevelMessagePrefixes =
|
||||
this.config.quickLogLevelMessagePrefixes || {};
|
||||
const prefixMssage = (message, level) => {
|
||||
const prefix = quickLogLevelMessagePrefixes[level] || '';
|
||||
return `${prefix}${message}`;
|
||||
|
@ -454,4 +484,3 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
|||
return format || this.getDateFormat();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
const { MenuModule } = require('./menu_module.js');
|
||||
const {
|
||||
getActiveConnectionList,
|
||||
UserVisibleConnections } = require('./client_connections.js');
|
||||
UserVisibleConnections,
|
||||
} = require('./client_connections.js');
|
||||
const { Errors } = require('./enig_error.js');
|
||||
|
||||
// deps
|
||||
|
@ -51,8 +52,13 @@ exports.getModule = class WhosOnlineModule extends MenuModule {
|
|||
);
|
||||
}
|
||||
|
||||
const onlineList = getActiveConnectionList(UserVisibleConnections).slice(0, onlineListView.height).map(
|
||||
oe => Object.assign(oe, { text : oe.userName, timeOn : _.upperFirst(oe.timeOn.humanize()) })
|
||||
const onlineList = getActiveConnectionList(UserVisibleConnections)
|
||||
.slice(0, onlineListView.height)
|
||||
.map(oe =>
|
||||
Object.assign(oe, {
|
||||
text: oe.userName,
|
||||
timeOn: _.upperFirst(oe.timeOn.humanize()),
|
||||
})
|
||||
);
|
||||
|
||||
onlineListView.setItems(onlineList);
|
||||
|
|
Loading…
Reference in New Issue