mirror of
https://github.com/NuSkooler/enigma-bbs.git
synced 2025-07-30 14:36:19 +02:00
Automatically generate the navigation
This commit is contained in:
parent
4793ad0492
commit
b5b0cc3ac5
94 changed files with 236 additions and 335 deletions
80
docs/_docs/configuration/acs.md
Normal file
80
docs/_docs/configuration/acs.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
layout: page
|
||||
title: Access Condition System (ACS)
|
||||
---
|
||||
|
||||
## Access Condition System (ACS)
|
||||
ENiGMA½ uses an Access Condition System (ACS) that is both familiar to oldschool BBS operators and has it's own style. With ACS, SysOp's are able to control access to various areas of the system based on various conditions such as group membership, connection type, etc. Various touch points in the system are configured to allow for `acs` checks. In some cases ACS is a simple boolean check while others (via ACS blocks) allow to define what conditions must be true for certain _rights_ such as `read` and `write` (though others exist as well).
|
||||
|
||||
## ACS Codes
|
||||
The following are ACS codes available as of this writing:
|
||||
|
||||
| Code | Condition |
|
||||
|------|-------------|
|
||||
| LC | Connection is local |
|
||||
| AG<i>age</i> | User's age is >= _age_ |
|
||||
| AS<i>status</i>, AS[_status_,...] | User's account status is _group_ or one of [_group_,...] |
|
||||
| EC<i>encoding</i> | Terminal encoding is set to _encoding_ where `0` is `CP437` and `1` is `UTF-8` |
|
||||
| GM[_group_,...] | User belongs to one of [_group_,...] |
|
||||
| NN<i>node</i>, NN[_node_,...] | Current node is _node_ or one of [_node_,...] |
|
||||
| NP<i>posts</i> | User's number of message posts is >= _posts_ |
|
||||
| NC<i>calls</i> | User's number of calls is >= _calls_ |
|
||||
| SC | Connection is considered secure (SSL, secure WebSockets, etc.) |
|
||||
| TH<i>height</i> | Terminal height is >= _height_ |
|
||||
| TW<i>width</i> | Terminal width is >= _width_ |
|
||||
| TM[_themeId_,...] | User's current theme ID is one of [_themeId_,...] (e.g. `luciano_blocktronics`) |
|
||||
| TT[_termType_,...] | User's current terminal type is one of [_termType_,...] (`ANSI-BBS`, `utf8`, `xterm`, etc.) |
|
||||
| ID<i>id</i>, ID[_id_,...] | User's ID is _id_ or oen of [_id_,...] |
|
||||
| WD<i>weekDay</i>, WD[_weekDay_,...] | Current day of week is _weekDay_ or one of [_weekDay_,...] where `0` is Sunday, `1` is Monday, and so on. |
|
||||
| AA<i>days</i> | Account is >= _days_ old |
|
||||
| BU<i>bytes</i> | User has uploaded >= _bytes_ |
|
||||
| UP<i>uploads</i> | User has uploaded >= _uploads_ files |
|
||||
| BD<i>bytes</i> | User has downloaded >= _bytes_ |
|
||||
| DL<i>downloads</i> | User has downloaded >= _downloads_ files |
|
||||
| NR<i>ratio</i> | User has upload/download count ratio >= _ratio_ |
|
||||
| KR<i>ratio</i> | User has a upload/download byte ratio >= _ratio_ |
|
||||
| PC<i>ratio</i> | User has a post/call ratio >= _ratio_ |
|
||||
| MM<i>minutes</i> | It is currently >= _minutes_ past midnight (system time) |
|
||||
| AC<i>achievementCount</i> | User has >= _achievementCount_ achievements |
|
||||
| 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.
|
||||
|
||||
The following logical operators are supported:
|
||||
* `!` NOT
|
||||
* `|` OR
|
||||
* `&` AND (this is the default)
|
||||
|
||||
ENiGMA½ also supports groupings using `(` and `)`. Lastly, some ACS codes allow for lists of acceptable values using `[` and `]` — for example, `GM[users,sysops]`.
|
||||
|
||||
### Example ACS Strings
|
||||
* `NC2`: User must have called two more more times for the check to return true (to pass)
|
||||
* `ID1`: User must be ID 1 (the +op)
|
||||
* `GM[elite,power]`: User must be a member of the `elite` or `power` user group (they could be both)
|
||||
* `ID1|GM[co-op]`: User must be ID 1 (SysOp!) or belong to the `co-op` group
|
||||
* `!TH24`: Terminal height must NOT be 24
|
||||
|
||||
## ACS Blocks
|
||||
Some areas of the system require more than a single ACS string. In these situations an *ACS block* is used to allow for finer grain control. As an example, consider the following file area `acs` block:
|
||||
```hjson
|
||||
acs: {
|
||||
read: GM[users]
|
||||
write: GM[sysops,co-ops]
|
||||
download: GM[elite-users]
|
||||
}
|
||||
```
|
||||
|
||||
All `users` can read (see) the area, `sysops` and `co-ops` can write (upload), and only members of the `elite-users` group can download.
|
||||
|
||||
## ACS Touch Points
|
||||
The following touch points exist in the system. Many more are planned:
|
||||
|
||||
* [Message conferences and areas](../messageareas/configuring-a-message-area.md)
|
||||
* [File base areas](../filebase/first-file-area.md) and [Uploads](../filebase/uploads.md)
|
||||
* Menus within [Menu HJSON (menu.hjson)](menu-hjson.md)
|
||||
|
||||
See the specific areas documentation for information on available ACS checks.
|
57
docs/_docs/configuration/archivers.md
Normal file
57
docs/_docs/configuration/archivers.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
layout: page
|
||||
title: Archivers
|
||||
---
|
||||
|
||||
## Archivers
|
||||
ENiGMA½ can detect and process various archive formats such as zip and arj for a variety of tasks from file upload processing to EchoMail bundle compress/decompression. The `archives` section of `config.hjson` is used to override defaults, add new handlers, and so on.
|
||||
|
||||
Archivers are manged via the `archives:archivers` configuration block of `config.hjson`. Each entry in this section defines an **external archiver** that can be referenced in other sections of `config.hjson` as and in code. Entries define how to `compress`, `decompress` (a full archive), `list`, and `extract` (specific files from an archive).
|
||||
|
||||
:bulb: Generally you do not need to anything beyond installing supporting binaries. No `config.hjson` editing necessary; Please see [External Binaries](external-binaries.md)!
|
||||
|
||||
### Archiver Configuration
|
||||
Archiver entries in `config.hjson` are mostly self explanatory with the exception of `list` commands that require some additional information. The `args` member for an entry is an array of arguments to pass to `cmd`. Some variables are available to `args` that will be expanded by the system:
|
||||
|
||||
* `{archivePath}` (all): Path to the archive
|
||||
* `{fileList}` (compress, extract): List of file(s) to compress or extract
|
||||
* `{extractPath}` (decompress, extract): Path to extract *to*
|
||||
|
||||
For `list` commands, the `entryMatch` key must be provided. This key should provide a regular expression that matches two sub groups: One for uncompressed file byte sizes (sub group 1) and the other for file names (sub group 2). An optional `entryGroupOrder` can be supplied to change the default sub group order.
|
||||
|
||||
#### Example Archiver Configuration
|
||||
```
|
||||
7Zip: {
|
||||
compress: {
|
||||
cmd: 7za,
|
||||
args: [ "a", "-tzip", "{archivePath}", "{fileList}" ]
|
||||
}
|
||||
decompress: {
|
||||
cmd: 7za,
|
||||
args: [ "e", "-o{extractPath}", "{archivePath}" ]
|
||||
}
|
||||
list: {
|
||||
cmd: 7za,
|
||||
args: [ "l", "{archivePath}" ]
|
||||
entryMatch: "^[0-9]{4}-[0-9]{2}-[0-9]{2}\\s[0-9]{2}:[0-9]{2}:[0-9]{2}\\s[A-Za-z\\.]{5}\\s+([0-9]+)\\s+[0-9]+\\s+([^\\r\\n]+)$",
|
||||
}
|
||||
extract: {
|
||||
cmd: 7za,
|
||||
args [ "e", "-o{extractPath}", "{archivePath}", "{fileList}" ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Archive Formats
|
||||
Archive formats can be defined such that ENiGMA½ can detect them by signature or extension, then utilize the correct *archiver* to process them. Formats are defined in the `archives:formats` key in `config.hjson`. Many differnet types come pre-configured (see `core/config_default.js`).
|
||||
|
||||
### Example Archive Format Configuration
|
||||
```
|
||||
zip: {
|
||||
sig: "504b0304" /* byte signature in HEX */
|
||||
offset: 0
|
||||
exts: [ "zip" ]
|
||||
handler: 7Zip /* points to a defined archiver */
|
||||
desc: "ZIP Archive"
|
||||
}
|
||||
```
|
23
docs/_docs/configuration/colour-codes.md
Normal file
23
docs/_docs/configuration/colour-codes.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
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 onelinerz, rumourz, full screen editor etc.
|
||||
|
||||
## Usage
|
||||
When ENiGMA½ encounters colour codes in strings, they'll be processed in order and combined where possible.
|
||||
|
||||
For example:
|
||||
|
||||
`|15|17Example` - white text on a blue background
|
||||
|
||||
`|10|23Example` - light green text on a light grey background
|
||||
|
||||
|
||||
## Colour Code Reference
|
||||
|
||||
:warning: Colour codes |24 to |31 are considered "blinking" or "iCE" colour codes. On terminals that support them they'll
|
||||
be shown as the correct colours - for terminals that don't, or are that are set to "blinking" mode - they'll blink!
|
||||
|
||||

|
||||
|
127
docs/_docs/configuration/config-files.md
Normal file
127
docs/_docs/configuration/config-files.md
Normal file
|
@ -0,0 +1,127 @@
|
|||
---
|
||||
layout: page
|
||||
title: Configuration Files
|
||||
---
|
||||
## General Information
|
||||
ENiGMA½ configuration files such as the [system config](config-hjson.md), [menus](menu-hjson.md) and [themes](../art/themes.md) are formatted in the [HJSON format](hjson.md).
|
||||
|
||||
## Hot-Reload
|
||||
Nearly all of ENiGMA½'s configuration can be hot-reloaded. That is, a live system can have it's configuration modified and it will be loaded in place.
|
||||
|
||||
:bulb: [Monitoring live logs](../troubleshooting/monitoring-logs.md) is useful when making live changes. The system will complain if something is wrong!
|
||||
|
||||
## Common Directives
|
||||
### Includes
|
||||
Most configuration files offer an `includes` directive that allows users to break up large configuration files into smaller and organized parts. For example, consider a system with many menus/screens. Instead of a single `menu.hjson`, the SysOp may break this into `message-base.hjson`, `file-base.hjson`, etc.
|
||||
|
||||
The `includes` directive may be used the top-level scope of a configuration file:
|
||||
```hjson
|
||||
// menu.hjson
|
||||
{
|
||||
includes: [
|
||||
message-base.hjson
|
||||
file-base.hjson
|
||||
]
|
||||
|
||||
menus: {
|
||||
someOtherMenu: {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```hjson
|
||||
// message-base.hjson
|
||||
{
|
||||
menus: {
|
||||
someMessageMenu: {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### References
|
||||
Often times in a configuration you will find that you're repeating yourself quite a bit. ENiGMA½ provides an `@reference` that can help with this in the form of `@reference:dot.path.to.section`.
|
||||
|
||||
Consider `actionKeys` in a menu. Often times you may show a screen and the user presses `Q` or `ESC` to fall back to the previous. Instead of repeating this in many menus, a generic block can be referenced:
|
||||
|
||||
```hjson
|
||||
{
|
||||
// note that 'recycle' here is arbitrary;
|
||||
// only 'menus' and 'prompts' is reserved at this level.
|
||||
recycle: {
|
||||
prevMenu: [
|
||||
{
|
||||
keys: [ "escape" ]
|
||||
action: @systemMethod:prevMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
menus: {
|
||||
someMenu: {
|
||||
form: {
|
||||
0: {
|
||||
actionKeys: @reference:recycle.prevMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:information_source: An unresolved `@reference` will be left intact.
|
||||
|
||||
### Environment Variables
|
||||
Especially in a container environment such as [Docker](../installation/docker.md), environment variable access in configuration files can become very handy. ENiGMA½ provides a flexible way to access variables using the `@environment` directive. The most basic form of `@environment:VAR_NAME` produces a string value. Additionally a `:type` suffix can be supplied to coerece the value to a particular type. Variables pointing to a comma separated list can be turned to arrays using an additional `:array` suffix.
|
||||
|
||||
Below is a table of the various forms:
|
||||
|
||||
| Form | Variable Value | Produces |
|
||||
|------|----------------|----------|
|
||||
| `@environment:SOME_VAR` | "Foo" | `"Foo"` (without quotes) |
|
||||
| `@environment:SOME_VAR` | "123" | `"123"` (without quotes) |
|
||||
| `@environment:SOME_VAR:string` | "Bar" | `"Bar"` (without quotes) |
|
||||
| `@environment:SOME_VAR:string:array` | "Foo,Bar" | `[ 'Foo', 'Bar' ]` |
|
||||
| `@environment:SOME_VAR:boolean` | "1" | `true` |
|
||||
| `@environment:SOME_VAR:boolean` | "True" | `true` |
|
||||
| `@environment:SOME_VAR:boolean` | "false" | `false` |
|
||||
| `@environment:SOME_VAR:boolean` | "cat" | `false` |
|
||||
| `@environment:SOME_VAR:boolean:array` | "True,false,TRUE" | `[ true, false, true ]` |
|
||||
| `@environment:SOME_VAR:number` | "123" | `123` |
|
||||
| `@environment:SOME_VAR:number:array` | "123,456" | `[ 123, 456 ]` |
|
||||
| `@environment:SOME_VAR:number` | "kitten" | (invalid) |
|
||||
| `@environment:SOME_VAR:object` | '{"a":"b"}' | `{ 'a' : 'b' }` |
|
||||
| `@environment:SOME_VAR:object:array` | '{"a":"b"},{"c":"d"}' | `[ { 'a' : 'b' }, { 'c' : 'd' } ]` |
|
||||
| `@environment:SOME_VAR:timestamp` | "2020-01-05" | A [moment](https://momentjs.com/) object representing 2020-01-05 |
|
||||
| `@environment:SOME_VAR:timestamp:array` | "2020-01-05,2016-05-16T01:15:37'" | An array of [moment](https://momentjs.com/) objects representing 2020-01-05 and 2016-05-16T01:15:37 |
|
||||
|
||||
:bulb: `bool` may be used as an alias to `boolean`.
|
||||
|
||||
:bulb: `timestamp` values can be in any form that [moment can parse](https://momentjs.com/docs/#/parsing/).
|
||||
|
||||
:information_source: An unresolved or invalid `@environment` will be left intact.
|
||||
|
||||
Consider the following fragment:
|
||||
```hjson
|
||||
{
|
||||
foo: {
|
||||
bar: @environment:BAR_VAR:number
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If the environment has `BAR_VAR=1337`, this would produce:
|
||||
```hjson
|
||||
{
|
||||
foo: {
|
||||
bar: 1337
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## See Also
|
||||
* [System Configuration](config-hjson.md)
|
||||
* [Menu Configuration](menu-hjson.md)
|
||||
* [The HJSON Format](hjson.md)
|
50
docs/_docs/configuration/config-hjson.md
Normal file
50
docs/_docs/configuration/config-hjson.md
Normal file
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
layout: page
|
||||
title: System Configuration
|
||||
---
|
||||
## System Configuration
|
||||
The main system configuration file, `config.hjson` both overrides defaults and provides additional configuration such as message areas. Defaults lived in `core/config_default.js`.
|
||||
|
||||
The default path is `/enigma-bbs/config/config.hjson` though this can be overridden using the `--config` parameter when invoking `main.js`.
|
||||
|
||||
:information_source: See also [Configuration Files](config-files.md). Additionally [HJSON General Information](hjson.md) may be helpful for more information on the HJSON format.
|
||||
|
||||
### Creating a Configuration
|
||||
Your initial configuration skeleton should be created using the `oputil.js` command line utility. From your enigma-bbs root directory:
|
||||
```
|
||||
./oputil.js config new
|
||||
```
|
||||
|
||||
You will be asked a series of questions to create an initial configuration.
|
||||
|
||||
### Overriding Defaults
|
||||
The file `core/config_default.js` provides various defaults to the system that you can override via `config.hjson`. For example, the default system name is defined as follows:
|
||||
```javascript
|
||||
general : {
|
||||
boardName : 'Another Fine ENiGMA½ System'
|
||||
}
|
||||
```
|
||||
|
||||
To override this for your own board, in `config.hjson`:
|
||||
```hjson
|
||||
general: {
|
||||
boardName: Super Fancy BBS
|
||||
}
|
||||
```
|
||||
|
||||
(Note the very slightly [HJSON](hjson.md) different syntax. **You can use standard JSON if you wish!**)
|
||||
|
||||
While not everything that is available in your `config.hjson` file can be found defaulted in `core/config_default.js`, a lot is. [Poke around and see what you can find](https://github.com/NuSkooler/enigma-bbs/blob/master/core/config_default.js)!
|
||||
|
||||
### Configuration Sections
|
||||
Below is a list of various configuration sections. There are many more, but this should get you started:
|
||||
|
||||
* [ACS](acs.md)
|
||||
* [Archivers](archivers.md): Set up external archive utilities for handling things like ZIP, ARJ, RAR, and so on.
|
||||
* [Email](email.md): System email support.
|
||||
* [Event Scheduler](event-scheduler.md): Set up events as you see fit!
|
||||
* [File Base](../filebase/index.md)
|
||||
* [File Transfer Protocols](file-transfer-protocols.md): Oldschool file transfer protocols such as X/Y/Z-Modem!
|
||||
* [Message Areas](../messageareas/configuring-a-message-area.md), [Networks](../messageareas/message-networks.md), [NetMail](../messageareas/netmail.md), etc.
|
||||
* ...and a **lot** more! Explore the docs! If you can't find something, please contact us!
|
||||
|
14
docs/_docs/configuration/creating-config.md
Normal file
14
docs/_docs/configuration/creating-config.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
layout: page
|
||||
title: Creating Initial Config Files
|
||||
---
|
||||
Configuration files in ENiGMA½ are simple UTF-8 encoded [HJSON](http://hjson.org/) files. HJSON is just like JSON but simplified and much more resilient to human error.
|
||||
|
||||
## Initial Configuration
|
||||
Your initial configuration skeleton can be created using the `oputil.js` command line utility. From your enigma-bbs root directory:
|
||||
```bash
|
||||
./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 menu files under `config/menus/`. See [Menu HJSON](menu-hjson.md) for more information.
|
||||
|
22
docs/_docs/configuration/directory-structure.md
Normal file
22
docs/_docs/configuration/directory-structure.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
layout: page
|
||||
title: Directory Structure
|
||||
---
|
||||
All paths mentioned here are relative to the ENiGMA½ checkout directory.
|
||||
|
||||
| Directory | Description |
|
||||
|---------------------|-----------------------------------------------------------------------------------------------------------|
|
||||
| `/art/general` | Non-theme art - welcome ANSI, logoff ANSI, etc. See [General Art]({{ site.baseurl }}{% link _docs/art/general.md %}).
|
||||
| `/art/themes` | Theme art. Themes should be in their own subdirectory and contain a theme.hjson. See [Themes]({{ site.baseurl }}{% link _docs/art/themes.md %}).
|
||||
| `/config` | [config.hjson](config-hjson.md) system configuration.
|
||||
| `/config/menus` | [menu.hjson](menu-hjson.md) storage.
|
||||
| `/config/security` | SSL certificates and public/private keys.
|
||||
| `/db` | All ENiGMA½ databases in SQLite3 format.
|
||||
| `/docs` | These docs ;-)
|
||||
| `/dropfiles` | Dropfiles created for [local doors]({{ site.baseurl }}{% link _docs/modding/local-doors.md %})
|
||||
| `/logs` | Logs. See [Monitoring Logs]({{ site.baseurl }}{% link _docs/troubleshooting/monitoring-logs.md %})
|
||||
| `/misc` | Stuff with no other home; reset password templates, common password lists, other random bits
|
||||
| `/mods` | User mods. See [Modding]({{ site.baseurl }}{% link _docs/modding/existing-mods.md %})
|
||||
| `/node_modules` | External libraries required by ENiGMA½, installed when you run `npm install`
|
||||
| `/util` | Various tools used in running/debugging ENiGMA½
|
||||
| `/www` | ENiGMA½'s built in webserver root directory
|
49
docs/_docs/configuration/email.md
Normal file
49
docs/_docs/configuration/email.md
Normal file
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
layout: page
|
||||
title: Email
|
||||
---
|
||||
## Email Support
|
||||
ENiGMA½ uses email to send password reset information to users. For it to work, you need to provide valid [Nodemailer](https://nodemailer.com/about/) compatible `email` block in your [config.hjson]({{ site.baseurl }}{% link _docs/configuration/config-hjson.md %}). Nodemailer supports SMTP in addition to many pre-defined services for ease of use. The `transport` block within `email` must be Nodemailer compatible.
|
||||
|
||||
Additional email support will come in the near future.
|
||||
|
||||
## Services
|
||||
|
||||
If you don't have an SMTP server to send from, [Sendgrid](https://sendgrid.com/) and [Zoho](https://www.zoho.com/mail/) both provide reliable and free services.
|
||||
|
||||
## Example Configurations
|
||||
|
||||
Example 1 - SMTP:
|
||||
```hjson
|
||||
email: {
|
||||
defaultFrom: sysop@bbs.awesome.com
|
||||
|
||||
transport: {
|
||||
host: smtp.awesomeserver.com
|
||||
port: 587
|
||||
secure: false
|
||||
auth: {
|
||||
user: leisuresuitlarry
|
||||
pass: sierra123
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Example 2 - Zoho
|
||||
```hjson
|
||||
email: {
|
||||
defaultFrom: sysop@bbs.awesome.com
|
||||
|
||||
transport: {
|
||||
service: Zoho
|
||||
auth: {
|
||||
user: noreply@bbs.awesome.com
|
||||
pass: yuspymypass
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Lockout Reset
|
||||
If email is available on your system and you allow email-driven password resets, you may elect to allow unlocking accounts at the time of a password reset. This is controlled by the `users.unlockAtEmailPwReset` configuration option. If an account is locked due to too many failed login attempts, a user may reset their password to remedy the situation themselves.
|
79
docs/_docs/configuration/event-scheduler.md
Normal file
79
docs/_docs/configuration/event-scheduler.md
Normal file
|
@ -0,0 +1,79 @@
|
|||
---
|
||||
layout: page
|
||||
title: Event Scheduler
|
||||
---
|
||||
## Event Scheduler
|
||||
The ENiGMA½ scheduler allows system operators to configure arbitrary events that can can fire based on date and/or time, or by watching for changes in a file. Events can kick off internal handlers, custom modules, or binaries & scripts.
|
||||
|
||||
## Scheduling Events
|
||||
To create a scheduled event, create a new configuration block in `config.hjson` under `eventScheduler.events`.
|
||||
|
||||
Events can have the following members:
|
||||
|
||||
| Item | Required | Description |
|
||||
|------|----------|-------------|
|
||||
| `schedule` | :+1: | A [Later style](https://bunkat.github.io/later/parsers.html#text) parsable schedule string such as `at 4:00 am`, or `every 24 hours`. Can also be (or contain) an `@watch` clause. See **Schedules** below for details. |
|
||||
| `action` | :+1: | Action to perform when the schedule is triggered. May be an `@method` or `@execute` spec. See **Actions** below. |
|
||||
| `args` | :-1: | An array of arguments to pass along to the method or binary specified in `action`. |
|
||||
|
||||
### Schedules
|
||||
As mentioned above, `schedule` may contain a [Later style](https://bunkat.github.io/later/parsers.html#text) parsable schedule string and/or an `@watch` clause.
|
||||
|
||||
`schedule` examples:
|
||||
* `every 2 hours`
|
||||
* `on the last day of the week`
|
||||
* `after 12th hour`
|
||||
|
||||
An `@watch` clause monitors a specified file for changes and takes the following form: `@watch:<path>` where `<path>` is a fully qualified path.
|
||||
|
||||
:bulb: If you would like to have a schedule **and** watch a file for changes, place the `@watch` clause second and separated with the word `or`. For example: `every 24 hours or @watch:/path/to/somefile.txt`.
|
||||
|
||||
### Actions
|
||||
Events can kick off actions by calling a method (function) provided by the system or custom module in addition to executing arbritary binaries or scripts.
|
||||
|
||||
#### Methods
|
||||
An action with a `@method` can take the following forms:
|
||||
|
||||
* `@method:/full/path/to/module.js:methodName`: Executes `methodName` at `/full/path/to/module.js`.
|
||||
* `@method:rel/path/to/module.js:methodName`: Executes `methodName` using the *relative* path `rel/path/to/module.js`. Paths for `@method` are relative to the ENiGMA½ installation directory.
|
||||
|
||||
Methods are passed any supplied `args` in the order they are provided.
|
||||
|
||||
##### Method Signature
|
||||
To create your own method, simply `export` a method with the following signature: `(args, callback)`. Methods are executed asynchronously.
|
||||
|
||||
Example:
|
||||
```javascript
|
||||
// my_custom_mod.js
|
||||
exports.myCustomMethod = (args, cb) => {
|
||||
console.log(`Hello, ${args[0]}!`);
|
||||
return cb(null);
|
||||
}
|
||||
```
|
||||
|
||||
#### Executables
|
||||
When using the `@execute` action, a binary or script can be executed. A full path or just the binary name is acceptable. If using the form without a path, the binary much be in ENiGMA½'s `PATH`.
|
||||
|
||||
Examples:
|
||||
* `@execute:/usr/bin/foo`
|
||||
* `@execute:foo`
|
||||
|
||||
Just like with methods, any supplied `args` will be passed along.
|
||||
|
||||
## Example Entries
|
||||
|
||||
Post a message to supplied networks every Monday night using the message post mod (see modding):
|
||||
```hjson
|
||||
eventScheduler: {
|
||||
events: {
|
||||
enigmaAdToNetworks: {
|
||||
schedule: at 10:35 pm on Mon
|
||||
action: @method:mods/message_post_evt/message_post_evt.js:messagePostEvent
|
||||
args: [
|
||||
"fsx_bot"
|
||||
"/home/enigma-bbs/ad.asc"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
44
docs/_docs/configuration/external-binaries.md
Normal file
44
docs/_docs/configuration/external-binaries.md
Normal file
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
layout: page
|
||||
title: External Support Binaries
|
||||
---
|
||||
|
||||
## External Support Binaries
|
||||
ENiGMA½ relies on various external binaries in order to perform common tasks such as processing file archives and extracting information from uploads/file imports, some legacy transfer protocols, etc.
|
||||
|
||||
:correct: Before using features such as the [File Base](../filebase/index.md) or [File Transfer Protocols](../configuration/file-transfer-protocols.md) it is highly recommended to install support binaries!
|
||||
|
||||
## Archivers
|
||||
Below is a table of pre-configured archivers. Remember that you can override settings or add new handlers! See [Archivers](archivers.md).
|
||||
|
||||
| Archiver (Key) | File Types | More Info | Debian/Ubuntu (apt/dep) | Red Hat (yum/rpm) | Windows |
|
||||
|----------|---------|-----------|-------------------------|-------------------|---------|
|
||||
| `Arj` | .arj | [Wikipedia](https://en.wikipedia.org/wiki/ARJ) | `arj` | `arj` | [ARJ](http://arj.sourceforge.net/) |
|
||||
| `7Zip` | .7z, .bzip2, .gzip/.gz, etc.<br>:warning: Does not attempt to handle zip files! See `InfoZip`! | http://www.7-zip.org | `p7zip-full` | `p7zip-full` | [7-zip](http://www.7-zip.org/) |
|
||||
| `InfoZip` | .zip | http://infozip.sourceforge.net <br>`zip` and `unzip` will need to be en ENiGMA's PATH | `zip` and `unzip` | `zip` and `unzip` | [InfoZip](http://infozip.sourceforge.net/) |
|
||||
| `Lha` | .lza, .lzh, etc. | [Wikipedia](https://en.wikipedia.org/wiki/LHA_(file_format)) <br> https://fragglet.github.io/lhasa/ | `lhasa` | `lhasa` | [Win32 binaries](https://soulsphere.org/projects/lhasa/win32/) |
|
||||
| `Lzx` | .lzx | [Amiga LZX](https://en.wikipedia.org/wiki/LZX_(algorithm)#Amiga_LZX) | `unlzx` | `unlzx` | [Source](http://xavprods.free.fr/lzx/) |
|
||||
| `Rar` | .rar | [Wikipedia](https://en.wikipedia.org/wiki/RAR_(file_format)) | `unrar` | `unrar`| [RARLAB](https://www.rarlab.com/) |
|
||||
| `TarGz` | .tar.gz, .gzip | [Wikipedia](https://en.wikipedia.org/wiki/Gzip) | `tar` | `tar` | [TAR.EXE](https://ss64.com/nt/tar.html)
|
||||
|
||||
|
||||
:information_source: For more information see `core/config_default.js`
|
||||
|
||||
:information_source: For information on changing configuration or adding more archivers see [Archivers](archivers.md).
|
||||
|
||||
## File Transfer Protocols
|
||||
Handlers for legacy file transfer protocols such as Z-Modem and Y-Modem.
|
||||
|
||||
| Handler (Key) | Protocol | More Info | Debian/Ubuntu (apt/dep) | Red Hat (yum/rpm) | Windows |
|
||||
|----------|---------|-----------|-------------------------|-------------------|---------|
|
||||
| `xmodemSexyz`<br>`ymodemSexyz`<br>`zmodem8kSexyz` | X-Modem, Y-Modem and Z-Modem SEXYZ | [SEXYZ](http://www.synchro.net/docs/sexyz.txt) | [x86_64 Binary](https://l33t.codes/outgoing/sexyz) | [x86_64 Binary](https://l33t.codes/outgoing/sexyz) | [Synchronet FTP](ftp://ftp.synchro.net/) |
|
||||
| `zmodem8kSz` | Z-Modem 8K | [Wikipedia](https://en.wikipedia.org/wiki/ZMODEM) | `lrzsz` | `lrzsz` | Unknown |
|
||||
|
||||
|
||||
## Information Extractors
|
||||
Information extraction utilities can extract information from various file types such as PDF in order to (attempt) to come up with a good default description.
|
||||
|
||||
| Extractor | File Types | More Info | Debian/Ubuntu (apt/dep) | Red Hat (yum/rpm) | Windows |
|
||||
|----------|---------|-----------|-------------------------|-------------------|---------|
|
||||
| ExifTool | .mp3, .pdf, .mp4, .jpg, .gif, .png, many more | [ExifTool](https://www.sno.phy.queensu.ca/~phil/) | `libimage-exiftool-perl` | `perl-Image-ExifTool` | Unknown |
|
||||
| XDMS | Amiga DiskMasher images | | `xdms` | `xdms` | Unknown
|
51
docs/_docs/configuration/file-transfer-protocols.md
Normal file
51
docs/_docs/configuration/file-transfer-protocols.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
---
|
||||
layout: page
|
||||
title: File Transfer Protocols
|
||||
---
|
||||
ENiGMA½ currently relies on external executable binaries for "legacy" file transfer protocols such as X, Y, and ZModem. Remember that ENiGMA½ also support modern web (HTTP/HTTPS) downloads!
|
||||
|
||||
## File Transfer Protocols
|
||||
File transfer protocols are managed via the `fileTransferProtocols` configuration block of `config.hjson`. Each entry defines an **external** protocol handler that can be used for uploads (recv), downloads (send), or both. Depending on the protocol and handler, batch receiving of files (uploads) may also be available.
|
||||
|
||||
### Predefined File Transfer Protocols
|
||||
Please see [External Binaries](external-binaries.md) for a table of built in / predefined protocol handlers. You will need to have the binaries in ENiGMA's PATH.
|
||||
#### SEXYZ
|
||||
[SEXYZ from Synchronet](http://wiki.synchro.net/util:sexyz) offers a nice X, Y, and ZModem implementation including ZModem-8k & works under *nix and Windows based systems. As of this writing, ENiGMA½ is pre-configured to support ZModem-8k, XModem, and YModem using SEXYZ. An x86_64 Linux binary, and hopefully more in the future, [can be downloaded here](https://l33t.codes/bbs-linux-binaries/).
|
||||
|
||||
#### sz/rz
|
||||
ZModem-8k is configured using the standard Linux [sz(1)](https://linux.die.net/man/1/sz) and [rz(1)](https://linux.die.net/man/1/rz) binaries. Note that these binaries also support XModem and YModem, and as such adding the configurations to your system should be fairly straight forward.
|
||||
|
||||
Generally available as `lrzsz` under Apt or Yum type packaging.
|
||||
|
||||
### File Transfer Protocol Configuration
|
||||
The following top-level members are available to an external protocol configuration:
|
||||
* `name`: Required; Display name of the protocol
|
||||
* `type`: Required; Currently must be `external`. This will be expanded upon in the future with built in protocols.
|
||||
* `sort`: Optional; Sort key. If not provided, `name` will be used for sorting.
|
||||
|
||||
For protocols of type `external` the following members may be defined:
|
||||
* `sendCmd`: Required for protocols that can send (allow user downloads); The command/binary to execute.
|
||||
* `sendArgs`: Required if using `sendCmd`; An array of arguments. A placeholder of `{fileListPath}` may be used to supply a path to a **file containing** a list of files to send, or `{filePaths}` to supply *1:n* individual file paths to send.
|
||||
* `recvCmd`: Required for protocols that can receive (allow user uploads); The command/binary to execute.
|
||||
* `recvArgs`: Required if using `recvCmd` and supporting **batch** uploads; An array of arguments. A placeholder of `{uploadDir}` may be used to supply the system provided upload directory. If `{uploadDir}` is not present, the system expects uploaded files to be placed in CWD which will be set to the upload directory.
|
||||
* `recvArgsNonBatch`: Required if using `recvCmd` and supporting non-batch (single file) uploads; A placeholder of `{fileName}` may be supplied to indicate to the protocol what the uploaded file should be named (this will be collected from the user before the upload starts).
|
||||
* `escapeTelnet`: Optional; If set to `true`, escape all internal Telnet related codes such as IAC's. This option is required for external protocol handlers such as `sz` and `rz` that do not escape themselves.
|
||||
|
||||
### Adding Your Own
|
||||
Take a look a the example below as well as [core/config_default.js](/core/config_default.js).
|
||||
|
||||
#### Example File Transfer Protocol Configuration
|
||||
```
|
||||
zmodem8kSexyz : {
|
||||
name : 'ZModem 8k (SEXYZ)',
|
||||
type : 'external',
|
||||
sort : 1,
|
||||
external : {
|
||||
sendCmd : 'sexyz',
|
||||
sendArgs : [ '-telnet', '-8', 'sz', '@{fileListPath}' ],
|
||||
recvCmd : 'sexyz',
|
||||
recvArgs : [ '-telnet', '-8', 'rz', '{uploadDir}' ],
|
||||
recvArgsNonBatch : [ '-telnet', '-8', 'rz', '{fileName}' ],
|
||||
}
|
||||
}
|
||||
```
|
70
docs/_docs/configuration/hjson.md
Normal file
70
docs/_docs/configuration/hjson.md
Normal file
|
@ -0,0 +1,70 @@
|
|||
---
|
||||
layout: page
|
||||
title: HJSON Config Files
|
||||
---
|
||||
## JSON for Humans!
|
||||
HJSON is the configuration file format used by ENiGMA½ for [System Configuration](config-hjson.md), [Menus](menu-hjson.md), etc. [HJSON](https://hjson.org/) is is [JSON](https://json.org/) for humans!
|
||||
|
||||
For those completely unfamiliar, JSON stands for JavaScript Object Notation. But don't let that scare you! JSON is simply a text file format with a bit of structure ― kind of like a fancier INI file. HJSON on the other hand as mentioned previously, is JSON for humans. That is, it has the following features and more:
|
||||
|
||||
* More resilient to syntax errors such as missing a comma
|
||||
* Strings generally do not need to be quoted. Multi-line strings are also supported!
|
||||
* Comments are supported (JSON doesn't allow this!): `#`, `//` and `/* ... */` style comments are allowed.
|
||||
* Keys never need to be quoted
|
||||
* ...much more! See [the official HJSON website](https://hjson.org/).
|
||||
|
||||
## Terminology
|
||||
Through the documentation, some terms regarding HJSON and configuration files will be used:
|
||||
|
||||
* `config.hjson`: Refers to `/path/to/enigma-bbs/config/config.hjson`. See [System Configuration](config-hjson.md).
|
||||
* `menu.hjson`: Refers to `/path/to/enigma-bbs/config/<yourBBSName>-menu.hjson`. See [Menus](menu-hjson.md).
|
||||
* Configuration *key*: Elements in HJSON are name-value pairs where the name is the *key*. For example, provided `foo: bar`, `foo` is the key.
|
||||
* Configuration *section* or *block* (also commonly called an "Object" in code): This is referring to a section in a HJSON file that starts with a *key*. For example:
|
||||
```hjson
|
||||
someSection: {
|
||||
foo: bar
|
||||
}
|
||||
```
|
||||
Note that `someSection` is the configuration *section* (or *block*) and `foo: bar` is within it.
|
||||
|
||||
## Editing HJSON
|
||||
HJSON is a text file format, and ENiGMA½ configuration files **should always be saved as UTF-8**.
|
||||
|
||||
It is **highly** recommended to use a text editor that has HJSON support. A few (but not all!) examples include:
|
||||
* [Sublime Text](https://www.sublimetext.com/) via the `sublime-hjson` package.
|
||||
* [Visual Studio Code](https://code.visualstudio.com/) via the `vscode-hjson` plugin.
|
||||
* [Notepad++](https://notepad-plus-plus.org) via the `npp-hjson` plugin.
|
||||
|
||||
See https://hjson.org/users.html for more more editors & plugins.
|
||||
|
||||
### Hot-Reload A.K.A. Live Editing
|
||||
ENiGMA½'s configuration, menu, and theme files can edited while your BBS is running. When a file is saved, it is hot-reloaded into the running system. If users are currently connected and you change a menu for example, the next reload of that menu will show the changes.
|
||||
|
||||
:information_source: See also [Configuration Files](../configuration/config-files.md)
|
||||
|
||||
### CaSe SeNsiTiVE
|
||||
Configuration keys are **case sensitive**. That means if a configuration key is `boardName` for example, `boardname`, or `BOARDNAME` **will not work**.
|
||||
|
||||
### Escaping
|
||||
Some values need escaped. This is especially important to remember on Windows machines where file paths contain backslashes (`\`). To specify a path to `C:\foo\bar\baz.exe` for example, an entry may look like this in your configuration file:
|
||||
```hjson
|
||||
something: {
|
||||
path: "C:\\foo\\bar\\baz.exe" // note the extra \'s!
|
||||
}
|
||||
```
|
||||
|
||||
## Tips & Tricks
|
||||
### JSON Compatibility
|
||||
Remember that standard JSON is fully compatible with HJSON. If you are more comfortable with JSON (or have an editor that works with JSON that you prefer) simply convert your config file(s) to JSON and use that instead!
|
||||
|
||||
HJSON can be converted to JSON with the `hjson` CLI:
|
||||
```bash
|
||||
cd /path/to/enigma-bbs
|
||||
cp ./config/config.hjson ./config/config.hjson.backup
|
||||
./node_modules/hjson/bin/hjson ./config/config.hjson.backup -j > ./config/config.hjson
|
||||
```
|
||||
|
||||
You can always convert back to HJSON by omitting `-j` in the command above.
|
||||
|
||||
### oputil
|
||||
You can easily dump out your current configuration in a pretty-printed style using oputil: ```./oputil.js config cat```
|
364
docs/_docs/configuration/menu-hjson.md
Normal file
364
docs/_docs/configuration/menu-hjson.md
Normal file
|
@ -0,0 +1,364 @@
|
|||
---
|
||||
layout: page
|
||||
title: Menu HSJON
|
||||
---
|
||||
## Menu HJSON
|
||||
The core of a ENiGMA½ based BBS is it's menus driven by what will be referred to as `menu.hjson`. Throughout ENiGMA½ documentation, when `menu.hjson` is referenced, we're actually talking about `config/menus/yourboardname-*.hjson`. These files determine the menus (or screens) a user can see, the order they come in, how they interact with each other, ACS configuration, and so on. Like all configuration within ENiGMA½, menu configuration is done in [HJSON](https://hjson.org/) format.
|
||||
|
||||
:information_source: See also [HJSON General Information](hjson.md) for more information on the HJSON file format.
|
||||
|
||||
:bulb: 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:
|
||||
|
||||
* Classical navigation and menus such as Main, Messages, and Files.
|
||||
* Art file display.
|
||||
* Module driven menus such as [door launchers](../modding/local-doors.md), [Onelinerz](../modding/onelinzerz.md), and other custom mods.
|
||||
|
||||
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.
|
||||
|
||||
Below is a very basic menu entry called `showSomeArt` that displays some art then returns to the previous menu after the user hits a key:
|
||||
```hjson
|
||||
showSomeArt: {
|
||||
art: someart.ans
|
||||
config: { pause: true }
|
||||
}
|
||||
```
|
||||
As you can see a menu can be very simple.
|
||||
|
||||
: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. Menus that use their own module contain a `module` declaration:
|
||||
|
||||
```hjson
|
||||
module: some_fancy_module
|
||||
```
|
||||
|
||||
See documentation for the module in question for particulars.
|
||||
|
||||
| Item | Description |
|
||||
|--------|--------------|
|
||||
| `desc` | A friendly description that can be found in places such as "Who's Online" or wherever the `%MD` MCI code is used. |
|
||||
| `art` | An art file *spec*. See [General Art Information](../art/general.md). |
|
||||
| `next` | Specifies the menu to go to next. Can be explicit or an array of possibilities dependent on ACS. See **Flow Control** in the **ACS Checks** section below. If `next` is not supplied, the next menu is this menus parent. Note that special built in methods such as `@systemMethod:logoff` can also be utilized here. |
|
||||
| `prompt` | Specifies a prompt, by name, to use along with this menu. Prompts are configured in the `prompts` section. See **Prompts** for more information. |
|
||||
| `submit` | Defines a submit handler when using `prompt`.
|
||||
| `form` | An object defining one or more *forms* available on this menu. |
|
||||
| `module` | Sets the module name to use for this menu. The system ships with many build in modules or you can build your own! |
|
||||
| `config` | An object containing additional configuration. See **Config Block** below. |
|
||||
|
||||
### Config Block
|
||||
The `config` block for a menu entry can contain common members as well as a per-module (when `module` is used) settings.
|
||||
|
||||
| Item | Description |
|
||||
|------|-------------|
|
||||
| `cls` | If `true` the screen will be cleared before showing this menu. |
|
||||
| `pause` | If `true` a pause will occur after showing this menu. Useful for simple menus such as displaying art or status screens. |
|
||||
| `nextTimeout` | Sets the number of **milliseconds** before the system will automatically advanced to the `next` menu. |
|
||||
| `baudRate` | See baud rate information in [General Art Information](../art/general.md). |
|
||||
| `font` | Sets a SyncTERM style font to use when displaying this menus `art`. See font listing in [General Art Information](../art/general.md). |
|
||||
| `menuFlags` | An array of menu flag(s) controlling menu behavior. See **Menu Flags** below.
|
||||
|
||||
#### Menu Flags
|
||||
The `menuFlags` field of a `config` block can change default behavior of a particular menu.
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `noHistory` | Prevents the menu from remaining in the menu stack / history. When this flag is set, when the **next** menu falls back, this menu will be skipped and the previous menu again displayed instead. Example: menuA -> menuB(noHistory) -> menuC: Exiting menuC returns the user to menuA. |
|
||||
| `popParent` | When *this* menu is exited, fall back beyond the parent as well. Often used in combination with `noHistory`. |
|
||||
| `forwardArgs` | If set, when the next menu is entered, forward any `extraArgs` arguments to *this* menu on to it. |
|
||||
|
||||
|
||||
## Forms
|
||||
ENiGMA½ uses a concept of *forms* in menus. A form is a collection of associated *views*. Consider a New User Application using the `nua` module: The default implementation utilizes a single form with multiple EditTextView views, a submit button, etc. Forms are identified by number starting with `0`. A given menu may have mutiple forms (often associated with different states or screens within the menu).
|
||||
|
||||
Menus may also support more than one layout type by using a *MCI key*. A MCI key is a alpha-numerically sorted key made from 1:n MCI codes. This lets the system choose the appropriate set of form(s) based on theme or random art. An example of this may be a matrix menu: Perhaps one style of your matrix uses a vertical light bar (`VM` key) while another uses a horizontal (`HM` key). The system can discover the correct form to use by matching MCI codes found in the art to that of the available forms defined in `menu.hjson`.
|
||||
|
||||
For more information on views and associated MCI codes, see [MCI Codes](../art/mci.md).
|
||||
|
||||
## Submit Handlers
|
||||
When a form is submitted, it's data is matched against a *submit handler*. When a match is found, it's *action* is performed.
|
||||
|
||||
### Submit Actions
|
||||
Submit actions are declared using the `action` member of a submit handler block. Actions can be kick off system/global or local-to-module methods, launch other menus, etc.
|
||||
|
||||
| Action | Description |
|
||||
|--------|-------------|
|
||||
| `@menu:menuName` | Takes the user to the *menuName* menu |
|
||||
| `@systemMethod:methodName` | Executes the system/global method *methodName*. See **System Methods** below. |
|
||||
| `@method:methodName` | Executes *methodName* local to the calling module. That is, the module set by the `module` member of a menu entry. |
|
||||
| `@method:/path/to/some_module.js:methodName` | Executes *methodName* exported by the module at */path/to/some_module.js*. |
|
||||
|
||||
#### Advanced Action Handling
|
||||
In addition to simple simple actions, `action` may also be:
|
||||
* An array of objects containing ACS checks and a sub `action` if that ACS is matched. See **Action Matches** in the ACS documentation below for details.
|
||||
* An array of actions. In this case a random selection will be made. Example:
|
||||
```hjson
|
||||
submit: [
|
||||
{
|
||||
value: { command: "FOO" }
|
||||
action: [
|
||||
// one of the following actions will be matched:
|
||||
"@menu:menuStyle1"
|
||||
"@menu:menuStyle2"
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### Method Signature
|
||||
Methods executed using `@method`, or `@systemMethod` have the following signature:
|
||||
```
|
||||
(callingMenu, formData, extraArgs, callback)
|
||||
```
|
||||
|
||||
#### System Methods
|
||||
Many built in global/system methods exist. Below are a few. See [system_menu_method](/core/system_menu_method.js) for more information.
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `login` | Performs a standard login. |
|
||||
| `login2FA_OTP` | Performs a 2-Factor Authentication (2FA) One-Time Password (OTP) check, if configured for the user. |
|
||||
| `logoff` | Performs a standard system logoff. |
|
||||
| `prevMenu` | Goes to the previous menu. |
|
||||
| `nextMenu` | Goes to the next menu (as set by `next`) |
|
||||
| `prevConf` | Sets the users message conference to the previous available. |
|
||||
| `nextConf` | Sets the users message conference to the next available. |
|
||||
| `prevArea` | Sets the users message area to the previous available. |
|
||||
| `nextArea` | Sets the users message area to the next available. |
|
||||
|
||||
## Example
|
||||
Let's look a couple basic menu entries:
|
||||
|
||||
```hjson
|
||||
telnetConnected: {
|
||||
art: CONNECT
|
||||
next: matrix
|
||||
config: { nextTimeout: 1500 }
|
||||
}
|
||||
```
|
||||
|
||||
The above entry `telnetConnected` is set as the Telnet server's first menu entry (set by `firstMenu` in the Telnet server's config). The entry sets up a few things:
|
||||
* A `art` spec of `CONNECT`. (See [General Art Information](../art/general.md)).
|
||||
* A `next` entry up the next menu, by name, in the stack (`matrix`) that we'll go to after `telnetConnected`.
|
||||
* An `config` block containing a single `nextTimeout` field telling the system to proceed to the `next` (`matrix`) entry automatically after 1500ms.
|
||||
|
||||
Now let's look at `matrix`, the `next` entry from `telnetConnected`:
|
||||
|
||||
```hjson
|
||||
matrix: {
|
||||
art: MATRIX
|
||||
desc: Login Matrix
|
||||
form: {
|
||||
0: {
|
||||
//
|
||||
// Here we have a MCI key of "VM". In this case we could
|
||||
// omit this level since no other keys are present.
|
||||
//
|
||||
VM: {
|
||||
mci: {
|
||||
VM1: {
|
||||
submit: true
|
||||
focus: true
|
||||
items: [ "login", "apply", "log off" ]
|
||||
argName: matrixSubmit
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
value: { matrixSubmit: 0 }
|
||||
action: @menu:login
|
||||
}
|
||||
{
|
||||
value: { matrixSubmit: 1 },
|
||||
action: @menu:newUserApplication
|
||||
}
|
||||
{
|
||||
value: { matrixSubmit: 2 },
|
||||
action: @menu:logoff
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If we wanted, we could declare a "HM" MCI key block here.
|
||||
// This would allow a horizontal matrix style when the matrix art
|
||||
// loaded contained a %HM code.
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the above entry, you'll notice `form`. This defines a form(s) object. In this case, a single form by ID of `0`. The system is then told to use a block only when the resulting art provides a `VM` (*VerticalMenuView*) MCI entry. Some other bits about the form:
|
||||
|
||||
* `VM1` is then setup to `submit` and start focused via `focus: true` as well as have some menu entries ("login", "apply", ...) defined. We provide an `argName` of `matrixSubmit` for this element view.
|
||||
* The `submit` object tells the system to attempt to apply provided match entries from any view ID (`*`).
|
||||
* 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
|
||||
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.
|
||||
|
||||
### Menu Access
|
||||
To restrict menu access add an `acs` key to `config`. Example:
|
||||
```
|
||||
opOnlyMenu: {
|
||||
desc: Ops Only!
|
||||
config: {
|
||||
acs: ID1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Action Matches
|
||||
Action blocks (`action`) can perform ACS checks:
|
||||
```
|
||||
// ...
|
||||
{
|
||||
action: [
|
||||
{
|
||||
acs: SC1
|
||||
action: @menu:secureMenu
|
||||
}
|
||||
{
|
||||
action: @menu:nonSecureMenu
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Flow Control
|
||||
The `next` member of a menu may be an array of objects containing an `acs` check as well as the destination. Depending on the current user's ACS, the system will pick the appropriate target. The last element in an array without an `acs` can be used as a catch all. Example:
|
||||
```
|
||||
login: {
|
||||
desc: Logging In
|
||||
next: [
|
||||
{
|
||||
// >= 2 calls else you get the full login
|
||||
acs: NC2
|
||||
next: loginSequenceLoginFlavorSelect
|
||||
}
|
||||
{
|
||||
next: fullLoginSequenceLoginArt
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Art Asset Selection
|
||||
Another area in which you can apply ACS in a menu is art asset specs.
|
||||
|
||||
```hjson
|
||||
someMenu: {
|
||||
desc: Neato Dorito
|
||||
art: [
|
||||
{
|
||||
acs: GM[couriers]
|
||||
art: COURIERINFO
|
||||
}
|
||||
{
|
||||
// show ie: EVERYONEELSE.ANS to everyone else
|
||||
art: EVERYONEELSE
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Case Study: Adding a Sub Menu to Main
|
||||
A very common task: You want to add a new menu accessible from "Main". First, let's create a new menu called "Snazzy Town"! Perhaps under the `mainMenu` entry somewhere, create a new menu:
|
||||
|
||||
```hjson
|
||||
snazzyTown: {
|
||||
desc: Snazzy Town
|
||||
art: snazzy
|
||||
config: {
|
||||
cls: true
|
||||
pause: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now let's make it accessible by "S" from the main menu. By default the main menu entry is named `mainMenu`. Within the `mainMenu`'s `submit` block you will see some existing action matches to "command". Simply add a new one pointing to `snazzyTown`:
|
||||
|
||||
```hjson
|
||||
{
|
||||
value: { command: "S" }
|
||||
action: @menu:snazzyTown
|
||||
}
|
||||
```
|
||||
|
||||
That's it! When users type "S" at the main menu, they'll be sent to the Snazzy Town menu. Since we did not supply additional flow logic when they exit, they will fall back to main.
|
||||
|
||||
## Case Study: Adding a New User Password (NUP)
|
||||
You've got a super 31337 board and want to prevent lamerz! Let's run through adding a NUP to your application flow.
|
||||
|
||||
Given the default menu system, two "pre" new user application menus exist due to the way Telnet vs SSH logins occur. We'll focus only on Telnet here. This menu is `newUserApplicationPre`. Let's say you want to display this preamble, but then ask for the NUP. If the user gets the password wrong, show them a `LAMER.ANS` and boot 'em.
|
||||
|
||||
First, let's create a new menu for the NUP:
|
||||
```hjson
|
||||
newUserPassword: {
|
||||
art: NUP.ANS
|
||||
next: newUserApplication
|
||||
desc: NUP!
|
||||
|
||||
form: {
|
||||
0: {
|
||||
mci: {
|
||||
ET1: {
|
||||
// here we create an argument/variable of "nup"
|
||||
argName: nup
|
||||
focus: true
|
||||
submit: true
|
||||
}
|
||||
}
|
||||
submit: {
|
||||
*: [
|
||||
{
|
||||
// if the user submits "nup" with the correct
|
||||
// value of "nolamerz" action will send
|
||||
// them to the next menu defined above --
|
||||
// in our case: newUserApplication
|
||||
value: { nup: "nolamerz" }
|
||||
action: @systemMethod:nextMenu
|
||||
}
|
||||
{
|
||||
// anything else will result in going to the badNewUserPassword menu
|
||||
value: { nup: null }
|
||||
action: @menu:badNewUserPassword
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Looks like we'll need a `badNewUserPassword` menu as well! Let's create a very basic menu to show art then disconnect the user.
|
||||
|
||||
```hjson
|
||||
badNewUserPassword: {
|
||||
art: LAMER.ANS
|
||||
// here we use a built in system method to boot them.
|
||||
next: @systemMethod:logoff
|
||||
config: {
|
||||
// wait 2s after showing the art before kicking them
|
||||
nextTimeout: 2000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Great, we have a couple new menus. Now let's just point to them. Remember the existing `newUserApplicationPre` menu? All that is left to do is point it's `next` to our `newUserPassword` menu:
|
||||
|
||||
```hjson
|
||||
newUserApplicationPre: {
|
||||
// easy! Just tell the system where to go next
|
||||
next: newUserPassword
|
||||
// note that the rest of this menu is omitted for clarity
|
||||
}
|
||||
```
|
64
docs/_docs/configuration/security.md
Normal file
64
docs/_docs/configuration/security.md
Normal file
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
layout: page
|
||||
title: Security
|
||||
---
|
||||
## Security
|
||||
Unlike in the golden era of BBSing, modern Internet-connected systems are prone to hacking attempts, eavesdropping, etc. While plain-text passwords, insecure data over [Plain Old Telephone Service (POTS)](https://en.wikipedia.org/wiki/Plain_old_telephone_service), and so on was good enough then, modern systems must employ protections against attacks. ENiGMA½ comes with many security features that help keep the system and your users secure — not limited to:
|
||||
* Passwords are **never** stored in plain-text, but instead are stored using [Password-Based Key Derivation Function 2 (PBKDF2)](https://en.wikipedia.org/wiki/PBKDF2). Even the system operator can _never_ know your password!
|
||||
* Alternatives to insecure Telnet logins are built in: [SSH](https://en.wikipedia.org/wiki/Secure_Shell) and secure [WebSockets](https://en.wikipedia.org/wiki/WebSocket) for example.
|
||||
* A built in web server with [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) support (aka HTTPS).
|
||||
* Optional [Two-Factor Authentication (2FA)](https://en.wikipedia.org/wiki/Multi-factor_authentication) via [One-Time-Password (OTP)](https://en.wikipedia.org/wiki/One-time_password) for users, supporting [Google Authenticator](http://google-authenticator.com/), [Time-Based One-Time Password Algorithm (TOTP, RFC-6238)](https://tools.ietf.org/html/rfc6238), and [HMAC-Based One-Time Password Algorithm (HOTP, RFC-4266)](https://tools.ietf.org/html/rfc4226).
|
||||
|
||||
## Two-Factor Authentication via One-Time Password
|
||||
Enabling Two-Factor Authentication via One-Time-Password (2FA/OTP) on an account adds an extra layer of security ("_something a user has_") in addition to their password ("_something a user knows_"). Providing 2FA/OTP to your users has some prerequisites:
|
||||
* [A configured email gateway](../configuration/email.md) such that the system can send out emails.
|
||||
* One or more secure servers enabled such as [SSH](../servers/ssh.md) or secure [WebSockets](../servers/websocket.md) (that is, WebSockets over a secure connection such as TLS).
|
||||
* The [web server](../servers/web-server.md) enabled and exposed over TLS (HTTPS).
|
||||
|
||||
:information_source: For WebSockets and the web server, ENiGMA½ _may_ listen on insecure channels if behind a secure web proxy.
|
||||
|
||||
### User Registration Flow
|
||||
Due to the nature of 2FA/OTP, even if enabled on your system, users must opt-in and enable this feature on their account. Users must also have a valid email address such that a registration link can be sent to them. To opt-in, users must enable the option, which will cause the system to email them a registration link. Following the link provides the following:
|
||||
|
||||
1. A secret for manual entry into a OTP device.
|
||||
2. If applicable, a scannable QR code for easy device entry (e.g. Google Authenticator)
|
||||
3. A confirmation prompt in which the user must enter a OTP code. If entered correctly, this validates everything is set up properly and 2FA/OTP will be enabled for the account. Backup codes will also be provided at this time. Future logins will now prompt the user for their OTP after they enter their standard password.
|
||||
|
||||
:warning: Serving 2FA/OTP registration links over insecure (HTTP) can expose secrets intended for the user and is **highly** discouraged!
|
||||
|
||||
:memo: +ops can also manually enable or disable 2FA/OTP for a user using [oputil](../admin/oputil.md), but this is generally discouraged.
|
||||
|
||||
#### Recovery
|
||||
In the situation that a user loses their 2FA/OTP device (such as a lost phone with Google Auth), there are some options:
|
||||
* Utilize one of their backup codes.
|
||||
* Contact the SysOp.
|
||||
|
||||
:warning: There is no way for a user to disable 2FA/OTP without first fully logging in! This is by design as a security measure.
|
||||
|
||||
### ACS Checks
|
||||
Various places throughout the system that implement [ACS](../configuration/acs.md) can make 2FA specific checks:
|
||||
* `AR#`: Current users **required** authentication factor. `AR2` for example means 2FA/OTP is required for this user.
|
||||
* `AF#`: Current users **active** authentication factor. `AF2` means the user is authenticated with some sort of 2FA (such as One-Time-Password).
|
||||
|
||||
See [ACS](../configuration/acs.md) for more information.
|
||||
|
||||
#### Example
|
||||
The following example illustrates using an `AR` ACS check to require applicable users to go through an additional 2FA/OTP process during login:
|
||||
|
||||
```hjson
|
||||
login: {
|
||||
art: USERLOG
|
||||
next: [
|
||||
{
|
||||
// users with AR2+ must first pass 2FA/OTP
|
||||
acs: AR2
|
||||
next: loginTwoFactorAuthOTP
|
||||
}
|
||||
{
|
||||
// everyone else skips ahead
|
||||
next: fullLoginSequenceLoginArt
|
||||
}
|
||||
]
|
||||
// ...
|
||||
}
|
||||
```
|
5
docs/_docs/configuration/sysop-setup.md
Normal file
5
docs/_docs/configuration/sysop-setup.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
layout: page
|
||||
title: SysOp Setup
|
||||
---
|
||||
SySop privileges will be granted to the first user to log into a fresh ENiGMA½ installation. +ops belong to the `sysop` user group by default.
|
Loading…
Add table
Add a link
Reference in a new issue