enigma-bbs/misc/acs_parser.pegjs

350 lines
9.0 KiB
Plaintext
Raw Normal View History

{
2018-11-24 05:02:36 +00:00
const UserProps = require('./user_property.js');
const Log = require('./logger.js').log;
2019-04-10 02:07:19 +00:00
const User = require('./user.js');
const Config = require('./config.js').get;
2018-11-24 05:02:36 +00:00
const _ = require('lodash');
const moment = require('moment');
const client = _.get(options, 'subject.client');
const user = _.get(options, 'subject.user');
function checkAccess(acsCode, value) {
2015-11-13 03:47:34 +00:00
try {
return {
SE : function servicesEnabled() {
if (!Array.isArray(value)) {
value = [ value];
}
const config = Config();
const webEnabled = () => {
return (true === _.get(config, 'contentServers.web.http.enabled') ||
true === _.get(config, 'contentServers.web.https.enabled'));
};
const allEnabled = value.every(svcName => {
switch (svcName) {
case 'http':
return true === _.get(config, 'contentServers.web.http.enabled');
case 'https':
return true === _.get(config, 'contentServers.web.https.enabled');
case 'web':
return webEnabled();
case 'gopher':
return true === _.get(config, 'contentServers.gopher.enabled');
case 'nttp':
return true === _.get(config, 'contentServers.nntp.nntp.enabled');
case 'nntps':
return true === _.get(config, 'contentServers.nntp.nntps.enabled');
case 'activitypub':
return webEnabled() && true === _.get(config, 'contentServers.web.handlers.activityPub.enabled');
case 'nodeinfo2':
return webEnabled() && true === _.get(config, 'contentServers.web.handlers.nodeInfo2.enabled');
case 'webfinger':
return webEnabled() && true === _.get(config, 'contentServers.web.handlers.webFinger.enabled');
}
});
return allEnabled;
},
LC : function isLocalConnection() {
return client && client.isLocal();
2015-11-13 03:47:34 +00:00
},
AG : function ageGreaterOrEqualThan() {
return !isNaN(value) && user && user.getAge() >= value;
2015-11-13 03:47:34 +00:00
},
AS : function accountStatus() {
if(!user) {
return false;
}
if(!Array.isArray(value)) {
value = [ value ];
}
2018-11-24 05:02:36 +00:00
const userAccountStatus = user.getPropertyAsNumber(UserProps.AccountStatus);
return value.map(n => parseInt(n, 10)).includes(userAccountStatus);
},
2015-11-13 03:47:34 +00:00
EC : function isEncoding() {
const encoding = _.get(client, 'term.outputEncoding', '').toLowerCase();
2015-11-13 03:47:34 +00:00
switch(value) {
case 0 : return 'cp437' === encoding;
case 1 : return 'utf-8' === encoding;
2015-11-13 03:47:34 +00:00
default : return false;
}
},
GM : function isOneOfGroups() {
if(!user) {
return false;
}
if(!Array.isArray(value)) {
2015-11-13 03:47:34 +00:00
return false;
}
return value.some(groupName => user.isGroupMember(groupName));
2015-11-13 03:47:34 +00:00
},
NN : function isNode() {
if(!client) {
return false;
}
if(!Array.isArray(value)) {
value = [ value ];
}
return value.map(n => parseInt(n, 10)).includes(client.node);
2015-11-13 03:47:34 +00:00
},
NP : function numberOfPosts() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const postCount = user.getPropertyAsNumber(UserProps.PostCount) || 0;
return !isNaN(value) && postCount >= value;
2015-11-13 03:47:34 +00:00
},
NC : function numberOfCalls() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const loginCount = user.getPropertyAsNumber(UserProps.LoginCount);
return !isNaN(value) && loginCount >= value;
2015-11-13 03:47:34 +00:00
},
AA : function accountAge() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const accountCreated = moment(user.getProperty(UserProps.AccountCreated));
const now = moment();
const daysOld = accountCreated.diff(moment(), 'days');
return !isNaN(value) &&
accountCreated.isValid() &&
now.isAfter(accountCreated) &&
daysOld >= value;
},
BU : function bytesUploaded() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const bytesUp = user.getPropertyAsNumber(UserProps.FileUlTotalBytes) || 0;
return !isNaN(value) && bytesUp >= value;
},
UP : function uploads() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const uls = user.getPropertyAsNumber(UserProps.FileUlTotalCount) || 0;
return !isNaN(value) && uls >= value;
},
BD : function bytesDownloaded() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const bytesDown = user.getPropertyAsNumber(UserProps.FileDlTotalBytes) || 0;
return !isNaN(value) && bytesDown >= value;
},
DL : function downloads() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const dls = user.getPropertyAsNumber(UserProps.FileDlTotalCount) || 0;
return !isNaN(value) && dls >= value;
},
NR : function uploadDownloadRatioGreaterThan() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const ulCount = user.getPropertyAsNumber(UserProps.FileUlTotalCount) || 0;
const dlCount = user.getPropertyAsNumber(UserProps.FileDlTotalCount) || 0;
const ratio = ~~((ulCount / dlCount) * 100);
return !isNaN(value) && ratio >= value;
},
KR : function uploadDownloadByteRatioGreaterThan() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const ulBytes = user.getPropertyAsNumber(UserProps.FileUlTotalBytes) || 0;
const dlBytes = user.getPropertyAsNumber(UserProps.FileDlTotalBytes) || 0;
const ratio = ~~((ulBytes / dlBytes) * 100);
return !isNaN(value) && ratio >= value;
},
PC : function postCallRatio() {
if(!user) {
return false;
}
2018-11-24 05:02:36 +00:00
const postCount = user.getPropertyAsNumber(UserProps.PostCount) || 0;
const loginCount = user.getPropertyAsNumber(UserProps.LoginCount) || 0;
const ratio = ~~((postCount / loginCount) * 100);
return !isNaN(value) && ratio >= value;
},
SC : function isSecureConnection() {
return _.get(client, 'session.isSecure', false);
2015-11-13 03:47:34 +00:00
},
2019-04-10 02:07:19 +00:00
AF : function currentAuthFactor() {
if(!user) {
return false;
}
return !isNaN(value) && user.authFactor >= value;
},
AR : function authFactorRequired() {
if(!user) {
return false;
}
switch(value) {
2019-05-11 06:19:11 +00:00
case 1 : return true;
case 2 : return user.getProperty(UserProps.AuthFactor2OTP) ? true : false;
2019-04-10 02:07:19 +00:00
default : return false;
}
},
ML : function minutesLeft() {
2015-11-13 03:47:34 +00:00
// :TODO: implement me!
return false;
},
TH : function termHeight() {
return !isNaN(value) && _.get(client, 'term.termHeight', 0) >= value;
2015-11-13 03:47:34 +00:00
},
TM : function isOneOfThemes() {
if(!Array.isArray(value)) {
2015-11-13 03:47:34 +00:00
return false;
}
return value.includes(_.get(client, 'currentTheme.name'));
2015-11-13 03:47:34 +00:00
},
TT : function isOneOfTermTypes() {
if(!Array.isArray(value)) {
2015-11-13 03:47:34 +00:00
return false;
}
return value.includes(_.get(client, 'term.termType'));
2015-11-13 03:47:34 +00:00
},
TW : function termWidth() {
return !isNaN(value) && _.get(client, 'term.termWidth', 0) >= value;
2015-11-13 03:47:34 +00:00
},
ID : function isUserId() {
if(!user) {
return false;
}
if(!Array.isArray(value)) {
value = [ value ];
}
return value.map(n => parseInt(n, 10)).includes(user.userId);
2015-11-13 03:47:34 +00:00
},
WD : function isOneOfDayOfWeek() {
if(!Array.isArray(value)) {
value = [ value ];
}
return value.map(n => parseInt(n, 10)).includes(new Date().getDay());
2015-11-13 03:47:34 +00:00
},
MM : function isMinutesPastMidnight() {
const now = moment();
const midnight = now.clone().startOf('day')
const minutesPastMidnight = now.diff(midnight, 'minutes');
return !isNaN(value) && minutesPastMidnight >= value;
},
AC : function achievementCount() {
if(!user) {
return false;
}
const count = user.getPropertyAsNumber(UserProps.AchievementTotalCount) || 0;
return !isNan(value) && points >= value;
},
AP : function achievementPoints() {
if(!user) {
return false;
}
const points = user.getPropertyAsNumber(UserProps.AchievementTotalPoints) || 0;
return !isNan(value) && points >= value;
2020-06-16 01:28:32 +00:00
},
PV : function userPropValue() {
if (!user || !Array.isArray(value) || value.length !== 2) {
return false;
}
const [propName, propValue] = value;
const actualPropValue = user.getProperty(propName);
return actualPropValue === propValue;
}
}[acsCode](value);
2015-11-13 03:47:34 +00:00
} catch (e) {
const logger = _.get(client, 'log', Log);
logger.warn( { acsCode : acsCode, value : value }, 'Invalid ACS string!');
2015-11-13 03:47:34 +00:00
return false;
}
}
}
start
= expr
expr
= orExpr
OR
= '|'
AND
= '&'
NOT
= '!'
groupOpen
= '('
groupClose
= ')'
orExpr
= left:andExpr OR right:expr { return left || right; }
/ andExpr
andExpr
= left:notExpr AND? right:expr { return left && right; }
/ notExpr
notExpr
= NOT value:atom { return !value; }
/ atom
atom
= acsCheck
/ groupOpen value:expr groupClose { return value; }
comma
= ','
ws
= ' '
optWs
= ws*
listOpen
= '['
listClose
= ']'
acsCheck
= acs:acsCode a:arg { return checkAccess(acs, a); }
acsCode
2015-11-13 03:47:34 +00:00
= c:([A-Z][A-Z]) { return c.join(''); }
argVar
= a:[A-Za-z0-9\-_\+]+ { return a.join('') }
commaList
= start:(v:argVar optWs comma optWs { return v; })* last:argVar { return start.concat(last); }
list
= listOpen l:commaList listClose { return l; }
number
= d:([0-9]+) { return parseInt(d.join(''), 10); }
arg
= list
/ num:number?