2020-06-07 21:26:11 +00:00
const paths = require ( 'path' ) ;
module . exports = ( ) => {
return {
2022-06-05 20:04:25 +00:00
general : {
boardName : 'Another Fine ENiGMA½ BBS' ,
prettyBoardName : '|08A|07nother |07F|08ine |07E|08NiGMA|07½ B|08BS' ,
telnetHostname : '' ,
sshHostname : '' ,
website : 'https://enigma-bbs.github.io' ,
description : 'An ENiGMA½ BBS' ,
2020-06-07 21:26:11 +00:00
// :TODO: closedSystem prob belongs under users{}?
2022-06-05 20:04:25 +00:00
closedSystem : false , // is the system closed to new users?
2020-06-07 21:26:11 +00:00
2022-06-05 20:04:25 +00:00
menuFile : 'menu.hjson' , // 'oputil.js config new' will set this appropriately in config.hjson; may be full path
achievementFile : 'achievements.hjson' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
term : {
2022-03-23 23:43:49 +00:00
// checkUtf8Encoding requires the use of cursor position reports, which are not supported on all terminals.
// Using this with a terminal that does not support cursor position reports results in a 2 second delay
// during the connect process, but provides better autoconfiguration of utf-8
2022-06-05 20:04:25 +00:00
checkUtf8Encoding : true ,
2022-03-23 23:43:49 +00:00
2022-03-28 19:18:00 +00:00
// Checking the ANSI home position also requires the use of cursor position reports, which are not
// supported on all terminals. Using this with a terminal that does not support cursor position reports
// results in a 3 second delay during the connect process, but works around positioning problems with
// non-standard terminals.
checkAnsiHomePosition : true ,
2022-03-23 23:43:49 +00:00
// List of terms that should be assumed to use cp437 encoding
2022-06-05 20:04:25 +00:00
cp437TermList : [
'ansi' ,
'pcansi' ,
'pc-ansi' ,
'ansi-bbs' ,
'qansi' ,
'scoansi' ,
'syncterm' ,
'ansi-256color' ,
'ansi-256color-rgb' ,
] ,
2022-03-23 23:43:49 +00:00
// List of terms that should be assumed to use utf8 encoding
2022-06-05 20:04:25 +00:00
utf8TermList : [
'xterm' ,
'linux' ,
'screen' ,
'dumb' ,
'rxvt' ,
'konsole' ,
'gnome' ,
'x11 terminal emulator' ,
] ,
2022-03-23 23:43:49 +00:00
} ,
2022-06-05 20:04:25 +00:00
users : {
usernameMin : 2 ,
usernameMax : 16 , // Note that FidoNet wants 36 max
usernamePattern : '^[A-Za-z0-9~!@#$%^&*()\\-\\_+ .]+$' ,
2020-06-07 21:26:11 +00:00
2022-06-05 20:04:25 +00:00
passwordMin : 6 ,
passwordMax : 128 ,
2020-06-07 21:26:11 +00:00
//
// The bad password list is a text file containing a password per line.
// Entries in this list are not allowed to be used on the system as they
// are known to be too common.
//
// A great resource can be found at https://github.com/danielmiessler/SecLists
//
// Current list source: https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/probable-v2-top12000.txt
//
2022-06-05 20:04:25 +00:00
badPassFile : paths . join ( _ _dirname , '../misc/bad_passwords.txt' ) ,
realNameMax : 32 ,
locationMax : 32 ,
affilsMax : 32 ,
emailMax : 255 ,
webMax : 255 ,
requireActivation : false , // require SysOp activation? false = auto-activate
groups : [ 'users' , 'sysops' ] , // built in groups
defaultGroups : [ 'users' ] , // default groups new users belong to
newUserNames : [ 'new' , 'apply' ] , // Names reserved for applying
badUserNames : [
'sysop' ,
'admin' ,
'administrator' ,
'root' ,
'all' ,
'areamgr' ,
'filemgr' ,
'filefix' ,
'areafix' ,
'allfix' ,
'server' ,
'client' ,
'notme' ,
2020-06-07 21:26:11 +00:00
] ,
2022-06-05 20:04:25 +00:00
preAuthIdleLogoutSeconds : 60 * 3 , // 3m
idleLogoutSeconds : 60 * 6 , // 6m
2020-06-07 21:26:11 +00:00
2022-06-05 20:04:25 +00:00
failedLogin : {
disconnect : 3 , // 0=disabled
lockAccount : 9 , // 0=disabled; Mark user status as "locked" if >= N
autoUnlockMinutes : 60 * 6 , // 0=disabled; Auto unlock after N minutes.
} ,
unlockAtEmailPwReset : true , // if true, password reset via email will unlock locked accounts
twoFactorAuth : {
method : 'googleAuth' ,
otp : {
registerEmailText : paths . join (
_ _dirname ,
'../misc/otp_register_email.template.txt'
) ,
registerEmailHtml : paths . join (
_ _dirname ,
'../misc/otp_register_email.template.html'
) ,
registerPageTemplate : paths . join (
_ _dirname ,
'../www/otp_register.template.html'
) ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2023-01-22 03:57:22 +00:00
// path to avatar generation parts
avatars : {
storagePath : paths . join ( _ _dirname , '../userdata/avatars/' ) ,
spritesPath : paths . join ( _ _dirname , '../misc/avatar-sprites/' ) ,
} ,
2023-01-28 18:55:31 +00:00
// See also ./core/activitypub/settings.js
activityPub : {
enabled : true , // ActivityPub enabled for this user?
manuallyApproveFollowers : false ,
hideSocialGraph : false ,
showRealName : true ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
theme : {
default : 'luciano_blocktronics' ,
preLogin : 'luciano_blocktronics' ,
2020-06-07 21:26:11 +00:00
2022-06-05 20:04:25 +00:00
passwordChar : '*' ,
dateFormat : {
short : 'MM/DD/YYYY' ,
long : 'ddd, MMMM Do, YYYY' ,
} ,
timeFormat : {
short : 'h:mm a' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
dateTimeFormat : {
short : 'MM/DD/YYYY h:mm a' ,
long : 'ddd, MMMM Do, YYYY, h:mm a' ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
menus : {
cls : true , // Clear screen before each menu by default?
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
paths : {
config : paths . join ( _ _dirname , './../config/' ) ,
security : paths . join ( _ _dirname , './../config/security' ) , // certs, keys, etc.
mods : paths . join ( _ _dirname , './../mods/' ) ,
loginServers : paths . join ( _ _dirname , './servers/login/' ) ,
contentServers : paths . join ( _ _dirname , './servers/content/' ) ,
2022-12-31 05:35:18 +00:00
webHandlers : paths . join ( _ _dirname , './servers/content/web_handlers' ) ,
2022-06-05 20:04:25 +00:00
chatServers : paths . join ( _ _dirname , './servers/chat/' ) ,
scannerTossers : paths . join ( _ _dirname , './scanner_tossers/' ) ,
mailers : paths . join ( _ _dirname , './mailers/' ) ,
art : paths . join ( _ _dirname , './../art/general/' ) ,
themes : paths . join ( _ _dirname , './../art/themes/' ) ,
logs : paths . join ( _ _dirname , './../logs/' ) ,
db : paths . join ( _ _dirname , './../db/' ) ,
modsDb : paths . join ( _ _dirname , './../db/mods/' ) ,
dropFiles : paths . join ( _ _dirname , './../drop/' ) , // + "/node<x>/
misc : paths . join ( _ _dirname , './../misc/' ) ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
loginServers : {
telnet : {
port : 8888 ,
enabled : true ,
firstMenu : 'telnetConnected' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
ssh : {
port : 8889 ,
enabled : false , // default to false as PK/pass in config.hjson are required
2020-06-07 21:26:11 +00:00
//
// To enable SSH, perform the following steps:
//
// 1 - Generate a Private Key (PK):
// Currently ENiGMA 1/2 requires a PKCS#1 PEM formatted PK.
// To generate a secure PK, issue the following command:
//
// > openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
// -pkeyopt rsa_keygen_pubexp:65537 | openssl rsa \
// -out ./config/security/ssh_private_key.pem -aes128
//
// (The above is a more modern equivalent of the following):
// > openssl genrsa -aes128 -out ./config/security/ssh_private_key.pem 2048
//
// 2 - Set 'privateKeyPass' to the password you used in step #1
//
// 3 - Finally, set 'enabled' to 'true'
//
// Additional reading:
// - https://blog.sleeplessbeastie.eu/2017/12/28/how-to-generate-private-key/
// - https://gist.github.com/briansmith/2ee42439923d8e65a266994d0f70180b
//
2022-06-05 20:04:25 +00:00
privateKeyPem : paths . join (
_ _dirname ,
'./../config/security/ssh_private_key.pem'
) ,
firstMenu : 'sshConnected' ,
firstMenuNewUser : 'sshConnectedNewUser' ,
2020-06-07 21:26:11 +00:00
//
// SSH details that can affect security. Stronger ciphers are better for example,
// but terminals such as SyncTERM require KEX diffie-hellman-group14-sha1,
// cipher 3des-cbc, etc.
//
// See https://github.com/mscdex/ssh2-streams for the full list of supported
// algorithms.
//
2022-06-05 20:04:25 +00:00
algorithms : {
kex : [
2020-06-07 21:26:11 +00:00
'ecdh-sha2-nistp256' ,
'ecdh-sha2-nistp384' ,
'ecdh-sha2-nistp521' ,
'diffie-hellman-group14-sha1' ,
'diffie-hellman-group1-sha1' ,
2022-04-06 16:01:21 +00:00
// Group exchange not currnetly supported
// 'diffie-hellman-group-exchange-sha256',
// 'diffie-hellman-group-exchange-sha1',
2020-06-07 21:26:11 +00:00
] ,
2022-06-05 20:04:25 +00:00
cipher : [
2020-06-07 21:26:11 +00:00
'aes128-ctr' ,
'aes192-ctr' ,
'aes256-ctr' ,
'aes128-gcm' ,
'aes128-gcm@openssh.com' ,
'aes256-gcm' ,
'aes256-gcm@openssh.com' ,
'aes256-cbc' ,
'aes192-cbc' ,
'aes128-cbc' ,
'blowfish-cbc' ,
'3des-cbc' ,
'arcfour256' ,
'arcfour128' ,
'cast128-cbc' ,
'arcfour' ,
] ,
2022-06-05 20:04:25 +00:00
hmac : [
2020-06-07 21:26:11 +00:00
'hmac-sha2-256' ,
'hmac-sha2-512' ,
'hmac-sha1' ,
'hmac-md5' ,
'hmac-sha2-256-96' ,
'hmac-sha2-512-96' ,
'hmac-ripemd160' ,
'hmac-sha1-96' ,
'hmac-md5-96' ,
] ,
// note that we disable compression by default due to issues with many clients. YMMV.
2022-06-05 20:04:25 +00:00
compress : [ 'none' ] ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
webSocket : {
ws : {
2020-06-07 21:26:11 +00:00
// non-secure ws://
2022-06-05 20:04:25 +00:00
enabled : false ,
port : 8810 ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
wss : {
2020-06-07 21:26:11 +00:00
// secure ws://
// must provide valid certPem and keyPem
2022-06-05 20:04:25 +00:00
enabled : false ,
port : 8811 ,
certPem : paths . join ( _ _dirname , './../config/https_cert.pem' ) ,
keyPem : paths . join ( _ _dirname , './../config/https_cert_key.pem' ) ,
2020-06-07 21:26:11 +00:00
} ,
} ,
} ,
2022-06-05 20:04:25 +00:00
contentServers : {
web : {
domain : 'another-fine-enigma-bbs.org' ,
2020-06-07 21:26:11 +00:00
2022-06-05 20:04:25 +00:00
staticRoot : paths . join ( _ _dirname , './../www' ) ,
2020-06-07 21:26:11 +00:00
2023-02-02 06:02:33 +00:00
// Logging block works the same way the system logger does
logging : {
rotatingFile : {
level : 'info' ,
type : 'rotating-file' ,
fileName : 'enigma-bbs.web.log' ,
period : '1d' ,
count : 3 ,
} ,
} ,
2023-01-22 17:18:52 +00:00
handlers : {
systemGeneral : {
enabled : true ,
} ,
2023-01-30 19:30:36 +00:00
nodeInfo2 : {
enabled : true ,
} ,
2023-01-22 17:18:52 +00:00
} ,
2022-06-05 20:04:25 +00:00
resetPassword : {
2020-06-07 21:26:11 +00:00
//
// The following templates have these variables available to them:
//
// * %BOARDNAME% : Name of BBS
// * %USERNAME% : Username of whom to reset password
// * %TOKEN% : Reset token
// * %RESET_URL% : In case of email, the link to follow for reset. In case of landing page,
// URL to POST submit reset form.
// templates for pw reset *email*
2022-06-05 20:04:25 +00:00
resetPassEmailText : paths . join (
_ _dirname ,
'../misc/reset_password_email.template.txt'
) , // plain text version
resetPassEmailHtml : paths . join (
_ _dirname ,
'../misc/reset_password_email.template.html'
) , // HTML version
2020-06-07 21:26:11 +00:00
// tempalte for pw reset *landing page*
//
2022-06-05 20:04:25 +00:00
resetPageTemplate : paths . join (
_ _dirname ,
'./../www/reset_password.template.html'
) ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
http : {
enabled : false ,
port : 8080 ,
} ,
https : {
enabled : false ,
port : 8443 ,
certPem : paths . join ( _ _dirname , './../config/https_cert.pem' ) ,
keyPem : paths . join ( _ _dirname , './../config/https_cert_key.pem' ) ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
gopher : {
enabled : false ,
port : 8070 ,
publicHostname : 'another-fine-enigma-bbs.org' ,
publicPort : 8070 , // adjust if behind NAT/etc.
staticRoot : paths . join ( _ _dirname , './../gopher' ) ,
2020-06-07 21:26:11 +00:00
//
// Set messageConferences{} to maps of confTag -> [ areaTag1, areaTag2, ... ]
// to export message confs/areas
//
} ,
2022-06-05 20:04:25 +00:00
nntp : {
2020-06-07 21:26:11 +00:00
// internal caching of groups, message lists, etc.
2022-06-05 20:04:25 +00:00
cache : {
maxItems : 200 ,
maxAge : 1000 * 30 , // 30s
2020-06-07 21:26:11 +00:00
} ,
//
// Set publicMessageConferences{} to a map of confTag -> [ areaTag1, areaTag2, ... ]
// in order to export *public* conf/areas that are available to anonymous
// NNTP users. Other conf/areas: Standard ACS rules apply.
//
publicMessageConferences : { } ,
2022-06-05 20:04:25 +00:00
nntp : {
enabled : false ,
port : 8119 ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
nntps : {
enabled : false ,
port : 8563 ,
certPem : paths . join ( _ _dirname , './../config/nntps_cert.pem' ) ,
keyPem : paths . join ( _ _dirname , './../config/nntps_key.pem' ) ,
} ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
chatServers : {
2020-06-07 21:26:11 +00:00
mrc : {
2022-06-05 20:04:25 +00:00
enabled : false ,
serverHostname : 'mrc.bottomlessabyss.net' ,
serverPort : 5000 ,
retryDelay : 10000 ,
multiplexerPort : 5000 ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2023-02-04 18:51:47 +00:00
// General ActivityPub integration configuration
activityPub : {
// Mimics Mastodon max 500 characters for *outgoing* Notes
// (messages destined for ActivityPub); This is a soft limit;
// Implementations including Mastodon should still display
// longer messages, but this keeps us as a "good citizen"
autoSignatures : false ,
// by default, don't include auto-signatures in AP outgoing
maxMessageLength : 500 ,
} ,
2022-06-05 20:04:25 +00:00
infoExtractUtils : {
Exiftool2Desc : {
cmd : ` ${ _ _dirname } /../util/exiftool2desc.js ` , // ensure chmod +x
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
Exiftool : {
cmd : 'exiftool' ,
args : [
'-charset' ,
'utf8' ,
'{filePath}' ,
2020-06-07 21:26:11 +00:00
// exclude the following:
2022-06-05 20:04:25 +00:00
'--directory' ,
'--filepermissions' ,
'--exiftoolversion' ,
'--filename' ,
'--filesize' ,
'--filemodifydate' ,
'--fileaccessdate' ,
'--fileinodechangedate' ,
'--createdate' ,
'--modifydate' ,
'--metadatadate' ,
'--xmptoolkit' ,
] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
XDMS2Desc : {
2020-06-07 21:26:11 +00:00
// http://manpages.ubuntu.com/manpages/trusty/man1/xdms.1.html
2022-06-05 20:04:25 +00:00
cmd : 'xdms' ,
args : [ 'd' , '{filePath}' ] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
XDMS2LongDesc : {
2020-06-07 21:26:11 +00:00
// http://manpages.ubuntu.com/manpages/trusty/man1/xdms.1.html
2022-06-05 20:04:25 +00:00
cmd : 'xdms' ,
args : [ 'f' , '{filePath}' ] ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
fileTypes : {
2020-06-07 21:26:11 +00:00
//
// File types explicitly known to the system. Here we can configure
// information extraction, archive treatment, etc.
//
// MIME types can be found in mime-db: https://github.com/jshttp/mime-db
//
// Resources for signature/magic bytes:
// * http://www.garykessler.net/library/file_sigs.html
//
//
// :TODO: text/x-ansi -> SAUCE extraction for .ans uploads
// :TODO: textual : bool -- if text, we can view.
// :TODO: asText : { cmd, args[] } -> viewable text
//
// Audio
//
2022-06-05 20:04:25 +00:00
'audio/mpeg' : {
desc : 'MP3 Audio' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
'application/pdf' : {
desc : 'Adobe PDF' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
2020-06-07 21:26:11 +00:00
} ,
//
// Video
//
2022-06-05 20:04:25 +00:00
'video/mp4' : {
desc : 'MPEG Video' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
'video/x-matroska ' : {
desc : 'Matroska Video' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
'video/x-msvideo' : {
desc : 'Audio Video Interleave' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
2020-06-07 21:26:11 +00:00
} ,
//
// Images
//
2022-06-05 20:04:25 +00:00
'image/jpeg' : {
desc : 'JPEG Image' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
} ,
'image/png' : {
desc : 'Portable Network Graphic Image' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
} ,
'image/gif' : {
desc : 'Graphics Interchange Format Image' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
} ,
'image/webp' : {
desc : 'WebP Image' ,
shortDescUtil : 'Exiftool2Desc' ,
longDescUtil : 'Exiftool' ,
2020-06-07 21:26:11 +00:00
} ,
//
// Archives
//
2022-06-05 20:04:25 +00:00
'application/zip' : {
desc : 'ZIP Archive' ,
sig : '504b0304' ,
offset : 0 ,
archiveHandler : 'InfoZip' ,
2020-06-07 21:26:11 +00:00
} ,
/ *
'application/x-cbr' : {
desc : 'Comic Book Archive' ,
sig : '504b0304' ,
} ,
* /
2022-06-05 20:04:25 +00:00
'application/x-arj' : {
desc : 'ARJ Archive' ,
sig : '60ea' ,
offset : 0 ,
archiveHandler : 'Arj' ,
} ,
'application/x-rar-compressed' : {
desc : 'RAR Archive' ,
sig : '526172211a07' ,
offset : 0 ,
archiveHandler : 'Rar' ,
} ,
'application/gzip' : {
desc : 'Gzip Archive' ,
sig : '1f8b' ,
offset : 0 ,
archiveHandler : 'TarGz' ,
2020-06-07 21:26:11 +00:00
} ,
// :TODO: application/x-bzip
2022-06-05 20:04:25 +00:00
'application/x-bzip2' : {
desc : 'BZip2 Archive' ,
sig : '425a68' ,
offset : 0 ,
archiveHandler : '7Zip' ,
} ,
'application/x-lzh-compressed' : {
desc : 'LHArc Archive' ,
sig : '2d6c68' ,
offset : 2 ,
archiveHandler : 'Lha' ,
} ,
'application/x-lzx' : {
desc : 'LZX Archive' ,
sig : '4c5a5800' ,
offset : 0 ,
archiveHandler : 'Lzx' ,
} ,
'application/x-7z-compressed' : {
desc : '7-Zip Archive' ,
sig : '377abcaf271c' ,
offset : 0 ,
archiveHandler : '7Zip' ,
2020-06-07 21:26:11 +00:00
} ,
//
// Generics that need further mapping
//
2022-06-05 20:04:25 +00:00
'application/octet-stream' : [
2020-06-07 21:26:11 +00:00
{
2022-06-05 20:04:25 +00:00
desc : 'Amiga DISKMASHER' ,
sig : '444d5321' , // DMS!
ext : '.dms' ,
shortDescUtil : 'XDMS2Desc' ,
longDescUtil : 'XDMS2LongDesc' ,
2020-06-07 21:26:11 +00:00
} ,
{
2022-06-05 20:04:25 +00:00
desc : 'SIO2PC Atari Disk Image' ,
sig : '9602' , // 16bit sum of "NICKATARI"
ext : '.atr' ,
archiveHandler : 'Atr' ,
} ,
] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
archives : {
archivers : {
'7Zip' : {
// p7zip package
compress : {
cmd : '7za' ,
args : [ 'a' , '-tzip' , '{archivePath}' , '{fileList}' ] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
decompress : {
cmd : '7za' ,
args : [ 'e' , '-y' , '-o{extractPath}' , '{archivePath}' ] , // :TODO: should be 'x'?
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
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]+)$' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
extract : {
cmd : '7za' ,
args : [
'e' ,
'-y' ,
'-o{extractPath}' ,
'{archivePath}' ,
'{fileList}' ,
] ,
2020-06-07 21:26:11 +00:00
} ,
} ,
InfoZip : {
2022-06-05 20:04:25 +00:00
compress : {
cmd : 'zip' ,
args : [ '{archivePath}' , '{fileList}' ] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
decompress : {
cmd : 'unzip' ,
args : [ '-n' , '{archivePath}' , '-d' , '{extractPath}' ] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
list : {
cmd : 'unzip' ,
args : [ '-l' , '{archivePath}' ] ,
2020-06-07 21:26:11 +00:00
// Annoyingly, dates can be in YYYY-MM-DD or MM-DD-YYYY format
2022-06-05 20:04:25 +00:00
entryMatch :
'^\\s*([0-9]+)\\s+[0-9]{2,4}-[0-9]{2}-[0-9]{2,4}\\s+[0-9]{2}:[0-9]{2}\\s+([^\\r\\n]+)$' ,
} ,
extract : {
cmd : 'unzip' ,
args : [
'-n' ,
'{archivePath}' ,
'{fileList}' ,
'-d' ,
'{extractPath}' ,
] ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
Lha : {
2020-06-07 21:26:11 +00:00
//
// 'lha' command can be obtained from:
// * apt-get: lhasa
//
// (compress not currently supported)
//
2022-06-05 20:04:25 +00:00
decompress : {
cmd : 'lha' ,
args : [ '-efw={extractPath}' , '{archivePath}' ] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
list : {
cmd : 'lha' ,
args : [ '-l' , '{archivePath}' ] ,
entryMatch :
'^[\\[a-z\\]]+(?:\\s+[0-9]+\\s+[0-9]+|\\s+)([0-9]+)\\s+[0-9]{2}\\.[0-9]\\%\\s+[A-Za-z]{3}\\s+[0-9]{1,2}\\s+[0-9]{4}\\s+([^\\r\\n]+)$' ,
} ,
extract : {
cmd : 'lha' ,
args : [ '-efw={extractPath}' , '{archivePath}' , '{fileList}' ] ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
Lzx : {
2020-06-07 21:26:11 +00:00
//
// 'unlzx' command can be obtained from:
// * Debian based: https://launchpad.net/~rzr/+archive/ubuntu/ppa/+build/2486127 (amd64/x86_64)
// * RedHat: https://fedora.pkgs.org/28/rpm-sphere/unlzx-1.1-4.1.x86_64.rpm.html
// * Source: http://xavprods.free.fr/lzx/
//
2022-06-05 20:04:25 +00:00
decompress : {
cmd : 'unlzx' ,
2020-06-07 21:26:11 +00:00
// unzlx doesn't have a output dir option, but we'll cwd to the temp output dir first
2022-06-05 20:04:25 +00:00
args : [ '-x' , '{archivePath}' ] ,
} ,
list : {
cmd : 'unlzx' ,
args : [ '-v' , '{archivePath}' ] ,
entryMatch :
'^\\s+([0-9]+)\\s+[^\\s]+\\s+[0-9]{2}:[0-9]{2}:[0-9]{2}\\s+[0-9]{1,2}-[a-z]{3}-[0-9]{4}\\s+[a-z\\-]+\\s+\\"([^"]+)\\"$' ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
Arj : {
2020-06-07 21:26:11 +00:00
//
// 'arj' command can be obtained from:
// * apt-get: arj
//
2022-06-05 20:04:25 +00:00
decompress : {
cmd : 'arj' ,
args : [ 'x' , '{archivePath}' , '{extractPath}' ] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
list : {
cmd : 'arj' ,
args : [ 'l' , '{archivePath}' ] ,
entryMatch :
'^([^\\s]+)\\s+([0-9]+)\\s+[0-9]+\\s[0-9\\.]+\\s+[0-9]{2}\\-[0-9]{2}\\-[0-9]{2}\\s[0-9]{2}\\:[0-9]{2}\\:[0-9]{2}\\s+(?:[^\\r\\n]+)$' ,
entryGroupOrder : {
// defaults to { byteSize : 1, fileName : 2 }
fileName : 1 ,
byteSize : 2 ,
} ,
} ,
extract : {
cmd : 'arj' ,
args : [ 'e' , '{archivePath}' , '{extractPath}' , '{fileList}' ] ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
Rar : {
decompress : {
cmd : 'unrar' ,
args : [ 'x' , '{archivePath}' , '{extractPath}' ] ,
} ,
list : {
cmd : 'unrar' ,
args : [ 'l' , '{archivePath}' ] ,
entryMatch :
'^\\s+[\\.A-Z]+\\s+([\\d]+)\\s{2}[0-9]{2,4}\\-[0-9]{2}\\-[0-9]{2}\\s[0-9]{2}\\:[0-9]{2}\\s{2}([^\\r\\n]+)$' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
extract : {
cmd : 'unrar' ,
args : [ 'e' , '{archivePath}' , '{extractPath}' , '{fileList}' ] ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
TarGz : {
decompress : {
cmd : 'tar' ,
args : [
'-xf' ,
'{archivePath}' ,
'-C' ,
'{extractPath}' ,
'--strip-components=1' ,
] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
list : {
cmd : 'tar' ,
args : [ '-tvf' , '{archivePath}' ] ,
entryMatch :
'^[drwx\\-]{10}\\s[A-Za-z0-9\\/]+\\s+([0-9]+)\\s[0-9]{4}\\-[0-9]{2}\\-[0-9]{2}\\s[0-9]{2}\\:[0-9]{2}\\s([^\\r\\n]+)$' ,
} ,
extract : {
cmd : 'tar' ,
args : [
'-xvf' ,
'{archivePath}' ,
'-C' ,
'{extractPath}' ,
'{fileList}' ,
] ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
Atr : {
decompress : {
cmd : 'atr' ,
args : [ '{archivePath}' , 'x' , '-a' , '-o' , '{extractPath}' ] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
list : {
cmd : 'atr' ,
args : [ '{archivePath}' , 'ls' , '-la1' ] ,
entryMatch :
'^[rwxs-]{5}\\s+([0-9]+)\\s\\([0-9\\s]+\\)\\s([^\\r\\n\\s]*)(?:[^\\r\\n]+)?$' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
extract : {
cmd : 'atr' ,
2020-06-07 21:26:11 +00:00
// note: -l converts Atari 0x9b line feeds to 0x0a; not ideal if we're dealing with a binary of course.
2022-06-05 20:04:25 +00:00
args : [
'{archivePath}' ,
'x' ,
'-a' ,
'-l' ,
'-o' ,
'{extractPath}' ,
'{fileList}' ,
] ,
} ,
} ,
2020-06-07 21:26:11 +00:00
} ,
} ,
2022-06-05 20:04:25 +00:00
fileTransferProtocols : {
2020-06-07 21:26:11 +00:00
//
// See http://www.synchro.net/docs/sexyz.txt for information on SEXYZ
//
2022-06-05 20:04:25 +00:00
zmodem8kSexyz : {
name : 'ZModem 8k (SEXYZ)' ,
type : 'external' ,
sort : 1 ,
external : {
2020-06-07 21:26:11 +00:00
// :TODO: Look into shipping sexyz binaries or at least hosting them somewhere for common systems
// Linux x86_64 binary: https://l33t.codes/outgoing/sexyz
2022-06-05 20:04:25 +00:00
sendCmd : 'sexyz' ,
sendArgs : [ '-telnet' , '-8' , 'sz' , '@{fileListPath}' ] ,
recvCmd : 'sexyz' ,
recvArgs : [ '-telnet' , '-8' , 'rz' , '{uploadDir}' ] ,
recvArgsNonBatch : [ '-telnet' , '-8' , 'rz' , '{fileName}' ] ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
xmodemSexyz : {
name : 'XModem (SEXYZ)' ,
type : 'external' ,
sort : 3 ,
external : {
sendCmd : 'sexyz' ,
sendArgs : [ '-telnet' , 'sX' , '@{fileListPath}' ] ,
recvCmd : 'sexyz' ,
recvArgsNonBatch : [ '-telnet' , 'rC' , '{fileName}' ] ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
ymodemSexyz : {
name : 'YModem (SEXYZ)' ,
type : 'external' ,
sort : 4 ,
external : {
sendCmd : 'sexyz' ,
sendArgs : [ '-telnet' , 'sY' , '@{fileListPath}' ] ,
recvCmd : 'sexyz' ,
recvArgs : [ '-telnet' , 'ry' , '{uploadDir}' ] ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
zmodem8kSz : {
name : 'ZModem 8k' ,
type : 'external' ,
sort : 2 ,
external : {
sendCmd : 'sz' , // Avail on Debian/Ubuntu based systems as the package "lrzsz"
sendArgs : [
2020-06-07 21:26:11 +00:00
// :TODO: try -q
2022-06-05 20:04:25 +00:00
'--zmodem' ,
'--try-8k' ,
'--binary' ,
'--restricted' ,
'{filePaths}' ,
2020-06-07 21:26:11 +00:00
] ,
2022-06-05 20:04:25 +00:00
recvCmd : 'rz' , // Avail on Debian/Ubuntu based systems as the package "lrzsz"
recvArgs : [
'--zmodem' ,
'--binary' ,
'--restricted' ,
'--keep-uppercase' , // dumps to CWD which is set to {uploadDir}
2020-06-07 21:26:11 +00:00
] ,
2022-06-05 20:04:25 +00:00
processIACs : true , // escape/de-escape IACs (0xff)
} ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
messageAreaDefaults : {
2020-06-07 21:26:11 +00:00
//
// The following can be override per-area as well
//
2022-06-05 20:04:25 +00:00
maxMessages : 1024 , // 0 = unlimited
maxAgeDays : 0 , // 0 = unlimited
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
messageConferences : {
system _internal : {
name : 'System Internal' ,
desc : 'Built in conference for private messages, bulletins, etc.' ,
2020-06-07 21:26:11 +00:00
2022-06-05 20:04:25 +00:00
areas : {
private _mail : {
name : 'Private Mail' ,
desc : 'Private user to user mail/email' ,
maxExternalSentAgeDays : 30 , // max external "outbox" item age
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
local _bulletin : {
name : 'System Bulletins' ,
desc : 'Bulletin messages for all users' ,
} ,
2023-02-06 04:10:51 +00:00
} ,
} ,
2023-02-05 05:55:11 +00:00
2023-02-06 04:10:51 +00:00
activity _pub : {
name : 'ActivityPub Shared Inbox' ,
desc : 'Public and shared ActivityPub messages' ,
areas : {
activitypub _shared : {
2023-02-05 05:55:11 +00:00
name : 'ActivityPub sharedInbox' ,
desc : 'Public shared inbox for ActivityPub' ,
2023-02-06 04:10:51 +00:00
alwaysExportExternal : true ,
subjectOptional : true ,
addressFlavor : 'activitypub' ,
2023-02-05 05:55:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
} ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
scannerTossers : {
ftn _bso : {
paths : {
outbound : paths . join ( _ _dirname , './../mail/ftn_out/' ) ,
inbound : paths . join ( _ _dirname , './../mail/ftn_in/' ) ,
secInbound : paths . join ( _ _dirname , './../mail/ftn_secin/' ) ,
reject : paths . join ( _ _dirname , './../mail/reject/' ) , // bad pkt, bundles, TIC attachments that fail any check, etc.
2020-06-07 21:26:11 +00:00
//outboundNetMail : paths.join(__dirname, './../mail/ftn_netmail_out/'),
// set 'retain' to a valid path to keep good pkt files
} ,
//
// Packet and (ArcMail) bundle target sizes are just that: targets.
// Actual sizes may be slightly larger when we must place a full
// PKT contents *somewhere*
//
2022-06-05 20:04:25 +00:00
packetTargetByteSize : 512000 , // 512k, before placing messages in a new pkt
bundleTargetByteSize : 2048000 , // 2M, before creating another archive
packetMsgEncoding : 'utf8' , // default packet encoding. Override per node if desired.
packetAnsiMsgEncoding : 'cp437' , // packet encoding for *ANSI ART* messages
tic : {
secureInOnly : true , // only bring in from secure inbound (|secInbound| path, password protected)
uploadBy : 'ENiGMA TIC' , // default upload by username (override @ network)
allowReplace : false , // use "Replaces" TIC field
descPriority : 'diz' , // May be diz=.DIZ/etc., or tic=from TIC Ldesc
} ,
} ,
2020-06-07 21:26:11 +00:00
} ,
fileBase : {
// areas with an explicit |storageDir| will be stored relative to |areaStoragePrefix|:
2022-06-05 20:04:25 +00:00
areaStoragePrefix : paths . join ( _ _dirname , './../file_base/' ) ,
2020-06-07 21:26:11 +00:00
2022-06-05 20:04:25 +00:00
maxDescFileByteSize : 471859 , // ~1/4 MB
maxDescLongFileByteSize : 524288 , // 1/2 MB
2020-06-07 21:26:11 +00:00
fileNamePatterns : {
// These are NOT case sensitive
// FILE_ID.DIZ - https://en.wikipedia.org/wiki/FILE_ID.DIZ
// Some groups include a FILE_ID.ANS. We try to use that over FILE_ID.DIZ if available.
2022-06-05 20:04:25 +00:00
desc : [
'^.*FILE_ID.ANS$' ,
'^.*FILE_ID.DIZ$' , // eslint-disable-line no-useless-escape
'^.*DESC.SDI$' , // eslint-disable-line no-useless-escape
'^.*DESCRIPT.ION$' , // eslint-disable-line no-useless-escape
'^.*FILE.DES$' , // eslint-disable-line no-useless-escape
'^.*FILE.SDI$' , // eslint-disable-line no-useless-escape
'^.*DISK.ID$' , // eslint-disable-line no-useless-escape
2020-06-07 21:26:11 +00:00
] ,
// common README filename - https://en.wikipedia.org/wiki/README
2022-06-05 20:04:25 +00:00
descLong : [
'^[^/]*.NFO$' , // eslint-disable-line no-useless-escape
'^.*README.1ST$' , // eslint-disable-line no-useless-escape
'^.*README.NOW$' , // eslint-disable-line no-useless-escape
'^.*README.TXT$' , // eslint-disable-line no-useless-escape
'^.*READ.ME$' , // eslint-disable-line no-useless-escape
'^.*README$' , // eslint-disable-line no-useless-escape
'^.*README.md$' , // eslint-disable-line no-useless-escape
'^RELEASE-INFO.ASC$' , // eslint-disable-line no-useless-escape
2020-06-07 21:26:11 +00:00
] ,
} ,
yearEstPatterns : [
//
// Patterns should produce the year in the first submatch.
// The extracted year may be YY or YYYY
//
2022-06-05 20:04:25 +00:00
'\\b((?:[1-2][0-9][0-9]{2}))[\\-\\/\\.][0-3]?[0-9][\\-\\/\\.][0-3]?[0-9]\\b' , // yyyy-mm-dd, yyyy/mm/dd, ...
'\\b[0-3]?[0-9][\\-\\/\\.][0-3]?[0-9][\\-\\/\\.]((?:[1-2][0-9][0-9]{2}))\\b' , // mm/dd/yyyy, mm.dd.yyyy, ...
'\\b((?:[1789][0-9]))[\\-\\/\\.][0-3]?[0-9][\\-\\/\\.][0-3]?[0-9]\\b' , // yy-mm-dd, yy-mm-dd, ...
'\\b[0-3]?[0-9][\\-\\/\\.][0-3]?[0-9][\\-\\/\\.]((?:[1789][0-9]))\\b' , // mm-dd-yy, mm/dd/yy, ...
2020-06-07 21:26:11 +00:00
//'\\b((?:[1-2][0-9][0-9]{2}))[\\-\\/\\.][0-3]?[0-9][\\-\\/\\.][0-3]?[0-9]|[0-3]?[0-9][\\-\\/\\.][0-3]?[0-9][\\-\\/\\.]((?:[0-9]{2})?[0-9]{2})\\b', // yyyy-mm-dd, m/d/yyyy, mm-dd-yyyy, etc.
//"\\b('[1789][0-9])\\b", // eslint-disable-line quotes
'\\b[0-3]?[0-9][\\-\\/\\.](?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec|january|february|march|april|may|june|july|august|september|october|november|december)[\\-\\/\\.]((?:[0-9]{2})?[0-9]{2})\\b' ,
2022-06-05 20:04:25 +00:00
'\\b(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec|january|february|march|april|may|june|july|august|september|october|november|december),?\\s[0-9]+(?:st|nd|rd|th)?,?\\s((?:[0-9]{2})?[0-9]{2})\\b' , // November 29th, 1997
'\\(((?:19|20)[0-9]{2})\\)' , // (19xx) or (20xx) -- with parens -- do this before 19xx 20xx such that this has priority
'\\b((?:19|20)[0-9]{2})\\b' , // simple 19xx or 20xx with word boundaries
"\\b'([17-9][0-9])\\b" , // '95, '17, ...
2020-06-07 21:26:11 +00:00
// :TODO: DD/MMM/YY, DD/MMMM/YY, DD/MMM/YYYY, etc.
] ,
2022-06-05 20:04:25 +00:00
web : {
2022-12-29 07:56:10 +00:00
// if you change the /_f/ prefix here, ensure something
// non-colliding with other routes is utilized
path : '/_f/' ,
routePath : '^/_f/[a-zA-Z0-9]+$' ,
2022-06-05 20:04:25 +00:00
expireMinutes : 1440 , // 1 day
2020-06-07 21:26:11 +00:00
} ,
//
// File area storage location tag/value pairs.
// Non-absolute paths are relative to |areaStoragePrefix|.
//
2022-06-05 20:04:25 +00:00
storageTags : {
sys _msg _attach : 'sys_msg_attach' ,
sys _temp _download : 'sys_temp_download' ,
2020-06-07 21:26:11 +00:00
} ,
areas : {
2022-06-05 20:04:25 +00:00
system _message _attachment : {
name : 'System Message Attachments' ,
desc : 'File attachments to messages' ,
storageTags : [ 'sys_msg_attach' ] ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
system _temporary _download : {
name : 'System Temporary Downloads' ,
desc : 'Temporary downloadables' ,
storageTags : [ 'sys_temp_download' ] ,
} ,
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
eventScheduler : {
events : {
dailyMaintenance : {
schedule : 'at 11:59pm' ,
action : '@method:core/misc_scheduled_events.js:dailyMaintenanceScheduledEvent' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
trimMessageAreas : {
2020-06-07 21:26:11 +00:00
// may optionally use [or ]@watch:/path/to/file
2022-06-05 20:04:25 +00:00
schedule : 'every 24 hours' ,
2020-06-07 21:26:11 +00:00
// action:
// - @method:path/to/module.js:theMethodName
// (path is relative to ENiGMA base dir)
//
// - @execute:/path/to/something/executable.sh
//
2022-06-05 20:04:25 +00:00
action : '@method:core/message_area.js:trimMessageAreasScheduledEvent' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
nntpMaintenance : {
schedule : 'every 12 hours' , // should generally be < trimMessageAreas interval
action : '@method:core/servers/content/nntp.js:performMaintenanceTask' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
updateFileAreaStats : {
schedule : 'every 1 hours' ,
action : '@method:core/file_base_area.js:updateAreaStatsScheduledEvent' ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
forgotPasswordMaintenance : {
schedule : 'every 24 hours' ,
action : '@method:core/web_password_reset.js:performMaintenanceTask' ,
args : [ '24 hours' ] , // items older than this will be removed
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
twoFactorRegisterTokenMaintenance : {
schedule : 'every 24 hours' ,
action : '@method:core/user_temp_token.js:temporaryTokenMaintenanceTask' ,
args : [
2020-06-07 21:26:11 +00:00
'auth_factor2_otp_register' ,
'24 hours' , // expire time
2022-06-05 20:04:25 +00:00
] ,
2020-06-07 21:26:11 +00:00
} ,
2023-02-09 00:19:12 +00:00
// Removes old Actor records
activityPubActorCacheMaintenance : {
schedule : 'every 24 hours' ,
action : '@method:/core/activitypub/actor.js:actorCacheMaintenanceTask' ,
} ,
2020-06-07 21:26:11 +00:00
//
// Enable the following entry in your config.hjson to periodically create/update
// DESCRIPT.ION files for your file base
//
/ *
updateDescriptIonFiles : {
schedule : 'on the last day of the week' ,
action : '@method:core/file_base_list_export.js:updateFileBaseDescFilesScheduledEvent' ,
}
* /
2022-06-05 20:04:25 +00:00
} ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
logging : {
rotatingFile : {
// set to 'disabled' or false to disable
type : 'rotating-file' ,
fileName : 'enigma-bbs.log' ,
period : '1d' ,
count : 3 ,
level : 'debug' ,
} ,
2020-06-07 21:26:11 +00:00
// :TODO: syslog - https://github.com/mcavage/node-bunyan-syslog
} ,
2022-06-05 20:04:25 +00:00
debug : {
assertsEnabled : false ,
2020-06-07 21:26:11 +00:00
} ,
2022-06-05 20:04:25 +00:00
statLog : {
systemEvents : {
2020-06-07 21:26:11 +00:00
loginHistoryMax : - 1 , // set to -1 for forever
2022-06-05 20:04:25 +00:00
} ,
2020-06-07 21:26:11 +00:00
} ,
} ;
2022-06-05 20:04:25 +00:00
} ;