Merge branch '280-config-revamp' of github.com:NuSkooler/enigma-bbs into 280-config-revamp
This commit is contained in:
commit
848d1f02b0
|
@ -3,7 +3,7 @@ For :bug: bug reports, please fill out the information below plus any additional
|
|||
**Short problem description**
|
||||
|
||||
**Environment**
|
||||
- [ ] I am using Node.js v10.x LTS or higher
|
||||
- [ ] I am using Node.js v12.x LTS or higher
|
||||
- [ ] `npm install` or `yarn` reports success
|
||||
- Actual Node.js version (`node --version`):
|
||||
- Operating system (`uname -a` on *nix systems):
|
||||
|
|
25
UPGRADE.md
25
UPGRADE.md
|
@ -2,29 +2,17 @@
|
|||
This document covers basic upgrade notes for major ENiGMA½ version updates.
|
||||
|
||||
# Before Upgrading
|
||||
* Always back up your system!
|
||||
* Always back up your system! (See [Administration](/docs/admin/administration.md))
|
||||
* Seriously, always back up your system!
|
||||
* At least back up the `db` directory and your `menu.hjson` (or renamed equivalent)
|
||||
|
||||
# General Notes
|
||||
## Configuration File Updates
|
||||
In general, look at the `menu_template.in.hjson`, and `config_template.in.hjson` as well as the default `luciano_blocktronics/theme.hjson` files when you update. These files may come with new sections you wish to merge into your system!
|
||||
In general, look at template menu files in `misc/menu_templates`, and `config_template.in.hjson` as well as the default `luciano_blocktronics/theme.hjson` files when you update. These files may come with new sections you wish to merge into your system!
|
||||
|
||||
### menu.hjson
|
||||
Upgrades often come with changes to the default `menu_template.in.hjson`. It is wise to use a *different* file name for your BBS's version of this file and point to it via `config.hjson`. For example:
|
||||
|
||||
```hjson
|
||||
general: {
|
||||
menuFile: my_bbs.hjson
|
||||
}
|
||||
```
|
||||
|
||||
After updating code, use a program such as DiffMerge to merge in updates to
|
||||
`my_bbs.hjson` from the shipping `menu.hjson`.
|
||||
|
||||
### theme.hjson
|
||||
Any custom themes you have created may now be missing features as well. Take a look at the default `luciano_blocktronics/theme.hjson` file. You can use missing sections in your `theme.hjson` (which will generally correspond to sections you've also merged in to your `menu.hjson`).
|
||||
### Menus & Theme Updates
|
||||
Upgrades often come with changes to the default menu templates found in `misc/menu_tempaltes`. You can use these as references for changes and additions to the default menu sets. This also applies to the default `luciano_blocktronics` theme and it's `theme.hjson` file.
|
||||
|
||||
See [Updating](/docs/admin/updating.md) for details on menu files/etc.
|
||||
|
||||
# Upgrading the Code
|
||||
Upgrading from GitHub is easy:
|
||||
|
@ -33,7 +21,7 @@ Upgrading from GitHub is easy:
|
|||
cd /path/to/enigma-bbs
|
||||
git pull
|
||||
rm -rf npm_modules # do this any time you update Node.js itself
|
||||
npm install
|
||||
npm install # or simply 'yarn'
|
||||
```
|
||||
|
||||
# Problems
|
||||
|
@ -42,6 +30,7 @@ Report your issue on Xibalba BBS, hop in #enigma-bbs on FreeNode and chat, or
|
|||
|
||||
# 0.0.11-beta to 0.0.12-beta
|
||||
* Be aware that `master` is now mainline! This means all `git pull`'s will yield the latest version. See [WHATSNEW](WHATSNEW.md) for more information.
|
||||
* There is no longer a `prompt.hjson` file. Prompts are simply part of the menu set in the `prompts` section.
|
||||
|
||||
# 0.0.10-alpha to 0.0.11-beta
|
||||
* Node.js 12.x LTS is now in use. Follow standard Node.js upgrade procedures (e.g.: `nvm install 12 && nvm use 12`).
|
||||
|
|
|
@ -5,7 +5,9 @@ This document attempts to track **major** changes and additions in ENiGMA½. For
|
|||
* The `master` branch has become mainline. What this means to users is `git pull` will always give you the latest and greatest. Make sure to read [Updating](/docs/admin/updating.md) and keep an eye on `WHATSNEW.md` (this file) and [UPGRADE](UPGRADE.md)! See also [ticket #276](https://github.com/NuSkooler/enigma-bbs/issues/276).
|
||||
* The default configuration has been moved to [config_default.js](/core/config_default.js).
|
||||
* A full configuration revamp has taken place. Configuration files such as `config.hjson`, `menu.hjson`, and `theme.hjson` can now utilize includes via the `includes` directive, reference 'self' sections using `@reference:` and import environment variables with `@environment`.
|
||||
* An explicit prompt file previously specified by `general.promptFile` in `config.hjson` is no longer necessary. Instead, this now simply part of the `prompts` section in `menu.hjson`. The default setup still creates a separate prompt HJSON file, but it is `includes`ed in `menu.hjson`.
|
||||
* An explicit prompt file previously specified by `general.promptFile` in `config.hjson` is no longer necessary. Instead, this now simply part of the `prompts` section in `menu.hjson`. The default setup still creates a separate prompt HJSON file, but it is `includes`ed in `menu.hjson`. With the removal of prompts the `PromptsChanged` event will no longer be fired.
|
||||
* New `PV` ACS check for arbitrary user properties. See [ACS](/docs/configuration/acs.md) for details.
|
||||
* The `message` arg used by `msg_list` has been deprecated. Please starting using `messageIndex` for this purpose. Support for `message` will be removed in the future.
|
||||
|
||||
## 0.0.11-beta
|
||||
* Upgraded from `alpha` to `beta` -- The software is far along and mature enough at this point!
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
author: Luciano Ayres
|
||||
group: blocktronics
|
||||
enabled: true
|
||||
|
||||
//
|
||||
// Also check out Luciano's ANSIGARDEN:
|
||||
// http://www.ansigarden.com/
|
||||
//
|
||||
}
|
||||
|
||||
customization: {
|
||||
|
@ -241,7 +246,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
messageAreaMessageList: {
|
||||
messageBaseMessageList: {
|
||||
config: {
|
||||
dateTimeFormat: ddd MMM Do
|
||||
allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}"
|
||||
|
@ -250,13 +255,13 @@
|
|||
VM1: {
|
||||
height: 14
|
||||
width: 70
|
||||
itemFormat: "|00|15{msgNum:>4} |03{subject:<28.27} |11{fromUserName:<20.20} |03{ts} |15{newIndicator}"
|
||||
focusItemFormat: "|00|19|15{msgNum:>4} {subject:<28.27} {fromUserName:<20.20} {ts} {newIndicator}"
|
||||
itemFormat: "|00|15{msgNum:>4} |03{subject:<28.27} |11{fromUserName:<20.20} |03{ts:<15.16} |15{newIndicator}"
|
||||
focusItemFormat: "|00|19|15{msgNum:>4} {subject:<28.27} {fromUserName:<20.20} {ts:<15.16} {newIndicator}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageAreaChangeCurrentConference: {
|
||||
messageBaseChangeCurrentConference: {
|
||||
mci: {
|
||||
VM1: {
|
||||
width: 26
|
||||
|
@ -267,7 +272,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
messageAreaChangeCurrentArea: {
|
||||
messageBaseChangeCurrentArea: {
|
||||
mci: {
|
||||
VM1: {
|
||||
width: 26
|
||||
|
@ -278,7 +283,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
messageAreaSetNewScanDate: {
|
||||
messageBaseSetNewScanDate: {
|
||||
mci: {
|
||||
SM2: {
|
||||
width: 54
|
||||
|
@ -299,7 +304,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
mailMenuCreateMessage: {
|
||||
privateMailMenuCreateMessage: {
|
||||
0: {
|
||||
mci: {
|
||||
TL1: { width: 19, textOverflow: "..." }
|
||||
|
@ -314,7 +319,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
mailMenuInbox: {
|
||||
privateMailMenuInbox: {
|
||||
config: {
|
||||
dateTimeFormat: ddd MMM Do
|
||||
allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}"
|
||||
|
@ -500,7 +505,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
messageAreaSearchMessageList: {
|
||||
messageBaseSearchMessageList: {
|
||||
config: {
|
||||
allViewsInfoFormat10: "|00|15{msgNumSelected:>4.4} |08/ |15{msgNumTotal:<4.4}"
|
||||
// Fri Sep 25th
|
||||
|
@ -516,7 +521,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
messageAreaMyMessagesList: {
|
||||
messageBaseMyMessagesList: {
|
||||
config: {
|
||||
// Fri Sep 25th
|
||||
dateTimeFormat: ddd MMM Do
|
||||
|
@ -531,6 +536,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// The 'msg_list' module looks for this entry by default
|
||||
messageAreaViewPost: {
|
||||
0: {
|
||||
mci: {
|
||||
|
@ -566,7 +572,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
messageAreaNewPost: {
|
||||
messageBaseNewPost: {
|
||||
0: {
|
||||
mci: {
|
||||
TL1: { width: 19, textOverflow: "..." }
|
||||
|
@ -582,7 +588,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
messageAreaReplyPost: {
|
||||
messageBaseReplyPost: {
|
||||
0: {
|
||||
mci: {
|
||||
TL1: { width: 19, textOverflow: "..." }
|
||||
|
@ -977,7 +983,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
fileAreaFilterEditor: {
|
||||
fileBaseFilterEditor: {
|
||||
mci: {
|
||||
ET1: {
|
||||
width: 26
|
||||
|
|
|
@ -1055,6 +1055,14 @@ function peg$parse(input, options) {
|
|||
}
|
||||
const points = user.getPropertyAsNumber(UserProps.AchievementTotalPoints) || 0;
|
||||
return !isNan(value) && points >= value;
|
||||
},
|
||||
PV : function userPropValue() {
|
||||
if (!user || !Array.isArray(value) || value.length !== 2) {
|
||||
return false;
|
||||
}
|
||||
const [propName, propValue] = value;
|
||||
const actualPropValue = user.getProperty(propName);
|
||||
return actualPropValue === propValue;
|
||||
}
|
||||
}[acsCode](value);
|
||||
} catch (e) {
|
||||
|
|
|
@ -12,7 +12,12 @@ exports.Config = class Config extends ConfigLoader {
|
|||
super(options);
|
||||
}
|
||||
|
||||
static create(baseConfigPath, cb) {
|
||||
static create(baseConfigPath, options, cb) {
|
||||
if (!cb && _.isFunction(options)) {
|
||||
cb = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
const replacePaths = [
|
||||
'loginServers.ssh.algorithms.kex',
|
||||
'loginServers.ssh.algorithms.cipher',
|
||||
|
@ -24,7 +29,7 @@ exports.Config = class Config extends ConfigLoader {
|
|||
'args', 'sendArgs', 'recvArgs', 'recvArgsNonBatch',
|
||||
];
|
||||
|
||||
const options = {
|
||||
const configOptions = Object.assign({}, options, {
|
||||
defaultConfig : DefaultConfig,
|
||||
defaultsCustomizer : (defaultVal, configVal, key, path) => {
|
||||
if (Array.isArray(defaultVal) && Array.isArray(configVal)) {
|
||||
|
@ -43,9 +48,9 @@ exports.Config = class Config extends ConfigLoader {
|
|||
Events.emit(Events.getSystemEvents().ConfigChanged);
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
systemConfigInstance = new Config(options);
|
||||
systemConfigInstance = new Config(configOptions);
|
||||
systemConfigInstance.init(baseConfigPath, err => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
|
|
|
@ -13,12 +13,14 @@ module.exports = class ConfigLoader {
|
|||
defaultConfig = {},
|
||||
defaultsCustomizer = null,
|
||||
onReload = null,
|
||||
keepWsc = false,
|
||||
} =
|
||||
{
|
||||
hotReload : true,
|
||||
defaultConfig : {},
|
||||
defaultsCustomizer : null,
|
||||
onReload : null,
|
||||
keepWsc : false,
|
||||
}
|
||||
)
|
||||
{
|
||||
|
@ -28,6 +30,7 @@ module.exports = class ConfigLoader {
|
|||
this.defaultConfig = defaultConfig;
|
||||
this.defaultsCustomizer = defaultsCustomizer;
|
||||
this.onReload = onReload;
|
||||
this.keepWsc = keepWsc;
|
||||
}
|
||||
|
||||
init(baseConfigPath, cb) {
|
||||
|
@ -158,7 +161,8 @@ module.exports = class ConfigLoader {
|
|||
|
||||
let value = process.env[varName];
|
||||
if (!value) {
|
||||
return;
|
||||
// console is about as good as we can do here
|
||||
return console.info(`WARNING: environment variable "${varName}" from spec "${spec}" not found!`);
|
||||
}
|
||||
|
||||
if ('array' === array) {
|
||||
|
@ -176,6 +180,7 @@ module.exports = class ConfigLoader {
|
|||
const options = {
|
||||
filePath,
|
||||
hotReload : this.hotReload,
|
||||
keepWsc : this.keepWsc,
|
||||
callback : this._configFileChanged.bind(this),
|
||||
};
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ const paths = require('path');
|
|||
exports.getConfigPath = getConfigPath;
|
||||
|
||||
function getConfigPath(filePath) {
|
||||
// |filePath| is assumed to be in the config path if it's only a file name
|
||||
if('.' === paths.dirname(filePath)) {
|
||||
filePath = paths.join(Config().paths.config, filePath);
|
||||
}
|
||||
if (paths.isAbsolute(filePath)) {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
return paths.join(Config().paths.config, filePath);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ function getMenuConfig(client, name, cb) {
|
|||
menuConfig.promptConfig = client.currentTheme.prompts[menuConfig.prompt];
|
||||
return callback(null, menuConfig);
|
||||
}
|
||||
return callback(Error.DoesNotExist(`No prompt entry for "${menuConfig.prompt}"`));
|
||||
return callback(Errors.DoesNotExist(`No prompt entry for "${menuConfig.prompt}"`));
|
||||
}
|
||||
return callback(null, menuConfig);
|
||||
}
|
||||
|
|
|
@ -60,13 +60,14 @@ exports.getModule = class MessageListModule extends MessageAreaConfTempSwitcher(
|
|||
this.menuMethods = {
|
||||
selectMessage : (formData, extraArgs, cb) => {
|
||||
if(MciViewIds.allViews.msgList === formData.submitId) {
|
||||
this.initialFocusIndex = formData.value.message;
|
||||
// 'messageIndex' or older deprecated 'message' member
|
||||
this.initialFocusIndex = _.get(formData, 'value.messageIndex', formData.value.message);
|
||||
|
||||
const modOpts = {
|
||||
extraArgs : {
|
||||
messageAreaTag : this.getSelectedAreaTag(formData.value.message),
|
||||
messageAreaTag : this.getSelectedAreaTag(this.initialFocusIndex),
|
||||
messageList : this.config.messageList,
|
||||
messageIndex : formData.value.message,
|
||||
messageIndex : this.initialFocusIndex,
|
||||
lastMessageNextExit : true,
|
||||
}
|
||||
};
|
||||
|
@ -107,7 +108,9 @@ exports.getModule = class MessageListModule extends MessageAreaConfTempSwitcher(
|
|||
if(MciViewIds.allViews.msgList != formData.submitId) {
|
||||
return cb(null);
|
||||
}
|
||||
const messageIndex = _.get(formData, 'value.message');
|
||||
|
||||
// newer 'messageIndex' or older deprecated value
|
||||
const messageIndex = _.get(formData, 'value.messageIndex', formData.value.message);
|
||||
return this.promptDeleteMessageConfirm(messageIndex, cb);
|
||||
},
|
||||
deleteMessageYes : (formData, extraArgs, cb) => {
|
||||
|
|
|
@ -64,14 +64,14 @@ function getDefaultConfigPath() {
|
|||
}
|
||||
|
||||
function getConfigPath() {
|
||||
const baseConfigPath = argv.config ? argv.config : config.getDefaultPath();
|
||||
const baseConfigPath = argv.config ? argv.config : config.Config.getDefaultPath();
|
||||
return baseConfigPath + 'config.hjson';
|
||||
}
|
||||
|
||||
function initConfig(cb) {
|
||||
const configPath = getConfigPath();
|
||||
|
||||
config.init(configPath, { keepWsc : true, hotReload : false }, cb);
|
||||
config.Config.create(configPath, { keepWsc : true, hotReload : false }, cb);
|
||||
}
|
||||
|
||||
function initConfigAndDatabases(cb) {
|
||||
|
|
|
@ -227,26 +227,44 @@ function buildNewConfig() {
|
|||
if(err) { return;
|
||||
}
|
||||
|
||||
const bn = sanatizeFilename(config.general.boardName)
|
||||
const boardName = sanatizeFilename(config.general.boardName)
|
||||
.replace(/[^a-z0-9_-]/ig, '_')
|
||||
.replace(/_+/g, '_')
|
||||
.toLowerCase();
|
||||
const menuFile = `${bn}-menu.hjson`;
|
||||
|
||||
const includeFilesIn = [
|
||||
'message_base.in.hjson',
|
||||
'private_mail.in.hjson',
|
||||
'login.in.hjson',
|
||||
'new_user.in.hjson',
|
||||
'doors.in.hjson',
|
||||
'file_base.in.hjson',
|
||||
];
|
||||
|
||||
let includeFiles = [];
|
||||
includeFilesIn.forEach(incFile => {
|
||||
const outName = `${boardName}-${incFile.replace('.in', '')}`;
|
||||
includeFiles.push(outName);
|
||||
|
||||
copyFileSyncSilent(
|
||||
paths.join(__dirname, '../../misc/menu_template.in.hjson'),
|
||||
paths.join(__dirname, '../../config/', menuFile),
|
||||
paths.join(__dirname, '../../misc/menu_templates', incFile),
|
||||
paths.join(__dirname, '../../config/menus', outName),
|
||||
fs.constants.COPYFILE_EXCL
|
||||
);
|
||||
});
|
||||
|
||||
const promptFile = `${bn}-prompt.hjson`;
|
||||
copyFileSyncSilent(
|
||||
paths.join(__dirname, '../../misc/prompt_template.in.hjson'),
|
||||
paths.join(__dirname, '../../config/', promptFile),
|
||||
fs.constants.COPYFILE_EXCL
|
||||
// We really only need includes to be replaced
|
||||
const mainTemplate = fs.readFileSync(paths.join(__dirname, '../../misc/menu_templates/main.in.hjson'), 'utf8')
|
||||
.replace(/%INCLUDE_FILES%/g, includeFiles.join('\n\t\t')); // cheesy, but works!
|
||||
|
||||
const menuFile = `${boardName}-main.hjson`;
|
||||
fs.writeFileSync(
|
||||
paths.join(__dirname, '../../config/menus', menuFile),
|
||||
mainTemplate,
|
||||
'utf8'
|
||||
);
|
||||
|
||||
config.general.menuFile = menuFile;
|
||||
config.general.promptFile = promptFile;
|
||||
config.general.menuFile = paths.join(__dirname, '../../config/menus/', menuFile);
|
||||
|
||||
if(writeConfig(config, configPath)) {
|
||||
console.info('Configuration generated');
|
||||
|
|
|
@ -121,7 +121,7 @@ exports.ThemeManager = class ThemeManager {
|
|||
onReload : err => {
|
||||
if (!err) {
|
||||
// this particular theme has changed
|
||||
this._themeLoaded(themeId, err => {
|
||||
this._themeLoaded(themeId, themeConfig, err => {
|
||||
if (!err) {
|
||||
Events.emit(
|
||||
Events.getSystemEvents().ThemeChanged,
|
||||
|
|
|
@ -171,7 +171,7 @@ exports.getModule = class UserConfigModule extends MenuModule {
|
|||
},
|
||||
function prepareAvailableThemes(callback) {
|
||||
self.availThemeInfo = _.sortBy([...theme.getAvailableThemes()].map(entry => {
|
||||
const theme = entry[1];
|
||||
const theme = entry[1].get();
|
||||
return {
|
||||
themeId : theme.info.themeId,
|
||||
name : theme.info.name,
|
||||
|
|
|
@ -39,6 +39,7 @@ The following are ACS codes available as of this writing:
|
|||
| AP<i>achievementPoints</i> | User has >= _achievementPoints_ achievement points |
|
||||
| AF<i>authFactor</i> | User's current *Authentication Factor* is >= _authFactor_. Authentication factor 1 refers to username + password (or PubKey) while factor 2 refers to 2FA such as One-Time-Password authentication. |
|
||||
| AR<i>authFactorReq</i> | Current user **requires** an Authentication Factor >= _authFactorReq_ |
|
||||
| PV[_name,_value_] | Checks that the property by _name_ for the current user is exactly _value_. This ACS allows arbitrary user property values to be checked. For example, `PV[message_conf,local]` checks that the user is currently in the "local" message conference.
|
||||
|
||||
## ACS Strings
|
||||
ACS strings are one or more ACS codes in addition to some basic language semantics.
|
||||
|
|
|
@ -24,12 +24,12 @@ The following archivers are pre-configured in ENiGMA½ as of this writing. Remem
|
|||
#### Lha
|
||||
* Formats: <a href="https://en.wikipedia.org/wiki/LHA_(file_format)">LHA</a> files such as .lzh.
|
||||
* Key: `Lha`
|
||||
* Homepage/package: `lhasa` on most UNIX-like environments. See also https://fragglet.github.io/lhasa/ and http://www2m.biglobe.ne.jp/~dolphin/lha/lha-unix.htm
|
||||
* Homepage/package: `lhasa` on most UNIX-like environments. See also https://fragglet.github.io/lhasa/ and https://web.archive.org/web/20191023045303/http://www2m.biglobe.ne.jp/~dolphin/lha/lha-unix.htm
|
||||
|
||||
#### Lzx
|
||||
* Formats: <a href="https://en.wikipedia.org/wiki/LZX_(algorithm)#Amiga_LZX">Amiga LZX</a>
|
||||
* Key: `Lzx`
|
||||
* Homepage/package: `unlzx` under most UNIX-like platforms ([Debian/Ubuntu](https://launchpad.net/~rzr/+archive/ubuntu/ppa/+build/2486127), [RedHat](https://fedora.pkgs.org/28/rpm-sphere/unlzx-1.1-4.1.x86_64.rpm.html), [Source](http://xavprods.free.fr/lzx/))
|
||||
* Homepage/package: `unlzx` under most UNIX-like platforms ([Debian/Ubuntu](https://launchpad.net/~rzr/+archive/ubuntu/ppa/+build/2486127), [RedHat](https://fedora.pkgs.org/32/rpm-sphere-x86_64/unlzx-1.1-4.1.x86_64.rpm.html), [Source](http://xavprods.free.fr/lzx/))
|
||||
|
||||
#### Arj
|
||||
* Formats: .arj
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: page
|
||||
title: Colour Codes
|
||||
---
|
||||
ENiGMA½ supports Renegade-style pipe colour codes for formatting strings. You'll see them used throughout your configuration, and can also be used in places like the oneliner, rumour mod, full screen editor etc.
|
||||
ENiGMA½ supports Renegade-style pipe colour codes for formatting strings. You'll see them used throughout your configuration, and can also be used in places like onelinerz, rumourz, full screen editor etc.
|
||||
|
||||
## Usage
|
||||
When ENiGMA½ encounters colour codes in strings, they'll be processed in order and combined where possible.
|
||||
|
|
|
@ -10,5 +10,5 @@ Your initial configuration skeleton can be created using the `oputil.js` command
|
|||
./oputil.js config new
|
||||
```
|
||||
|
||||
You will be asked a series of questions to create an initial configuration, which will be saved to `/enigma-bbs-install-path/config/config.hjson`. This will also produce `config/<bbsName>-menu.hjson` and `config/<bbsName>-prompt.hjson` files (where `<bbsName>` is replaced by the name you provided in the steps above). See [Menu HJSON](menu-hjson.md) for more information.
|
||||
You will be asked a series of questions to create an initial configuration, which will be saved to `/enigma-bbs-install-path/config/config.hjson`. This will also produce menu files under `config/menus/`. See [Menu HJSON](menu-hjson.md) for more information.
|
||||
|
||||
|
|
|
@ -8,8 +8,10 @@ All paths mentioned here are relative to the ENiGMA½ checkout directory.
|
|||
|---------------------|-----------------------------------------------------------------------------------------------------------|
|
||||
| `/art/general` | Non-theme art - welcome ANSI, logoff ANSI, etc. See [General Art]({{ site.baseurl }}{% link art/general.md %}).
|
||||
| `/art/themes` | Theme art. Themes should be in their own subdirectory and contain a theme.hjson. See [Themes]({{ site.baseurl }}{% link art/themes.md %}).
|
||||
| `/config` | config.hjson, [menu.hjson]({{ site.baseurl }}{% link configuration/menu-hjson.md %}) and prompt.hjson storage. Also default path for SSL certs and public/private keys
|
||||
| `/db` | All ENiGMA½ databases in Sqlite3 format
|
||||
| `/config` | [config.hjson](config-hjson.md) system configuration.
|
||||
| `/config/menus` | [menu.hjson](menu-hjson.md)storage.
|
||||
| `/config/security` | D path for SSL certs and public/private keys.
|
||||
| `/db` | All ENiGMA½ databases in Sqlite3 format.
|
||||
| `/docs` | These docs ;-)
|
||||
| `/dropfiles` | Dropfiles created for [local doors]({{ site.baseurl }}{% link modding/local-doors.md %})
|
||||
| `/logs` | Logs. See [Monitoring Logs]({{ site.baseurl }}{% link troubleshooting/monitoring-logs.md %})
|
||||
|
|
|
@ -3,7 +3,7 @@ layout: page
|
|||
title: Menu HSJON
|
||||
---
|
||||
## Menu HJSON
|
||||
The core of a ENiGMA½ based BBS is `menu.hjson`. Note that when `menu.hjson` is referenced, we're actually talking about `config/yourboardname-menu.hjson` or similar. This file determines the menus (or screens) a user can see, the order they come in and how they interact with each other, ACS configuration, etc. Like all configuration within ENiGMA½, menu configuration is done in [HJSON](https://hjson.org/) format. See [HJSON General Information](hjson.md) for more information.
|
||||
The core of a ENiGMA½ based BBS is `menu.hjson`. Note that when `menu.hjson` is referenced, we're actually talking about `config/menus/yourboardname-*.hjson`. These files determines the menus (or screens) a user can see, the order they come in and how they interact with each other, ACS configuration, etc. Like all configuration within ENiGMA½, menu configuration is done in [HJSON](https://hjson.org/) format. See [HJSON General Information](hjson.md) for more information.
|
||||
|
||||
Entries in `menu.hjson` are often referred to as *blocks* or *sections*. Each entry defines a menu. A menu in this sense is something the user can see or visit. Examples include but are not limited to:
|
||||
|
||||
|
@ -13,6 +13,8 @@ Entries in `menu.hjson` are often referred to as *blocks* or *sections*. Each en
|
|||
|
||||
Menu entries live under the `menus` section of `menu.hjson`. The *key* for a menu is it's name that can be referenced by other menus and areas of the system.
|
||||
|
||||
:information_source: Remember that the top level menu may include additional files using the `includes` directive. See [Configuration Files](config-files.md) for more information on this.
|
||||
|
||||
## Common Menu Entry Members
|
||||
Below is a table of **common** menu entry members. These members apply to most entries, though entries that are backed by a specialized module (ie: `module: bbs_list`) may differ. See documentation for the module in question for particulars.
|
||||
|
||||
|
@ -184,7 +186,9 @@ In the above entry, you'll notice `form`. This defines a form(s) object. In this
|
|||
* Upon submit, the first match will be executed. For example, if the user selects "login", the first entry with a value of `{ matrixSubmit: 0 }` will match (due to 0 being the first index in the list and `matrixSubmit` being the arg name in question) causing `action` of `@menu:login` to be executed (go to `login` menu).
|
||||
|
||||
## Prompts
|
||||
TODO: describe the "prompts" section, default setup, etc.
|
||||
Prompts are found in the `prompts` section of menu files. Prompts allow for quick user input and shorthand form requirements for menus. Additionally, prompts are often used for for multiple menus. Consider a pause prompt or menu command input for example.
|
||||
|
||||
TODO: additional prompt docs
|
||||
|
||||
## ACS Checks
|
||||
Menu modules can check user ACS in order to restrict areas and perform flow control. See [ACS](acs.md) for available ACS syntax.
|
||||
|
|
|
@ -6,7 +6,7 @@ title: TIC Support
|
|||
ENiGMA½ supports FidoNet-Style TIC file attachments by mapping TIC areas to local file areas.
|
||||
|
||||
Under a given node defined in the `ftn_bso` config section in `config.hjson` (see
|
||||
[BSO Import/Export](../messageareas/bso-import-export)), TIC configuration may be supplied:
|
||||
[BSO Import/Export](../messageareas/bso-import-export.md)), TIC configuration may be supplied:
|
||||
|
||||
```hjson
|
||||
{
|
||||
|
|
|
@ -21,5 +21,4 @@ uploads: {
|
|||
|
||||
:information_source: Remember that uploads in a particular area are stored **using the first storage tag defined in that area.**
|
||||
|
||||
:information_source: Any ACS checks are allowed. See [ACS](/docs/acs.md)
|
||||
|
||||
:information_source: Any ACS checks are allowed. See [ACS](../configuration/acs.md)
|
||||
|
|
|
@ -8,4 +8,4 @@ using `contentServers::web::domain` and will default to HTTPS (https://) if enab
|
|||
HTTP. The end result is users are given a temporary web link that may look something like this:
|
||||
`https://xibalba.l33t.codes:44512/f/h7JK`
|
||||
|
||||
See [Web Server](web_server.md) for more information.
|
||||
See [Web Server](../servers/web-server.md) for more information.
|
||||
|
|
|
@ -10,8 +10,8 @@ ENiGMA½ is a modern BBS software with a nostalgic flair!
|
|||
## Features Available Now
|
||||
* Multi platform: Anywhere [Node.js](https://nodejs.org/) runs likely works (known to work under Linux, FreeBSD, OpenBSD, OS X and Windows)
|
||||
* Unlimited multi node support (for all those BBS "callers"!)
|
||||
* **Highly** customizable via [HJSON](http://hjson.org/) based configuration, menus, and themes in addition to JavaScript based [mods](docs/mods.md)
|
||||
* [MCI support](docs/mci.md) for lightbars, toggles, input areas, and so on plus many other other bells and whistles
|
||||
* **Highly** customizable via [HJSON](http://hjson.org/) based configuration, menus, and themes in addition to JavaScript based [mods](modding/)
|
||||
* [MCI support](art/mci.md) for lightbars, toggles, input areas, and so on plus many other other bells and whistles
|
||||
* Telnet, **SSH**, and both secure and non-secure [WebSocket](https://en.wikipedia.org/wiki/WebSocket) access built in! Additional servers are easy to implement
|
||||
* [CP437](http://www.ascii-codes.com/) and UTF-8 output
|
||||
* [SyncTerm](http://syncterm.bbsdev.net/) style font and baud emulation support. Display PC/DOS and Amiga style artwork as it's intended! In general, ANSI-BBS / [cterm.txt](http://cvs.synchro.net/cgi-bin/viewcvs.cgi/*checkout*/src/conio/cterm.txt?content-type=text%2Fplain&revision=HEAD) / [bansi.txt](http://www.bbsdocumentary.com/library/PROGRAMS/GRAPHICS/ANSI/bansi.txt) are followed for expected BBS behavior
|
||||
|
@ -19,9 +19,9 @@ ENiGMA½ is a modern BBS software with a nostalgic flair!
|
|||
* Renegade style pipe color codes
|
||||
* [SQLite](http://sqlite.org/) storage of users, message areas, and so on
|
||||
* Strong [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) backed password encryption
|
||||
* [Door support](docs/doors.md) including common dropfile formats for legacy DOS doors. Built in [BBSLink](http://bbslink.net/), [DoorParty](http://forums.throwbackbbs.com/), [Exodus](https://oddnetwork.org/exodus/) and [CombatNet](http://combatnet.us/) support!
|
||||
* [Door support](modding/local-doors.md) including common dropfile formats for legacy DOS doors. Built in [BBSLink](http://bbslink.net/), [DoorParty](http://forums.throwbackbbs.com/), [Exodus](https://oddnetwork.org/exodus/) and [CombatNet](http://combatnet.us/) support!
|
||||
* [Bunyan](https://github.com/trentm/node-bunyan) logging
|
||||
* [Message networks](docs/msg_networks.md) with FidoNet Type Network (FTN) + BinkleyTerm Style Outbound (BSO) message import/export
|
||||
* [Gazelle](https://github.com/WhatCD/Gazelle) inspired File Bases including fast fully indexed full text search (FTS), #tags, and HTTP(S) temporary download URLs using a built in [web server](docs/web_server.md). Legacy X/Y/Z modem also supported!
|
||||
* [Message networks](messageareas/message_networks.md) with FidoNet Type Network (FTN) + BinkleyTerm Style Outbound (BSO) message import/export
|
||||
* [Gazelle](https://github.com/WhatCD/Gazelle) inspired File Bases including fast fully indexed full text search (FTS), #tags, and HTTP(S) temporary download URLs using a built in [web server](servers/web-server.md). Legacy X/Y/Z modem also supported!
|
||||
* Upload processor supporting [FILE_ID.DIZ](https://en.wikipedia.org/wiki/FILE_ID.DIZ) and [NFO](https://en.wikipedia.org/wiki/.nfo) extraction, year estimation, and more!
|
||||
* ANSI support in the Full Screen Editor (FSE), file descriptions, and so on
|
||||
|
|
|
@ -57,7 +57,7 @@ ENiGMA BBS makes use of a few packages for archive and legacy protocol support.
|
|||
|------------|-----------------------------------|--------------------------------------------|---------------------------------------------------|------------------------------------------------------------------|
|
||||
| arj | Unpacking arj archives | `arj` | n/a, binaries [here](http://arj.sourceforge.net/) | [ARJ](http://arj.sourceforge.net/) |
|
||||
| 7zip | Unpacking zip, rar, archives | `p7zip-full` | `p7zip-full` | [7-zip](http://www.7-zip.org/) |
|
||||
| lha | Unpacking lha archives | `lhasa` | n/a, source [here](http://www2m.biglobe.ne.jp/~dolphin/lha/lha.htm) | Unknown |
|
||||
| lha | Unpacking lha archives | `lhasa` | n/a, source [here](https://web.archive.org/web/20200301124852/http://www2m.biglobe.ne.jp/~dolphin/lha/lha.htm) | Unknown |
|
||||
| Rar | Unpacking rar archives | `unrar` | n/a, binaries [here](https://www.rarlab.com/download.htm) | Unknown |
|
||||
| lrzsz | sz/rz: X/Y/Z protocol support | `lrzsz` | `lrzsz` | Unknown |
|
||||
| sexyz | SexyZ protocol support | [sexyz](https://l33t.codes/outgoing/sexyz) | [sexyz](https://l33t.codes/outgoing/sexyz) | Available with [Synchronet](http://wiki.synchro.net/install:win) |
|
||||
|
|
|
@ -6,7 +6,7 @@ If you've become convinced you would like a "production" BBS running ENiGMA½ a
|
|||
may be in order.
|
||||
|
||||
[PM2](https://github.com/Unitech/pm2) is an excellent choice for managing your running ENiGMA½ instances if
|
||||
you've installed via the [install script](install-script) or [manual installation](manual) method.
|
||||
you've installed via the [install script](install-script.md) or [manual installation](manual.md) method.
|
||||
Additionally, it is suggested that you run as a specific more locked down user (e.g. 'enigma').
|
||||
|
||||
If you're running ENiGMA via Docker, then process management is already handled for you!
|
||||
|
|
|
@ -22,6 +22,6 @@ to get it written to an SD card.
|
|||
|
||||
4. Install required packages: `sudo apt install lrzsz p7zip-full`
|
||||
|
||||
5. Follow the [installation instructions](/installation) to install ENiGMA½.
|
||||
5. Follow the [installation instructions](../installation/) to install ENiGMA½.
|
||||
|
||||
6. Profit!
|
||||
|
|
|
@ -4,7 +4,7 @@ title: Testing Your Installation
|
|||
---
|
||||
Once you've completed your chosen installation method, it's time to test!
|
||||
|
||||
_Note that if you've used the [Docker](docker) installation method, you've already done this._
|
||||
_Note that if you've used the [Docker](docker.md) installation method, you've already done this._
|
||||
|
||||
```bash
|
||||
./main.js
|
||||
|
@ -44,6 +44,6 @@ If you don't have any telnet software, these are compatible with ENiGMA½:
|
|||
* [SyncTERM](http://syncterm.bbsdev.net/)
|
||||
* [EtherTerm](https://github.com/M-griffin/EtherTerm)
|
||||
* [NetRunner](http://mysticbbs.com/downloads.html)
|
||||
* [MagiTerm](https://magickabbs.com/index.php/magiterm/)
|
||||
* [MagiTerm](https://magickabbs.com/utils/)
|
||||
* [VTX](https://github.com/codewar65/VTX_ClientServer) (Browser based)
|
||||
* [fTelnet](https://www.ftelnet.ca/) (Browser based)
|
||||
|
|
|
@ -41,7 +41,7 @@ ENiGMA½ will run on both 32bit and 64bit Windows. If you want to run 16bit door
|
|||
4. Click `New` and paste the path to 7zip
|
||||
5. Close your console window and reopen. You can type `7z` to make sure it's working.
|
||||
|
||||
(Please see [Archivers](/docs/archivers.md) for additional archive utilities!)
|
||||
(Please see [Archivers](../configuration/archivers.md) for additional archive utilities!)
|
||||
|
||||
3. Install [Git](https://git-scm.com/downloads) and optionally [TortoiseGit](https://tortoisegit.org/download/).
|
||||
|
||||
|
@ -68,4 +68,4 @@ ENiGMA½ will run on both 32bit and 64bit Windows. If you want to run 16bit door
|
|||
```
|
||||
|
||||
|
||||
6. Look at [Production Installation](/installation/production) for maintaining ENiGMA½ when you are ready to go live.
|
||||
6. Look at [Production Installation](production.md) for maintaining ENiGMA½ when you are ready to go live.
|
||||
|
|
|
@ -30,7 +30,7 @@ A node entry starts with a [FTN address](http://ftsc.org/docs/old/fsp-1028.001)
|
|||
| `packetType` | :-1: | `2`, `2.2`, or `2+`. Defaults to `2+` for modern mailer compatiability. |
|
||||
| `packetPassword` | :-1: | Optional password for the packet |
|
||||
| `encoding` | :-1: | Encoding to use for message bodies; Defaults to `utf-8`. |
|
||||
| `archiveType` | :-1: | Specifies the archive type (by extension or MIME type) for ArcMail bundles. This should be `zip` (or `application/zip`) for most setups. Other valid examples include `arc`, `arj`, `lhz`, `pak`, `sqz`, or `zoo`. See [Archivers](docs/configuration/archivers.md) for more information. |
|
||||
| `archiveType` | :-1: | Specifies the archive type (by extension or MIME type) for ArcMail bundles. This should be `zip` (or `application/zip`) for most setups. Other valid examples include `arc`, `arj`, `lhz`, `pak`, `sqz`, or `zoo`. See [Archivers](../configuration/archivers.md) for more information. |
|
||||
|
||||
**Example**:
|
||||
```hjson
|
||||
|
|
|
@ -28,9 +28,9 @@ Dropfile types specified by `dropFileType`:
|
|||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `DOOR` | [DOOR.SYS](http://goldfndr.home.mindspring.com/dropfile/doorsys.htm)
|
||||
| `DOOR` | [DOOR.SYS](https://web.archive.org/web/20160325192739/http://goldfndr.home.mindspring.com/dropfile/doorsys.htm)
|
||||
| `DOOR32` | [DOOR32.SYS](https://raw.githubusercontent.com/NuSkooler/ansi-bbs/master/docs/dropfile_formats/door32_sys.txt)
|
||||
| `DORINFO` | [DORINFOx.DEF](http://goldfndr.home.mindspring.com/dropfile/dorinfo.htm)
|
||||
| `DORINFO` | [DORINFOx.DEF](https://web.archive.org/web/20160321190038/http://goldfndr.home.mindspring.com/dropfile/dorinfo.htm)
|
||||
|
||||
#### Argument Variables
|
||||
The following variables may be used in `args` entries:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: page
|
||||
title: Web Server
|
||||
---
|
||||
ENiGMA½ comes with a built in *content server* for supporting both HTTP and HTTPS. Currently the [File Bases](file_base.md) registers routes for file downloads, password reset email links are handled via the server, and static files can also be served for your BBS. Other features will likely come in the future or you can easily write your own!
|
||||
ENiGMA½ comes with a built in *content server* for supporting both HTTP and HTTPS. Currently the [File Bases](../modding/file-base-web-download-manager.md) registers routes for file downloads, password reset email links are handled via the server, and static files can also be served for your BBS. Other features will likely come in the future or you can easily write your own!
|
||||
|
||||
# Configuration
|
||||
By default the web server is not enabled. To enable it, you will need to at a minimum configure two keys in the `contentServers.web` section of `config.hjson`:
|
||||
|
|
|
@ -211,6 +211,14 @@
|
|||
}
|
||||
const points = user.getPropertyAsNumber(UserProps.AchievementTotalPoints) || 0;
|
||||
return !isNan(value) && points >= value;
|
||||
},
|
||||
PV : function userPropValue() {
|
||||
if (!user || !Array.isArray(value) || value.length !== 2) {
|
||||
return false;
|
||||
}
|
||||
const [propName, propValue] = value;
|
||||
const actualPropValue = user.getProperty(propName);
|
||||
return actualPropValue === propValue;
|
||||
}
|
||||
}[acsCode](value);
|
||||
} catch (e) {
|
||||
|
|
|
@ -369,7 +369,7 @@
|
|||
storageTags: {
|
||||
//
|
||||
// Example storage tag: "super_l33t_warez":
|
||||
// super_l33t_warez: "/path/to/super/l33t/warez"
|
||||
// super_l33t_warez: /path/to/super/l33t/warez
|
||||
//
|
||||
}
|
||||
|
||||
|
@ -377,10 +377,10 @@
|
|||
//
|
||||
// Example area with the areaTag of "an_example_area":
|
||||
// an_example_area: {
|
||||
// name: "Example File Area"
|
||||
// desc: "It's just an example, yo!"
|
||||
// name: Example File Area
|
||||
// desc: It's just an example, yo!
|
||||
// storageTags: [
|
||||
// "super_l33t_warez"
|
||||
// super_l33t_warez
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
menus: {
|
||||
doorsMainMenu: {
|
||||
desc: Doors Menu
|
||||
art: DOORMNU
|
||||
prompt: menuCommand
|
||||
config: {
|
||||
interrupt: realtime
|
||||
}
|
||||
submit: [
|
||||
{
|
||||
value: { command: "G" }
|
||||
action: @menu:fullLogoffSequence
|
||||
}
|
||||
{
|
||||
value: { command: "Q" }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
//
|
||||
// The system supports many ways of launching doors including
|
||||
// modules for DoorParty!, BBSLink, etc.
|
||||
//
|
||||
// Below are some examples. See the documentation for more info.
|
||||
//
|
||||
{
|
||||
value: { command: "ABRACADABRA" }
|
||||
action: @menu:doorAbracadabraExample
|
||||
}
|
||||
{
|
||||
value: { command: "TWBBSLINK" }
|
||||
action: @menu:doorTradeWars2002BBSLinkExample
|
||||
}
|
||||
{
|
||||
value: { command: "DP" }
|
||||
action: @menu:doorPartyExample
|
||||
}
|
||||
{
|
||||
value: { command: "CN" }
|
||||
action: @menu:doorCombatNetExample
|
||||
}
|
||||
{
|
||||
value: { command: "EXODUS" }
|
||||
action: @menu:doorExodusCataclysm
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
//
|
||||
// Local Door Example via abracadabra module
|
||||
//
|
||||
// This example assumes launch_door.sh (which is passed args)
|
||||
// launches the door.
|
||||
//
|
||||
doorAbracadabraExample: {
|
||||
desc: Abracadabra Example
|
||||
module: abracadabra
|
||||
config: {
|
||||
name: Example Door
|
||||
dropFileType: DORINFO
|
||||
cmd: /home/enigma/DOS/scripts/launch_door.sh
|
||||
args: [
|
||||
"{node}",
|
||||
"{dropFile}",
|
||||
"{srvPort}",
|
||||
],
|
||||
nodeMax: 1
|
||||
tooManyArt: DOORMANY
|
||||
io: socket
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// BBSLink Example (TradeWars 2000)
|
||||
//
|
||||
// Register @ https://bbslink.net/
|
||||
//
|
||||
doorTradeWars2002BBSLinkExample: {
|
||||
desc: Playing TW 2002 (BBSLink)
|
||||
module: bbs_link
|
||||
config: {
|
||||
sysCode: XXXXXXXX
|
||||
authCode: XXXXXXXX
|
||||
schemeCode: XXXXXXXX
|
||||
door: tw
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// DoorParty! Example
|
||||
//
|
||||
// Register @ http://throwbackbbs.com/
|
||||
//
|
||||
doorPartyExample: {
|
||||
desc: Using DoorParty!
|
||||
module: door_party
|
||||
config: {
|
||||
username: XXXXXXXX
|
||||
password: XXXXXXXX
|
||||
bbsTag: XX
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CombatNet Example
|
||||
//
|
||||
// Register @ http://combatnet.us/
|
||||
//
|
||||
doorCombatNetExample: {
|
||||
desc: Using CombatNet
|
||||
module: combatnet
|
||||
config: {
|
||||
bbsTag: CBNxxx
|
||||
password: XXXXXXXXX
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Exodus Example (cataclysm)
|
||||
// Register @ https://oddnetwork.org/exodus/
|
||||
//
|
||||
doorExodusCataclysm: {
|
||||
desc: Cataclysm
|
||||
module: exodus
|
||||
config: {
|
||||
rejectUnauthorized: false
|
||||
board: XXX
|
||||
key: XXXXXXXX
|
||||
door: cataclysm
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,918 @@
|
|||
{
|
||||
menus: {
|
||||
fileBaseMainMenu: {
|
||||
desc: File Base
|
||||
art: FMENU
|
||||
prompt: fileMenuCommand
|
||||
config: {
|
||||
interrupt: realtime
|
||||
}
|
||||
submit: [
|
||||
{
|
||||
value: { menuOption: "L" }
|
||||
action: @menu:fileBaseListEntries
|
||||
}
|
||||
{
|
||||
value: { menuOption: "B" }
|
||||
action: @menu:fileBaseBrowseByAreaSelect
|
||||
}
|
||||
{
|
||||
value: { menuOption: "F" }
|
||||
action: @menu:fileBaseFilterEditor
|
||||
}
|
||||
{
|
||||
value: { menuOption: "Q" }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
value: { menuOption: "G" }
|
||||
action: @menu:fullLogoffSequence
|
||||
}
|
||||
{
|
||||
value: { menuOption: "D" }
|
||||
action: @menu:fileBaseDownloadManager
|
||||
}
|
||||
{
|
||||
value: { menuOption: "W" }
|
||||
action: @menu:fileBaseWebDownloadManager
|
||||
}
|
||||
{
|
||||
value: { menuOption: "U" }
|
||||
action: @menu:fileBaseUploadFiles
|
||||
}
|
||||
{
|
||||
value: { menuOption: "S" }
|
||||
action: @menu:fileBaseSearch
|
||||
}
|
||||
{
|
||||
value: { menuOption: "P" }
|
||||
action: @menu:fileBaseSetNewScanDate
|
||||
}
|
||||
{
|
||||
value: { menuOption: "E" }
|
||||
action: @menu:fileBaseExportListFilter
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
fileBaseListEntries: {
|
||||
module: file_area_list
|
||||
desc: Browsing Files
|
||||
config: {
|
||||
art: {
|
||||
browse: FBRWSE
|
||||
details: FDETAIL
|
||||
detailsGeneral: FDETGEN
|
||||
detailsNfo: FDETNFO
|
||||
detailsFileList: FDETLST
|
||||
help: FBHELP
|
||||
}
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
MT1: {
|
||||
mode: preview
|
||||
}
|
||||
|
||||
HM2: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: navSelect
|
||||
items: [
|
||||
"prev", "next", "details", "toggle queue", "rate", "change filter", "help", "quit"
|
||||
]
|
||||
focusItemIndex: 1
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { navSelect: 0 }
|
||||
action: @method:prevFile
|
||||
}
|
||||
{
|
||||
value: { navSelect: 1 }
|
||||
action: @method:nextFile
|
||||
}
|
||||
{
|
||||
value: { navSelect: 2 }
|
||||
action: @method:viewDetails
|
||||
}
|
||||
{
|
||||
value: { navSelect: 3 }
|
||||
action: @method:toggleQueue
|
||||
}
|
||||
{
|
||||
value: { navSelect: 4 }
|
||||
action: @menu:fileBaseGetRatingForSelectedEntry
|
||||
}
|
||||
{
|
||||
value: { navSelect: 5 }
|
||||
action: @menu:fileBaseFilterEditor
|
||||
}
|
||||
{
|
||||
value: { navSelect: 6 }
|
||||
action: @method:displayHelp
|
||||
}
|
||||
{
|
||||
value: { navSelect: 7 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "w", "shift + w" ]
|
||||
action: @method:showWebDownloadLink
|
||||
}
|
||||
{
|
||||
keys: [ "escape", "q", "shift + q" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
keys: [ "t", "shift + t" ]
|
||||
action: @method:toggleQueue
|
||||
}
|
||||
{
|
||||
keys: [ "f", "shift + f" ]
|
||||
action: @menu:fileBaseFilterEditor
|
||||
}
|
||||
{
|
||||
keys: [ "v", "shift + v" ]
|
||||
action: @method:viewDetails
|
||||
}
|
||||
{
|
||||
keys: [ "r", "shift + r" ]
|
||||
action: @menu:fileBaseGetRatingForSelectedEntry
|
||||
}
|
||||
{
|
||||
keys: [ "?" ]
|
||||
action: @method:displayHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
1: {
|
||||
mci: {
|
||||
HM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: navSelect
|
||||
items: [
|
||||
"general", "nfo/readme", "file listing"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape", "q", "shift + q" ]
|
||||
action: @method:detailsQuit
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
2: {
|
||||
// details - general
|
||||
mci: {}
|
||||
}
|
||||
|
||||
3: {
|
||||
// details - nfo/readme
|
||||
mci: {
|
||||
MT1: {
|
||||
mode: preview
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4: {
|
||||
// details - file listing
|
||||
mci: {
|
||||
VM1: {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseBrowseByAreaSelect: {
|
||||
desc: Browsing File Areas
|
||||
module: file_base_area_select
|
||||
art: FAREASEL
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
argName: areaTag
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { areaTag: null }
|
||||
action: @method:selectArea
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseFilterEditor: {
|
||||
desc: File Filter Editor
|
||||
module: file_area_filter_edit
|
||||
art: FFILEDT
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
argName: searchTerms
|
||||
}
|
||||
ET2: {
|
||||
maxLength: 64
|
||||
argName: tags
|
||||
}
|
||||
SM3: {
|
||||
maxLength: 64
|
||||
argName: areaIndex
|
||||
}
|
||||
SM4: {
|
||||
items: [
|
||||
"upload date",
|
||||
"uploaded by",
|
||||
"downloads",
|
||||
"rating",
|
||||
"estimated year",
|
||||
"size",
|
||||
]
|
||||
argName: sortByIndex
|
||||
}
|
||||
SM5: {
|
||||
items: [
|
||||
"decending",
|
||||
"ascending"
|
||||
]
|
||||
argName: orderByIndex
|
||||
}
|
||||
ET6: {
|
||||
maxLength: 64
|
||||
argName: name
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
HM7: {
|
||||
focus: true
|
||||
items: [
|
||||
"prev", "next", "make active", "save", "new", "delete"
|
||||
]
|
||||
argName: navSelect
|
||||
focusItemIndex: 1
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { navSelect: 0 }
|
||||
action: @method:prevFilter
|
||||
}
|
||||
{
|
||||
value: { navSelect: 1 }
|
||||
action: @method:nextFilter
|
||||
}
|
||||
{
|
||||
value: { navSelect: 2 }
|
||||
action: @method:makeFilterActive
|
||||
}
|
||||
{
|
||||
value: { navSelect: 3 }
|
||||
action: @method:saveFilter
|
||||
}
|
||||
{
|
||||
value: { navSelect: 4 }
|
||||
action: @method:newFilter
|
||||
}
|
||||
{
|
||||
value: { navSelect: 5 }
|
||||
action: @method:deleteFilter
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseDownloadManager: {
|
||||
desc: Download Manager
|
||||
module: file_base_download_manager
|
||||
config: {
|
||||
art: {
|
||||
queueManager: FDLMGR
|
||||
/*
|
||||
NYI
|
||||
details: FDLDET
|
||||
*/
|
||||
}
|
||||
emptyQueueMenu: fileBaseDownloadManagerEmptyQueue
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
argName: queueItem
|
||||
}
|
||||
HM2: {
|
||||
focus: true
|
||||
items: [ "download all", "quit" ]
|
||||
argName: navSelect
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { navSelect: 0 }
|
||||
action: @method:downloadAll
|
||||
}
|
||||
{
|
||||
value: { navSelect: 1 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "a", "shift + a" ]
|
||||
action: @method:downloadAll
|
||||
}
|
||||
{
|
||||
keys: [ "delete", "r", "shift + r" ]
|
||||
action: @method:removeItem
|
||||
}
|
||||
{
|
||||
keys: [ "c", "shift + c" ]
|
||||
action: @method:clearQueue
|
||||
}
|
||||
{
|
||||
keys: [ "escape", "q", "shift + q" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseDownloadManagerEmptyQueue: {
|
||||
desc: Empty Download Queue
|
||||
art: FEMPTYQ
|
||||
config: {
|
||||
pause: true
|
||||
menuFlags: [ "noHistory", "popParent" ]
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseWebDownloadManager: {
|
||||
desc: Web D/L Manager
|
||||
module: file_base_web_download_manager
|
||||
config: {
|
||||
art: {
|
||||
queueManager: FWDLMGR
|
||||
batchList: BATDLINF
|
||||
}
|
||||
emptyQueueMenu: fileBaseDownloadManagerEmptyQueue
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
argName: queueItem
|
||||
}
|
||||
HM2: {
|
||||
focus: true
|
||||
items: [ "get batch link", "quit", "help" ]
|
||||
argName: navSelect
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { navSelect: 0 }
|
||||
action: @method:getBatchLink
|
||||
}
|
||||
{
|
||||
value: { navSelect: 1 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "b", "shift + b" ]
|
||||
action: @method:getBatchLink
|
||||
}
|
||||
{
|
||||
keys: [ "delete", "r", "shift + r" ]
|
||||
action: @method:removeItem
|
||||
}
|
||||
{
|
||||
keys: [ "c", "shift + c" ]
|
||||
action: @method:clearQueue
|
||||
}
|
||||
{
|
||||
keys: [ "escape", "q", "shift + q" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseUploadFiles: {
|
||||
desc: Uploading
|
||||
module: upload
|
||||
config: {
|
||||
interrupt: never
|
||||
art: {
|
||||
options: ULOPTS
|
||||
fileDetails: ULDETAIL
|
||||
processing: ULCHECK
|
||||
dupes: ULDUPES
|
||||
}
|
||||
}
|
||||
|
||||
form: {
|
||||
// options
|
||||
0: {
|
||||
mci: {
|
||||
SM1: {
|
||||
argName: areaSelect
|
||||
focus: true
|
||||
}
|
||||
TM2: {
|
||||
argName: uploadType
|
||||
items: [ "blind", "supply filename" ]
|
||||
}
|
||||
ET3: {
|
||||
argName: fileName
|
||||
maxLength: 255
|
||||
validate: @method:validateNonBlindFileName
|
||||
}
|
||||
HM4: {
|
||||
argName: navSelect
|
||||
items: [ "continue", "cancel" ]
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { navSelect: 0 }
|
||||
action: @method:optionsNavContinue
|
||||
}
|
||||
{
|
||||
value: { navSelect: 1 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
"actionKeys" : [
|
||||
{
|
||||
"keys" : [ "escape" ],
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
1: {
|
||||
mci: { }
|
||||
}
|
||||
|
||||
// file details entry
|
||||
2: {
|
||||
mci: {
|
||||
MT1: {
|
||||
argName: shortDesc
|
||||
tabSwitchesView: true
|
||||
focus: true
|
||||
}
|
||||
|
||||
ET2: {
|
||||
argName: tags
|
||||
}
|
||||
|
||||
ME3: {
|
||||
argName: estYear
|
||||
maskPattern: "####"
|
||||
}
|
||||
|
||||
BT4: {
|
||||
argName: continue
|
||||
text: continue
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { continue: null }
|
||||
action: @method:fileDetailsContinue
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// dupes
|
||||
3: {
|
||||
mci: {
|
||||
VM1: {
|
||||
/*
|
||||
Use 'dupeInfoFormat' to custom format:
|
||||
|
||||
areaDesc
|
||||
areaName
|
||||
areaTag
|
||||
desc
|
||||
descLong
|
||||
fileId
|
||||
fileName
|
||||
fileSha256
|
||||
storageTag
|
||||
uploadTimestamp
|
||||
|
||||
*/
|
||||
|
||||
mode: preview
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseSearch: {
|
||||
module: file_base_search
|
||||
desc: Searching Files
|
||||
art: FSEARCH
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
focus: true
|
||||
argName: searchTerms
|
||||
}
|
||||
BT2: {
|
||||
argName: search
|
||||
text: search
|
||||
submit: true
|
||||
}
|
||||
ET3: {
|
||||
maxLength: 64
|
||||
argName: tags
|
||||
}
|
||||
SM4: {
|
||||
maxLength: 64
|
||||
argName: areaIndex
|
||||
}
|
||||
SM5: {
|
||||
items: [
|
||||
"upload date",
|
||||
"uploaded by",
|
||||
"downloads",
|
||||
"rating",
|
||||
"estimated year",
|
||||
"size",
|
||||
"filename",
|
||||
]
|
||||
argName: sortByIndex
|
||||
}
|
||||
SM6: {
|
||||
items: [
|
||||
"decending",
|
||||
"ascending"
|
||||
]
|
||||
argName: orderByIndex
|
||||
}
|
||||
BT7: {
|
||||
argName: advancedSearch
|
||||
text: advanced search
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { search: null }
|
||||
action: @method:search
|
||||
}
|
||||
{
|
||||
value: { advancedSearch: null }
|
||||
action: @method:search
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseSetNewScanDate: {
|
||||
module: set_newscan_date
|
||||
desc: File Base
|
||||
art: SETFNSDATE
|
||||
config: {
|
||||
target: file
|
||||
scanDateFormat: YYYYMMDD
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ME1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: scanDate
|
||||
maskPattern: "####/##/##"
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { scanDate: null }
|
||||
action: @method:scanDateSubmit
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseExportListFilter: {
|
||||
module: file_base_search
|
||||
art: FBLISTEXPSEARCH
|
||||
config: {
|
||||
fileBaseListEntriesMenu: fileBaseExportList
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
focus: true
|
||||
argName: searchTerms
|
||||
}
|
||||
BT2: {
|
||||
argName: search
|
||||
text: search
|
||||
submit: true
|
||||
}
|
||||
ET3: {
|
||||
maxLength: 64
|
||||
argName: tags
|
||||
}
|
||||
SM4: {
|
||||
maxLength: 64
|
||||
argName: areaIndex
|
||||
}
|
||||
SM5: {
|
||||
items: [
|
||||
"upload date",
|
||||
"uploaded by",
|
||||
"downloads",
|
||||
"rating",
|
||||
"estimated year",
|
||||
"size",
|
||||
"filename"
|
||||
]
|
||||
argName: sortByIndex
|
||||
}
|
||||
SM6: {
|
||||
items: [
|
||||
"decending",
|
||||
"ascending"
|
||||
]
|
||||
argName: orderByIndex
|
||||
}
|
||||
BT7: {
|
||||
argName: advancedSearch
|
||||
text: advanced search
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { search: null }
|
||||
action: @method:search
|
||||
}
|
||||
{
|
||||
value: { advancedSearch: null }
|
||||
action: @method:search
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseExportList: {
|
||||
module: file_base_user_list_export
|
||||
art: FBLISTEXP
|
||||
config: {
|
||||
pause: true
|
||||
templates: {
|
||||
entry: file_list_entry.asc
|
||||
}
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
TL1: { }
|
||||
TL2: { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseExportListNoResults: {
|
||||
desc: Browsing Files
|
||||
art: FBNORES
|
||||
config: {
|
||||
pause: true
|
||||
menuFlags: [ "noHistory", "popParent" ]
|
||||
}
|
||||
}
|
||||
|
||||
// Referenced by various menus
|
||||
fileBaseGetRatingForSelectedEntry: {
|
||||
desc: Rating a File
|
||||
prompt: fileBaseRateEntryPrompt
|
||||
config: {
|
||||
cls: true
|
||||
}
|
||||
submit: [
|
||||
// :TODO: handle esc/q
|
||||
{
|
||||
// pass data back to caller
|
||||
value: { rating: null }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// default menu entry used by the 'file_area_list' module
|
||||
// when there are no search results for the provided criteria
|
||||
fileBaseListEntriesNoResults: {
|
||||
desc: Browsing Files
|
||||
art: FBNORES
|
||||
config: {
|
||||
pause: true
|
||||
menuFlags: [ "noHistory", "popParent" ]
|
||||
}
|
||||
}
|
||||
|
||||
// default menu entry used by the 'file_base_download_manager' module
|
||||
// for protocol selection
|
||||
fileTransferProtocolSelection: {
|
||||
desc: Protocol selection
|
||||
module: file_transfer_protocol_select
|
||||
art: FPROSEL
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
argName: protocol
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { protocol: null }
|
||||
action: @method:selectProtocol
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default menu entry used by the 'upload' module for when
|
||||
// no areas are available for the user to upload to
|
||||
fileBaseNoUploadAreasAvail: {
|
||||
desc: File Base
|
||||
art: ULNOAREA
|
||||
config: {
|
||||
pause: true
|
||||
menuFlags: [ "noHistory", "popParent" ]
|
||||
}
|
||||
}
|
||||
|
||||
// default menu entry used by the 'file_transfer_protocol_select' module
|
||||
// when performing user downloads
|
||||
sendFilesToUser: {
|
||||
desc: Downloading
|
||||
module: file_transfer
|
||||
config: {
|
||||
// defaults - generally use extraArgs
|
||||
protocol: zmodem8kSexyz
|
||||
direction: send
|
||||
}
|
||||
}
|
||||
|
||||
// default menu entry used by the 'file_transfer_protocol_select' module
|
||||
// when performing user uploads
|
||||
recvFilesFromUser: {
|
||||
desc: Uploading
|
||||
module: file_transfer
|
||||
config: {
|
||||
// defaults - generally use extraArgs
|
||||
protocol: zmodem8kSexyz
|
||||
direction: recv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prompts: {
|
||||
fileMenuCommand: {
|
||||
art: FILPMPT
|
||||
mci: {
|
||||
TL1: {}
|
||||
ET2: {
|
||||
argName: menuOption
|
||||
width: 20
|
||||
maxLength: 20
|
||||
textStyle: upper
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseRateEntryPrompt: {
|
||||
art: RATEFILE
|
||||
mci: {
|
||||
SM1: {
|
||||
argName: rating
|
||||
items: [ "-----", "*----", "**---", "***--", "****-", "*****" ]
|
||||
}
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
fileBaseTagEntryPrompt: {
|
||||
art: TAGFILE
|
||||
mci: {
|
||||
ET1: {
|
||||
argName: tags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,607 @@
|
|||
{
|
||||
menus: {
|
||||
//
|
||||
// Send telnet connections to matrix where users can login, apply, etc.
|
||||
//
|
||||
telnetConnected: {
|
||||
art: CONNECT
|
||||
next: matrix
|
||||
config: { nextTimeout: 1500 }
|
||||
}
|
||||
|
||||
//
|
||||
// SSH connections are pre-authenticated via the SSH server itself.
|
||||
// Jump directly to either the 2FA/OTP auth or the login sequence
|
||||
// depending on user ACS.
|
||||
//
|
||||
sshConnected: {
|
||||
art: CONNECT
|
||||
next: [
|
||||
{
|
||||
acs: AR2
|
||||
next: loginTwoFactorAuthOTPLoop
|
||||
}
|
||||
{
|
||||
next: fullLoginSequenceLoginArt
|
||||
}
|
||||
]
|
||||
config: { nextTimeout: 1500 }
|
||||
}
|
||||
|
||||
//
|
||||
// Another SSH specialization: If the user logs in with a new user
|
||||
// name (e.g. "new", "apply", ...) they will be directed to the
|
||||
// application process.
|
||||
//
|
||||
sshConnectedNewUser: {
|
||||
art: CONNECT
|
||||
next: newUserApplicationPreSsh
|
||||
config: { nextTimeout: 1500 }
|
||||
}
|
||||
|
||||
// Ye ol' standard matrix
|
||||
matrix: {
|
||||
art: matrix
|
||||
form: {
|
||||
0: {
|
||||
VM: {
|
||||
mci: {
|
||||
VM1: {
|
||||
submit: true
|
||||
focus: true
|
||||
argName: navSelect
|
||||
items: [
|
||||
{
|
||||
text: login
|
||||
data: login
|
||||
}
|
||||
{
|
||||
text: apply
|
||||
data: apply
|
||||
}
|
||||
|
||||
//
|
||||
// To enable the forgot password option, you'll need to have
|
||||
// the web server & email configured. Once that is in place,
|
||||
// uncomment the section below.
|
||||
//
|
||||
// See docs for more information
|
||||
//
|
||||
/*
|
||||
{
|
||||
text: forgot pass
|
||||
data: forgot
|
||||
}
|
||||
*/
|
||||
{
|
||||
text: log off
|
||||
data: logoff
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { navSelect: "login" }
|
||||
action: @menu:login
|
||||
}
|
||||
{
|
||||
value: { navSelect: "apply" }
|
||||
action: @menu:newUserApplicationPre
|
||||
}
|
||||
{
|
||||
value: { navSelect: "forgot" }
|
||||
action: @menu:forgotPassword
|
||||
}
|
||||
{
|
||||
value: { navSelect: "logoff" }
|
||||
action: @menu:logoff
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
login: {
|
||||
art: USERLOG
|
||||
next: [
|
||||
{
|
||||
//
|
||||
// Users with 2FA/OTP enabled *must* go through
|
||||
// an additional OTP authentication step
|
||||
//
|
||||
acs: AR2
|
||||
next: loginTwoFactorAuthOTPLoop
|
||||
}
|
||||
{
|
||||
// ...everyone else can carry on as per usual
|
||||
next: fullLoginSequenceLoginArt
|
||||
}
|
||||
]
|
||||
config: {
|
||||
tooNodeMenu: loginAttemptTooNode
|
||||
inactive: loginAttemptAccountInactive
|
||||
disabled: loginAttemptAccountDisabled
|
||||
locked: loginAttemptAccountLocked
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
maxLength: @config:users.usernameMax
|
||||
argName: username
|
||||
focus: true
|
||||
}
|
||||
ET2: {
|
||||
password: true
|
||||
maxLength: @config:users.passwordMax
|
||||
argName: password
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { password: null }
|
||||
action: @systemMethod:login
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference:common.escToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loginAttemptTooNode: {
|
||||
art: TOONODE
|
||||
config: {
|
||||
cls: true
|
||||
nextTimeout: 2000
|
||||
}
|
||||
next: logoff
|
||||
}
|
||||
|
||||
loginAttemptAccountLocked: {
|
||||
art: ACCOUNTLOCKED
|
||||
config: {
|
||||
cls: true
|
||||
nextTimeout: 2000
|
||||
}
|
||||
next: logoff
|
||||
}
|
||||
|
||||
loginAttemptAccountDisabled: {
|
||||
art: ACCOUNTDISABLED
|
||||
config: {
|
||||
cls: true
|
||||
nextTimeout: 2000
|
||||
}
|
||||
next: logoff
|
||||
}
|
||||
|
||||
loginAttemptAccountInactive: {
|
||||
art: ACCOUNTINACTIVE
|
||||
config: {
|
||||
cls: true
|
||||
nextTimeout: 2000
|
||||
}
|
||||
next: logoff
|
||||
}
|
||||
|
||||
forgotPassword: {
|
||||
desc: Forgot password
|
||||
prompt: forgotPasswordPrompt
|
||||
submit: [
|
||||
{
|
||||
value: { username: null }
|
||||
action: @systemMethod:sendForgotPasswordEmail
|
||||
extraArgs: { next: "forgotPasswordSubmitted" }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
forgotPasswordSubmitted: {
|
||||
desc: Forgot password
|
||||
art: FORGOTPWSENT
|
||||
config: {
|
||||
cls: true
|
||||
pause: true
|
||||
}
|
||||
next: @systemMethod:logoff
|
||||
}
|
||||
|
||||
fullLoginSequenceLoginArt: {
|
||||
desc: Logging In
|
||||
art: WELCOME
|
||||
config: { pause: true }
|
||||
next: fullLoginSequenceLastCallers
|
||||
}
|
||||
|
||||
fullLoginSequenceLastCallers: {
|
||||
desc: Last Callers
|
||||
module: last_callers
|
||||
art: LASTCALL
|
||||
config: {
|
||||
pause: true
|
||||
font: cp437
|
||||
}
|
||||
next: fullLoginSequenceWhosOnline
|
||||
}
|
||||
|
||||
fullLoginSequenceWhosOnline: {
|
||||
desc: Who's Online
|
||||
module: whos_online
|
||||
art: WHOSON
|
||||
config: { pause: true }
|
||||
next: fullLoginSequenceOnelinerz
|
||||
}
|
||||
|
||||
fullLoginSequenceOnelinerz: {
|
||||
desc: Viewing Onelinerz
|
||||
module: onelinerz
|
||||
next: [
|
||||
{
|
||||
// calls >= 2
|
||||
acs: NC2
|
||||
next: fullLoginSequenceNewScanConfirm
|
||||
}
|
||||
{
|
||||
// new users - skip new scan
|
||||
next: fullLoginSequenceUserStats
|
||||
}
|
||||
]
|
||||
config: {
|
||||
cls: true
|
||||
art: {
|
||||
view: ONELINER
|
||||
add: ONEADD
|
||||
}
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: false
|
||||
height: 10
|
||||
}
|
||||
TM2: {
|
||||
argName: addOrExit
|
||||
items: [ "yeah!", "nah" ]
|
||||
"hotKeys" : { "Y" : 0, "N" : 1, "Q" : 1 }
|
||||
submit: true
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { addOrExit: 0 }
|
||||
action: @method:viewAddScreen
|
||||
}
|
||||
{
|
||||
value: { addOrExit: null }
|
||||
action: @systemMethod:nextMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:nextMenu
|
||||
}
|
||||
]
|
||||
},
|
||||
1: {
|
||||
mci: {
|
||||
ET1: {
|
||||
focus: true
|
||||
maxLength: 70
|
||||
argName: oneliner
|
||||
}
|
||||
TL2: {
|
||||
width: 60
|
||||
}
|
||||
TM3: {
|
||||
argName: addOrCancel
|
||||
items: [ "add", "cancel" ]
|
||||
"hotKeys" : { "A" : 0, "C" : 1, "Q" : 1 }
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { addOrCancel: 0 }
|
||||
action: @method:addEntry
|
||||
}
|
||||
{
|
||||
value: { addOrCancel: 1 }
|
||||
action: @method:cancelAdd
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @method:cancelAdd
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fullLoginSequenceNewScanConfirm: {
|
||||
desc: Logging In
|
||||
prompt: loginGlobalNewScan
|
||||
submit: [
|
||||
{
|
||||
value: { promptValue: 0 }
|
||||
action: @menu:fullLoginSequenceNewScan
|
||||
}
|
||||
{
|
||||
value: { promptValue: 1 }
|
||||
action: @menu:fullLoginSequenceUserStats
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
fullLoginSequenceNewScan: {
|
||||
desc: Performing New Scan
|
||||
module: new_scan
|
||||
art: NEWSCAN
|
||||
next: fullLoginSequenceSysStats
|
||||
config: {
|
||||
messageListMenu: newScanMessageList
|
||||
}
|
||||
}
|
||||
|
||||
newScanMessageList: {
|
||||
desc: New Messages
|
||||
module: msg_list
|
||||
art: NEWMSGS
|
||||
config: {
|
||||
menuViewPost: messageAreaViewPost
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: messageIndex
|
||||
}
|
||||
TL6: { }
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { messageIndex: null }
|
||||
action: @method:selectMessage
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape", "q", "shift + q" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
keys: [ "x", "shift + x" ]
|
||||
action: @method:fullExit
|
||||
}
|
||||
{
|
||||
keys: [ "m", "shift + m" ]
|
||||
action: @method:markAllRead
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newScanFileBaseList: {
|
||||
module: file_area_list
|
||||
desc: New Files
|
||||
config: {
|
||||
art: {
|
||||
browse: FNEWBRWSE
|
||||
details: FDETAIL
|
||||
detailsGeneral: FDETGEN
|
||||
detailsNfo: FDETNFO
|
||||
detailsFileList: FDETLST
|
||||
help: FBHELP
|
||||
}
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
MT1: {
|
||||
mode: preview
|
||||
ansiView: true
|
||||
}
|
||||
|
||||
HM2: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: navSelect
|
||||
items: [
|
||||
"prev", "next", "details", "toggle queue", "rate", "help", "quit"
|
||||
]
|
||||
focusItemIndex: 1
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { navSelect: 0 }
|
||||
action: @method:prevFile
|
||||
}
|
||||
{
|
||||
value: { navSelect: 1 }
|
||||
action: @method:nextFile
|
||||
}
|
||||
{
|
||||
value: { navSelect: 2 }
|
||||
action: @method:viewDetails
|
||||
}
|
||||
{
|
||||
value: { navSelect: 3 }
|
||||
action: @method:toggleQueue
|
||||
}
|
||||
{
|
||||
value: { navSelect: 4 }
|
||||
action: @menu:fileBaseGetRatingForSelectedEntry
|
||||
}
|
||||
{
|
||||
value: { navSelect: 5 }
|
||||
action: @method:displayHelp
|
||||
}
|
||||
{
|
||||
value: { navSelect: 6 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "w", "shift + w" ]
|
||||
action: @method:showWebDownloadLink
|
||||
}
|
||||
{
|
||||
keys: [ "escape", "q", "shift + q" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
keys: [ "t", "shift + t" ]
|
||||
action: @method:toggleQueue
|
||||
}
|
||||
{
|
||||
keys: [ "v", "shift + v" ]
|
||||
action: @method:viewDetails
|
||||
}
|
||||
{
|
||||
keys: [ "r", "shift + r" ]
|
||||
action: @menu:fileBaseGetRatingForSelectedEntry
|
||||
}
|
||||
{
|
||||
keys: [ "?" ]
|
||||
action: @method:displayHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
1: {
|
||||
mci: {
|
||||
HM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: navSelect
|
||||
items: [
|
||||
"general", "nfo/readme", "file listing"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
|
||||
2: {
|
||||
// details - general
|
||||
mci: { }
|
||||
}
|
||||
|
||||
3: {
|
||||
// details - nfo/readme
|
||||
mci: {
|
||||
MT1: {
|
||||
mode: preview
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4: {
|
||||
// details - file listing
|
||||
mci: {
|
||||
VM1: { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fullLoginSequenceSysStats: {
|
||||
desc: System Stats
|
||||
art: SYSSTAT
|
||||
config: { pause: true }
|
||||
next: fullLoginSequenceUserStats
|
||||
}
|
||||
|
||||
fullLoginSequenceUserStats: {
|
||||
desc: User Stats
|
||||
art: STATUS
|
||||
config: { pause: true }
|
||||
next: mainMenu
|
||||
}
|
||||
|
||||
//
|
||||
// Empty menu to catch us in a 2FA/OTP auth loop
|
||||
// until the user either authenticates successfully
|
||||
// or the system boots them.
|
||||
//
|
||||
loginTwoFactorAuthOTPLoop: {
|
||||
next: loginTwoFactorAuthOTP
|
||||
}
|
||||
|
||||
loginTwoFactorAuthOTP: {
|
||||
art: 2FAOTP
|
||||
next: fullLoginSequenceLoginArt
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
argName: token
|
||||
focus: true
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { token: null }
|
||||
action: @systemMethod:login2FA_OTP
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
// no turning back at this point...
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:logoff
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
prompts: {
|
||||
loginGlobalNewScan: {
|
||||
art: GNSPMPT
|
||||
mci: {
|
||||
TM1: {
|
||||
argName: promptValue
|
||||
items: [ "yes", "no" ]
|
||||
focus: true
|
||||
hotKeys: { Y: 0, N: 1 }
|
||||
hotKeySubmit: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,816 @@
|
|||
{
|
||||
menus: {
|
||||
messageBaseMainMenu: {
|
||||
art: MSGMNU
|
||||
desc: Message Area
|
||||
prompt: messageBaseMenuPrompt
|
||||
config: {
|
||||
interrupt: realtime
|
||||
}
|
||||
submit: [
|
||||
{
|
||||
value: { command: "P" }
|
||||
action: @menu:messageBaseNewPost
|
||||
}
|
||||
{
|
||||
value: { command: "J" }
|
||||
action: @menu:messageBaseChangeCurrentConference
|
||||
}
|
||||
{
|
||||
value: { command: "C" }
|
||||
action: @menu:messageBaseChangeCurrentArea
|
||||
}
|
||||
{
|
||||
value: { command: "L" }
|
||||
action: @menu:messageBaseMessageList
|
||||
}
|
||||
{
|
||||
value: { command: "<" }
|
||||
action: @systemMethod:prevConf
|
||||
}
|
||||
{
|
||||
value: { command: ">" }
|
||||
action: @systemMethod:nextConf
|
||||
}
|
||||
{
|
||||
value: { command: "[" }
|
||||
action: @systemMethod:prevArea
|
||||
}
|
||||
{
|
||||
value: { command: "]" }
|
||||
action: @systemMethod:nextArea
|
||||
}
|
||||
{
|
||||
value: { command: "D" }
|
||||
action: @menu:messageBaseSetNewScanDate
|
||||
}
|
||||
{
|
||||
value: { command: "S" }
|
||||
action: @menu:messageBaseSearch
|
||||
}
|
||||
{
|
||||
value: { command: "M" }
|
||||
action: @menu:messageBaseMyMessages
|
||||
}
|
||||
{
|
||||
value: { command: "A" }
|
||||
action: @menu:editAutoSignature
|
||||
}
|
||||
{
|
||||
value: { command: "Q" }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
value: { command: "G" }
|
||||
action: @menu:fullLogoffSequence
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
messageBaseNewPost: {
|
||||
desc: Posting message,
|
||||
module: msg_area_post_fse
|
||||
config: {
|
||||
art: {
|
||||
header: MSGEHDR
|
||||
body: MSGBODY
|
||||
footerEditor: MSGEFTR
|
||||
footerEditorMenu: MSGEMFT
|
||||
help: MSGEHLP
|
||||
}
|
||||
editorMode: edit
|
||||
editorType: area
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
TL1: {
|
||||
argName: from
|
||||
}
|
||||
ET2: {
|
||||
argName: to
|
||||
focus: true
|
||||
text: All
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
maxLength: 36
|
||||
}
|
||||
ET3: {
|
||||
argName: subject
|
||||
maxLength: 72
|
||||
submit: true
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
3: [
|
||||
{
|
||||
value: { subject: null }
|
||||
action: @method:headerSubmit
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
1: {
|
||||
"mci" : {
|
||||
MT1: {
|
||||
width: 79
|
||||
argName: message
|
||||
mode: edit
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [ { "value": "message", "action": "@method:editModeEscPressed" } ]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
viewId: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
2: {
|
||||
TLTL: {
|
||||
mci: {
|
||||
TL1: { width: 5 }
|
||||
TL2: { width: 4 }
|
||||
}
|
||||
}
|
||||
}
|
||||
3: {
|
||||
HM: {
|
||||
mci: {
|
||||
HM1: {
|
||||
"items" : [ "save", "discard", "help" ]
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { 1: 0 }
|
||||
action: @method:editModeMenuSave
|
||||
}
|
||||
{
|
||||
value: { 1: 1 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
value: { 1: 2 }
|
||||
action: @method:editModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @method:editModeEscPressed
|
||||
}
|
||||
{
|
||||
keys: [ "?" ]
|
||||
action: @method:editModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageBaseChangeCurrentConference: {
|
||||
art: CCHANGE
|
||||
module: msg_conf_list
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: conf
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { conf: null }
|
||||
action: @method:changeConference
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageBaseChangeCurrentArea: {
|
||||
art: CHANGE
|
||||
module: msg_area_list
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: area
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { area: null }
|
||||
action: @method:changeArea
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageBaseMessageList: {
|
||||
module: msg_list
|
||||
art: MSGLIST
|
||||
config: {
|
||||
menuViewPost: messageAreaViewPost
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: messageIndex
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { message: null }
|
||||
action: @method:selectMessage
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageBaseSetNewScanDate: {
|
||||
module: set_newscan_date
|
||||
desc: Message Base
|
||||
art: SETMNSDATE
|
||||
config: {
|
||||
target: message
|
||||
scanDateFormat: YYYYMMDD
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ME1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: scanDate
|
||||
maskPattern: "####/##/##"
|
||||
}
|
||||
SM2: {
|
||||
argName: targetSelection
|
||||
submit: false
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { scanDate: null }
|
||||
action: @method:scanDateSubmit
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageBaseSearch: {
|
||||
desc: Message Search
|
||||
module: message_base_search
|
||||
art: MSEARCH
|
||||
config: {
|
||||
messageListMenu: messageBaseSearchResultsMessageList
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
focus: true
|
||||
argName: searchTerms
|
||||
}
|
||||
BT2: {
|
||||
argName: search
|
||||
text: search
|
||||
submit: true
|
||||
}
|
||||
SM3: {
|
||||
argName: confTag
|
||||
}
|
||||
SM4: {
|
||||
argName: areaTag
|
||||
}
|
||||
ET5: {
|
||||
argName: toUserName
|
||||
maxLength: @config:users.usernameMax
|
||||
}
|
||||
ET6: {
|
||||
argName: fromUserName
|
||||
maxLength: @config:users.usernameMax
|
||||
}
|
||||
BT7: {
|
||||
argName: advancedSearch
|
||||
text: advanced search
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { search: null }
|
||||
action: @method:search
|
||||
}
|
||||
{
|
||||
value: { advancedSearch: null }
|
||||
action: @method:search
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageBaseSearchResultsMessageList: {
|
||||
desc: Message Search
|
||||
module: msg_list
|
||||
art: MSRCHLST
|
||||
config: {
|
||||
menuViewPost: messageAreaViewPost
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: messageIndex
|
||||
}
|
||||
TL6: {
|
||||
// theme me!
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { messageIndex: null }
|
||||
action: @method:selectMessage
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The message_base_search module looks for this entry by default
|
||||
messageSearchNoResults: {
|
||||
desc: Message Search
|
||||
art: MSRCNORES
|
||||
config: {
|
||||
pause: true
|
||||
}
|
||||
}
|
||||
|
||||
messageBaseMyMessages: {
|
||||
desc: Personal Messages
|
||||
module: my_messages
|
||||
config: {
|
||||
messageListMenu: messageBaseMyMessagesList
|
||||
}
|
||||
}
|
||||
|
||||
messageBaseMyMessagesList: {
|
||||
desc: Personal Messages
|
||||
module: msg_list
|
||||
art: MYMSGLST
|
||||
config: {
|
||||
menuViewPost: messageAreaViewPost
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: messageIndex
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { messageIndex: null }
|
||||
action: @method:selectMessage
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference:common.quitToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editAutoSignature: {
|
||||
desc: Auto Sig Editor
|
||||
module: autosig_edit
|
||||
art: autosig
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
MT1: {
|
||||
argName: signature
|
||||
tabSwitchesView: true
|
||||
}
|
||||
BT2: {
|
||||
text: save
|
||||
argName: save
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { save: null }
|
||||
action: @method:saveChanges
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageAreaViewPost: {
|
||||
module: msg_area_view_fse
|
||||
config: {
|
||||
art: {
|
||||
header: MSGVHDR
|
||||
body: MSGBODY
|
||||
footerView: MSGVFTR
|
||||
help: MSGVHLP
|
||||
},
|
||||
editorMode: view
|
||||
editorType: area
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
// :TODO: ensure this block isn't even req. for theme to apply...
|
||||
}
|
||||
}
|
||||
1: {
|
||||
mci: {
|
||||
MT1: {
|
||||
width: 79
|
||||
mode: preview
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: message
|
||||
action: @method:editModeEscPressed
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
viewId: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
2: {
|
||||
TLTL: {
|
||||
mci: {
|
||||
TL1: { width: 5 }
|
||||
TL2: { width: 4 }
|
||||
}
|
||||
}
|
||||
}
|
||||
4: {
|
||||
mci: {
|
||||
HM1: {
|
||||
// :TODO: (#)Jump/(L)Index (msg list)/Last
|
||||
items: [ "prev", "next", "reply", "quit", "help" ]
|
||||
focusItemIndex: 1
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { 1: 0 }
|
||||
action: @method:prevMessage
|
||||
}
|
||||
{
|
||||
value: { 1: 1 }
|
||||
action: @method:nextMessage
|
||||
}
|
||||
{
|
||||
value: { 1: 2 }
|
||||
action: @method:replyMessage
|
||||
extraArgs: {
|
||||
menu: messageAreaReplyPost
|
||||
}
|
||||
}
|
||||
{
|
||||
value: { 1: 3 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
value: { 1: 4 }
|
||||
action: @method:viewModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "p", "shift + p" ]
|
||||
action: @method:prevMessage
|
||||
}
|
||||
{
|
||||
keys: [ "n", "shift + n" ]
|
||||
action: @method:nextMessage
|
||||
}
|
||||
{
|
||||
keys: [ "r", "shift + r" ]
|
||||
action: @method:replyMessage
|
||||
extraArgs: {
|
||||
menu: messageAreaReplyPost
|
||||
}
|
||||
}
|
||||
{
|
||||
keys: [ "escape", "q", "shift + q" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
keys: [ "?" ]
|
||||
action: @method:viewModeMenuHelp
|
||||
}
|
||||
{
|
||||
keys: [ "down arrow", "up arrow", "page up", "page down" ]
|
||||
action: @method:movementKeyPressed
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageAreaReplyPost: {
|
||||
module: msg_area_post_fse
|
||||
config: {
|
||||
art: {
|
||||
header: MSGEHDR
|
||||
body: MSGBODY
|
||||
quote: MSGQUOT
|
||||
footerEditor: MSGEFTR
|
||||
footerEditorMenu: MSGEMFT
|
||||
help: MSGEHLP
|
||||
}
|
||||
editorMode: edit
|
||||
editorType: area
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
// :TODO: use appropriate system properties for max lengths
|
||||
TL1: {
|
||||
argName: from
|
||||
}
|
||||
ET2: {
|
||||
argName: to
|
||||
focus: true
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
maxLength: 36
|
||||
}
|
||||
ET3: {
|
||||
argName: subject
|
||||
maxLength: 72
|
||||
submit: true
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
TL4: {
|
||||
// :TODO: this is for RE: line (NYI)
|
||||
//width: 27
|
||||
//textOverflow: ...
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
3: [
|
||||
{
|
||||
value: { subject: null }
|
||||
action: @method:headerSubmit
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
1: {
|
||||
mci: {
|
||||
MT1: {
|
||||
width: 79
|
||||
height: 14
|
||||
argName: message
|
||||
mode: edit
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [ { "value": "message", "action": "@method:editModeEscPressed" } ]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ],
|
||||
viewId: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
3: {
|
||||
mci: {
|
||||
HM1: {
|
||||
items: [ "save", "discard", "quote", "help" ]
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { 1: 0 }
|
||||
action: @method:editModeMenuSave
|
||||
}
|
||||
{
|
||||
value: { 1: 1 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
value: { 1: 2 },
|
||||
action: @method:editModeMenuQuote
|
||||
}
|
||||
{
|
||||
value: { 1: 3 }
|
||||
action: @method:editModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @method:editModeEscPressed
|
||||
}
|
||||
{
|
||||
keys: [ "s", "shift + s" ]
|
||||
action: @method:editModeMenuSave
|
||||
}
|
||||
{
|
||||
keys: [ "d", "shift + d" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
keys: [ "q", "shift + q" ]
|
||||
action: @method:editModeMenuQuote
|
||||
}
|
||||
{
|
||||
keys: [ "?" ]
|
||||
action: @method:editModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// Quote builder
|
||||
5: {
|
||||
mci: {
|
||||
MT1: {
|
||||
width: 79
|
||||
height: 7
|
||||
}
|
||||
VM3: {
|
||||
width: 79
|
||||
height: 4
|
||||
argName: quote
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { quote: null }
|
||||
action: @method:appendQuoteEntry
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @method:quoteBuilderEscPressed
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// The 'msg_conf_list' module defaults to looking for
|
||||
// a menu entry of 'changeConfPreArtMenu'. If found,
|
||||
// this menu will be executed upon changing message
|
||||
// conferences using the conference tag as an art spec.
|
||||
//
|
||||
changeMessageConfPreArt: {
|
||||
module: show_art
|
||||
config: {
|
||||
method: messageConf
|
||||
key: confTag
|
||||
pause: true
|
||||
cls: true
|
||||
menuFlags: [ "popParent", "noHistory" ]
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// The 'msg_area_list' module defaults to looking for
|
||||
// a menu entry of 'changeMessageAreaPreArt'. If found,
|
||||
// this menu will be executed upon changing message
|
||||
// areas using the area tag as an art spec.
|
||||
//
|
||||
changeMessageAreaPreArt: {
|
||||
module: show_art
|
||||
config: {
|
||||
method: messageArea
|
||||
key: areaTag
|
||||
pause: true
|
||||
cls: true
|
||||
menuFlags: [ "popParent", "noHistory" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prompts: {
|
||||
messageBaseMenuPrompt: {
|
||||
art: MSGPMPT
|
||||
mci: {
|
||||
//TL1: {}
|
||||
ET2: {
|
||||
argName: command
|
||||
width: 20
|
||||
maxLength: 20
|
||||
submit: true
|
||||
textStyle: upper
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// default prompt entry used by the 'msg_lsit' module
|
||||
deleteMessageFromListPrompt: {
|
||||
art: MSGDELPMPT
|
||||
mci: {
|
||||
TM1: {
|
||||
argName: promptValue
|
||||
items: [ "yes", "no" ]
|
||||
focus: true
|
||||
hotKeys: { Y: 0, N: 1 }
|
||||
hotKeySubmit: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,362 @@
|
|||
{
|
||||
menus: {
|
||||
// A quick preamble - defaults to warning about broken terminals
|
||||
newUserApplicationPre: {
|
||||
art: NEWUSER1
|
||||
next: newUserApplication
|
||||
desc: Applying
|
||||
config: {
|
||||
pause: true
|
||||
cls: true
|
||||
menuFlags: [ "noHistory" ]
|
||||
}
|
||||
}
|
||||
|
||||
newUserApplication: {
|
||||
module: nua
|
||||
art: NUA
|
||||
next: [
|
||||
{
|
||||
// Initial SysOp does not send feedback to themselves
|
||||
acs: ID1
|
||||
next: fullLoginSequenceLoginArt
|
||||
}
|
||||
{
|
||||
// ...everyone else does
|
||||
next: newUserFeedbackToSysOpPreamble
|
||||
}
|
||||
]
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
focus: true
|
||||
argName: username
|
||||
maxLength: @config:users.usernameMax
|
||||
validate: @systemMethod:validateUserNameAvail
|
||||
}
|
||||
ET2: {
|
||||
argName: realName
|
||||
maxLength: @config:users.realNameMax
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
MET3: {
|
||||
argName: birthdate
|
||||
maskPattern: "####/##/##"
|
||||
validate: @systemMethod:validateBirthdate
|
||||
}
|
||||
ME4: {
|
||||
argName: sex
|
||||
maskPattern: A
|
||||
textStyle: upper
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
ET5: {
|
||||
argName: location
|
||||
maxLength: @config:users.locationMax
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
ET6: {
|
||||
argName: affils
|
||||
maxLength: @config:users.affilsMax
|
||||
}
|
||||
ET7: {
|
||||
argName: email
|
||||
maxLength: @config:users.emailMax
|
||||
validate: @systemMethod:validateEmailAvail
|
||||
}
|
||||
ET8: {
|
||||
argName: web
|
||||
maxLength: @config:users.webMax
|
||||
}
|
||||
ET9: {
|
||||
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
|
||||
items: [ "apply", "cancel" ]
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { "submission" : 0 }
|
||||
action: @method:submitApplication
|
||||
extraArgs: {
|
||||
inactive: userNeedsActivated
|
||||
error: newUserCreateError
|
||||
}
|
||||
}
|
||||
{
|
||||
value: { "submission" : 1 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: @reference:common.escToPrev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A quick preamble - defaults to warning about broken terminals (SSH version)
|
||||
newUserApplicationPreSsh: {
|
||||
art: NEWUSER1
|
||||
next: newUserApplicationSsh
|
||||
desc: Applying
|
||||
config: {
|
||||
pause: true
|
||||
cls: true
|
||||
menuFlags: [ "noHistory" ]
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SSH specialization of NUA
|
||||
// Canceling this form logs off vs falling back to matrix
|
||||
//
|
||||
newUserApplicationSsh: {
|
||||
module: nua
|
||||
art: NUA
|
||||
fallback: logoff
|
||||
next: newUserFeedbackToSysOpPreamble
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
focus: true
|
||||
argName: username
|
||||
maxLength: @config:users.usernameMax
|
||||
validate: @systemMethod:validateUserNameAvail
|
||||
}
|
||||
ET2: {
|
||||
argName: realName
|
||||
maxLength: @config:users.realNameMax
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
MET3: {
|
||||
argName: birthdate
|
||||
maskPattern: "####/##/##"
|
||||
validate: @systemMethod:validateBirthdate
|
||||
}
|
||||
ME4: {
|
||||
argName: sex
|
||||
maskPattern: A
|
||||
textStyle: upper
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
ET5: {
|
||||
argName: location
|
||||
maxLength: @config:users.locationMax
|
||||
validate: @systemMethod:validateNonEmpty
|
||||
}
|
||||
ET6: {
|
||||
argName: affils
|
||||
maxLength: @config:users.affilsMax
|
||||
}
|
||||
ET7: {
|
||||
argName: email
|
||||
maxLength: @config:users.emailMax
|
||||
validate: @systemMethod:validateEmailAvail
|
||||
}
|
||||
ET8: {
|
||||
argName: web
|
||||
maxLength: @config:users.webMax
|
||||
}
|
||||
ET9: {
|
||||
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
|
||||
items: [ "apply", "cancel" ]
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { "submission" : 0 }
|
||||
action: @method:submitApplication
|
||||
extraArgs: {
|
||||
inactive: userNeedsActivated
|
||||
error: newUserCreateError
|
||||
}
|
||||
}
|
||||
{
|
||||
value: { "submission" : 1 }
|
||||
action: @systemMethod:logoff
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:logoff
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newUserFeedbackToSysOpPreamble: {
|
||||
art: LETTER
|
||||
config: { pause: true }
|
||||
next: newUserFeedbackToSysOp
|
||||
}
|
||||
|
||||
newUserFeedbackToSysOp: {
|
||||
desc: Feedback to SysOp
|
||||
module: msg_area_post_fse
|
||||
next: [
|
||||
{
|
||||
acs: AS2
|
||||
next: fullLoginSequenceLoginArt
|
||||
}
|
||||
{
|
||||
next: newUserInactiveDone
|
||||
}
|
||||
]
|
||||
config: {
|
||||
art: {
|
||||
header: MSGEHDR
|
||||
body: MSGBODY
|
||||
footerEditor: MSGEFTR
|
||||
footerEditorMenu: MSGEMFT
|
||||
help: MSGEHLP
|
||||
},
|
||||
editorMode: edit
|
||||
editorType: email
|
||||
messageAreaTag: private_mail
|
||||
toUserId: 1 /* always to +op */
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
TL1: {
|
||||
argName: from
|
||||
}
|
||||
ET2: {
|
||||
argName: to
|
||||
focus: true
|
||||
text: @sysStat:sysop_username
|
||||
maxLength: 36
|
||||
// :TODO: readOnly: true
|
||||
}
|
||||
ET3: {
|
||||
argName: subject
|
||||
maxLength: 72
|
||||
submit: true
|
||||
text: New user feedback
|
||||
validate: @systemMethod:validateMessageSubject
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
3: [
|
||||
{
|
||||
value: { subject: null }
|
||||
action: @method:headerSubmit
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
1: {
|
||||
mci: {
|
||||
MT1: {
|
||||
width: 79
|
||||
argName: message
|
||||
mode: edit
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: message
|
||||
action: @method:editModeEscPressed
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
viewId: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
2: {
|
||||
TLTL: {
|
||||
mci: {
|
||||
TL1: {
|
||||
width: 5
|
||||
}
|
||||
TL2: {
|
||||
width: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3: {
|
||||
HM: {
|
||||
mci: {
|
||||
HM1: {
|
||||
// :TODO: clear
|
||||
items: [ "save", "help" ]
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { 1: 0 }
|
||||
action: @method:editModeMenuSave
|
||||
}
|
||||
{
|
||||
value: { 1: 1 }
|
||||
action: @method:editModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @method:editModeEscPressed
|
||||
}
|
||||
{
|
||||
keys: [ "?" ]
|
||||
action: @method:editModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newUserInactiveDone: {
|
||||
desc: Finished with NUA
|
||||
art: DONE
|
||||
config: { pause: true }
|
||||
next: @menu:logoff
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
{
|
||||
menus: {
|
||||
privateMailMenu: {
|
||||
art: MAILMNU
|
||||
desc: Private Mail
|
||||
prompt: menuCommand
|
||||
config: {
|
||||
interrupt: realtime
|
||||
}
|
||||
submit: [
|
||||
{
|
||||
value: { command: "C" }
|
||||
action: @menu:privateMailMenuCreateMessage
|
||||
}
|
||||
{
|
||||
value: { command: "I" }
|
||||
action: @menu:privateMailMenuInbox
|
||||
}
|
||||
{
|
||||
value: { command: "Q" }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
value: { command: "G" }
|
||||
action: @menu:fullLogoffSequence
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
privateMailMenuCreateMessage: {
|
||||
desc: Mailing Someone
|
||||
module: msg_area_post_fse
|
||||
config: {
|
||||
art: {
|
||||
header: MSGEHDR
|
||||
body: MSGBODY
|
||||
footerEditor: MSGEFTR
|
||||
footerEditorMenu: MSGEMFT
|
||||
help: MSGEHLP
|
||||
},
|
||||
editorMode: edit
|
||||
editorType: email
|
||||
messageAreaTag: private_mail
|
||||
}
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
TL1: {
|
||||
argName: from
|
||||
}
|
||||
ET2: {
|
||||
argName: to
|
||||
focus: true
|
||||
validate: @systemMethod:validateGeneralMailAddressedTo
|
||||
maxLength: 36
|
||||
}
|
||||
ET3: {
|
||||
argName: subject
|
||||
maxLength: 72
|
||||
submit: true
|
||||
validate: @systemMethod:validateMessageSubject
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
3: [
|
||||
{
|
||||
value: { subject: null }
|
||||
action: @method:headerSubmit
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: @reference: common.escToPrev
|
||||
}
|
||||
1: {
|
||||
mci: {
|
||||
MT1: {
|
||||
width: 79
|
||||
argName: message
|
||||
mode: edit
|
||||
}
|
||||
}
|
||||
|
||||
submit: {
|
||||
*: [ { value: "message", action: "@method:editModeEscPressed" } ]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
viewId: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
2: {
|
||||
TLTL: {
|
||||
mci: {
|
||||
TL1: {
|
||||
width: 5
|
||||
}
|
||||
TL2: {
|
||||
width: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3: {
|
||||
HM: {
|
||||
mci: {
|
||||
HM1: {
|
||||
// :TODO: clear
|
||||
items: [ "save", "discard", "help" ]
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { 1: 0 }
|
||||
action: @method:editModeMenuSave
|
||||
}
|
||||
{
|
||||
value: { 1: 1 }
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
value: { 1: 2 }
|
||||
action: @method:editModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @method:editModeEscPressed
|
||||
}
|
||||
{
|
||||
keys: [ "?" ]
|
||||
action: @method:editModeMenuHelp
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
privateMailMenuInbox: {
|
||||
module: msg_list
|
||||
art: PRVMSGLIST
|
||||
config: {
|
||||
menuViewPost: messageAreaViewPost
|
||||
messageAreaTag: private_mail
|
||||
}
|
||||
form: {
|
||||
0: { // main list
|
||||
mci: {
|
||||
VM1: {
|
||||
focus: true
|
||||
submit: true
|
||||
argName: messageIndex
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { messageIndex: null }
|
||||
action: @method:selectMessage
|
||||
}
|
||||
]
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape", "q", "shift + q" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
{
|
||||
keys: [ "delete", "d", "shift + d" ]
|
||||
action: @method:deleteSelected
|
||||
}
|
||||
]
|
||||
}
|
||||
1: { // delete prompt form
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { promptValue: 0 }
|
||||
action: @method:deleteMessageYes
|
||||
}
|
||||
{
|
||||
value: { promptValue: 1 }
|
||||
action: @method:deleteMessageNo
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,294 +0,0 @@
|
|||
{
|
||||
/*
|
||||
./\/\.' ENiGMA½ Prompt Configuration -/--/-------- - -- -
|
||||
|
||||
_____________________ _____ ____________________ __________\_ /
|
||||
\__ ____/\_ ____ \ /____/ / _____ __ \ / ______/ // /___jp!
|
||||
// __|___// | \// |// | \// | | \// \ /___ /_____
|
||||
/____ _____| __________ ___|__| ____| \ / _____ \
|
||||
---- \______\ -- |______\ ------ /______/ ---- |______\ - |______\ /__/ // ___/
|
||||
/__ _\
|
||||
<*> ENiGMA½ // HTTPS://GITHUB.COM/NUSKOOLER/ENIGMA-BBS <*> /__/
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This configuration is in HJSON (http://hjson.org/) format. Strict to-spec
|
||||
JSON is also perfectly valid. Use 'hjson' from npm to convert to/from JSON.
|
||||
|
||||
See http://hjson.org/ for more information and syntax.
|
||||
|
||||
|
||||
If you haven't yet, copy the conents of this file to something like
|
||||
sick_board_prompt.hjson. Point to it via config.hjson using the
|
||||
'general.promptFile' key:
|
||||
|
||||
general: { promptFile: "sick_board_prompt.hjson" }
|
||||
|
||||
*/
|
||||
// :TODO: this entire file needs cleaned up a LOT
|
||||
// :TODO: Convert all of this to HJSON
|
||||
prompts: {
|
||||
userCredentials: {
|
||||
"art" : "usercred",
|
||||
"mci" : {
|
||||
"ET1" : {
|
||||
"argName" : "username",
|
||||
"maxLength" : "@config:users.usernameMax"
|
||||
},
|
||||
"ET2" : {
|
||||
"submit" : true,
|
||||
"argName" : "password",
|
||||
"password" : true,
|
||||
"maxLength" : "@config:users.passwordMax"
|
||||
}
|
||||
}
|
||||
},
|
||||
"userLoginCredentials" : {
|
||||
"art" : "USRCRED",
|
||||
"mci" : {
|
||||
"ET1" : {
|
||||
"argName" : "username",
|
||||
"maxLength" : "@config:users.usernameMax"
|
||||
},
|
||||
"ET2" : {
|
||||
"submit" : true,
|
||||
"argName" : "password",
|
||||
"password" : true,
|
||||
"maxLength" : "@config:users.passwordMax"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
logoffConfirmation: {
|
||||
art: LOGPMPT
|
||||
mci: {
|
||||
TM1: {
|
||||
argName: promptValue
|
||||
items: [ "yes", "no" ]
|
||||
focus: true
|
||||
hotKeys: { Y: 0, N: 1 }
|
||||
hotKeySubmit: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loginSequenceFlavorSelect: {
|
||||
art: LOGINSEL
|
||||
mci: {
|
||||
TM1: {
|
||||
argName: promptValue
|
||||
items: [ "yes", "no" ]
|
||||
focus: true
|
||||
focusItemIndex: 1
|
||||
hotKeys: { Y: 0, N: 1 }
|
||||
hotKeySubmit: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loginGlobalNewScan: {
|
||||
art: GNSPMPT
|
||||
mci: {
|
||||
TM1: {
|
||||
argName: promptValue
|
||||
items: [ "yes", "no" ]
|
||||
focus: true
|
||||
hotKeys: { Y: 0, N: 1 }
|
||||
hotKeySubmit: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menuCommand: {
|
||||
art: MNUPRMT
|
||||
mci: {
|
||||
TL1: {
|
||||
// theme me!
|
||||
}
|
||||
ET2: {
|
||||
argName: command
|
||||
width: 20
|
||||
maxLength: 20
|
||||
submit: true
|
||||
textStyle: upper
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
messageMenuCommand: {
|
||||
art: MSGPMPT
|
||||
mci: {
|
||||
TL1: {
|
||||
// theme me!
|
||||
}
|
||||
ET2: {
|
||||
argName: command
|
||||
width: 20
|
||||
maxLength: 20
|
||||
submit: true
|
||||
textStyle: upper
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
deleteMessageFromListPrompt: {
|
||||
art: MSGDELPMPT
|
||||
mci: {
|
||||
TM1: {
|
||||
argName: promptValue
|
||||
items: [ "yes", "no" ]
|
||||
focus: true
|
||||
hotKeys: { Y: 0, N: 1 }
|
||||
hotKeySubmit: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"newAreaPostPrompt" : {
|
||||
"art" : "message_area_new_post",
|
||||
"mci" : {
|
||||
"ET1" : {
|
||||
"argName" : "to",
|
||||
"width" : 20
|
||||
},
|
||||
"ET2" : {
|
||||
"argName" : "subject",
|
||||
"width" : 20
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
forgotPasswordPrompt: {
|
||||
art: FORGOTPW
|
||||
mci: {
|
||||
ET1: {
|
||||
argName: username
|
||||
maxLength: @config:users.usernameMax
|
||||
width: 32
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// File Base Related
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
fileMenuCommand: {
|
||||
art: FILPMPT
|
||||
mci: {
|
||||
TL1: {}
|
||||
ET2: {
|
||||
argName: menuOption
|
||||
width: 20
|
||||
maxLength: 20
|
||||
textStyle: upper
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBaseRateEntryPrompt: {
|
||||
art: RATEFILE
|
||||
mci: {
|
||||
SM1: {
|
||||
argName: rating
|
||||
items: [ "-----", "*----", "**---", "***--", "****-", "*****" ]
|
||||
}
|
||||
}
|
||||
|
||||
actionKeys: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
fileBaseTagEntryPrompt: {
|
||||
art: TAGFILE
|
||||
mci: {
|
||||
ET1: {
|
||||
argName: tags
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Standard / Required
|
||||
//
|
||||
// Prompts in this section are considered "standard" and are required
|
||||
// to be present
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
pause: {
|
||||
//
|
||||
// Any menu 'pause' will use this prompt
|
||||
//
|
||||
art: pause
|
||||
config: {
|
||||
trailingLF: no
|
||||
}
|
||||
/*
|
||||
"mci" : {
|
||||
// :TODO: Need special pause for a key MCI
|
||||
// e.g. %PA -> themed prompt
|
||||
}
|
||||
|
||||
...or maybe pause should just be special:
|
||||
{
|
||||
...
|
||||
"pause" true
|
||||
// uses theme pause which can be art/inline/etc.
|
||||
|
||||
}
|
||||
|
||||
... better, a special prompt
|
||||
|
||||
GetKeyView
|
||||
* echoKey : false
|
||||
|
||||
*/
|
||||
}
|
||||
/*,
|
||||
"standard" : {
|
||||
// any menu 'pause' will display this, pause for a key, then erase and move on
|
||||
"pause" : {
|
||||
"art" : "pause"
|
||||
// :TODO: support mci mappings
|
||||
}
|
||||
},
|
||||
"custom" : {
|
||||
|
||||
}*/
|
||||
/*
|
||||
see notes in menu_module.js also
|
||||
...how to allow for this to come from the theme first???
|
||||
same as custom vc drawing/etc.? ...
|
||||
|
||||
{
|
||||
"theme" : {
|
||||
"inlineArt" : {
|
||||
"something" : "%MC and |01Pipe codes here"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"pause" : {
|
||||
"art" : "@inline:simplePrompt",
|
||||
// support pipe codes & MCI
|
||||
"simplePrompt" : "--------/ Pause /----------------",
|
||||
"mci" : {
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue