Additionl of WIP NodeInfo2 support, fix content-type for Actor images
This commit is contained in:
parent
3bdce81bdb
commit
35b7c00d11
|
@ -26,6 +26,7 @@ const mimeTypes = require('mime-types');
|
|||
const { getJson } = require('../http_util.js');
|
||||
const { getISOTimestampString } = require('../database.js');
|
||||
const moment = require('moment');
|
||||
const paths = require('path');
|
||||
|
||||
const ActorCacheTTL = moment.duration(1, 'day');
|
||||
|
||||
|
@ -82,7 +83,8 @@ module.exports = class Actor extends ActivityPubObject {
|
|||
const addImage = (o, t) => {
|
||||
const url = userSettings[t];
|
||||
if (url) {
|
||||
const mt = mimeTypes.contentType(url);
|
||||
const fn = paths.basename(url);
|
||||
const mt = mimeTypes.contentType(fn);
|
||||
if (mt) {
|
||||
o[t] = {
|
||||
mediaType: mt,
|
||||
|
|
|
@ -137,6 +137,9 @@ function getUserProfileTemplatedBody(
|
|||
if (isString(v)) {
|
||||
return v ? encode(v) : '';
|
||||
} else {
|
||||
if (isNaN(v)) {
|
||||
return '';
|
||||
}
|
||||
return v ? v : 0;
|
||||
}
|
||||
};
|
||||
|
@ -171,7 +174,7 @@ function getUserProfileTemplatedBody(
|
|||
ACHIEVEMENT_COUNT: user.getPropertyAsNumber(
|
||||
UserProps.AchievementTotalCount
|
||||
),
|
||||
ACHIEVEMENT_POINTS: user.getProperty(
|
||||
ACHIEVEMENT_POINTS: user.getPropertyAsNumber(
|
||||
UserProps.AchievementTotalPoints
|
||||
),
|
||||
BOARDNAME: Config().general.boardName,
|
||||
|
|
|
@ -306,6 +306,9 @@ module.exports = () => {
|
|||
systemGeneral: {
|
||||
enabled: true,
|
||||
},
|
||||
nodeInfo2: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
|
||||
resetPassword: {
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
const WebHandlerModule = require('../../../web_handler_module');
|
||||
const { Errors } = require('../../../enig_error');
|
||||
const EngiAssert = require('../../../enigma_assert');
|
||||
const Config = require('../../../config').get;
|
||||
const packageJson = require('../../../../package.json');
|
||||
const StatLog = require('../../../stat_log');
|
||||
const SysProps = require('../../../system_property');
|
||||
const SysLogKeys = require('../../../system_log');
|
||||
|
||||
// deps
|
||||
const moment = require('moment');
|
||||
const async = require('async');
|
||||
|
||||
exports.moduleInfo = {
|
||||
name: 'NodeInfo2',
|
||||
desc: 'A NodeInfo2 Handler implementing https://github.com/jaywink/nodeinfo2',
|
||||
author: 'NuSkooler',
|
||||
packageName: 'codes.l33t.enigma.web.handler.nodeinfo2',
|
||||
};
|
||||
|
||||
exports.getModule = class NodeInfo2WebHadnler extends WebHandlerModule {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
init(webServer, cb) {
|
||||
// we rely on the web server
|
||||
this.webServer = webServer;
|
||||
EngiAssert(webServer, 'NodeInfo2 Web Handler init without webServer');
|
||||
|
||||
this.log = webServer.logger().child({ webHandler: 'NodeInfo2' });
|
||||
|
||||
const domain = this.webServer.getDomain();
|
||||
if (!domain) {
|
||||
return cb(Errors.UnexpectedState('Web server does not have "domain" set'));
|
||||
}
|
||||
|
||||
this.webServer.addRoute({
|
||||
method: 'GET',
|
||||
path: /^\/\.well-known\/x-nodeinfo2$/,
|
||||
handler: this._nodeInfo2Handler.bind(this),
|
||||
});
|
||||
|
||||
return cb(null);
|
||||
}
|
||||
|
||||
_nodeInfo2Handler(req, resp) {
|
||||
this.log.info({ url: req.url }, 'Serving NodeInfo2 request');
|
||||
|
||||
this._getNodeInfo(nodeInfo => {
|
||||
const body = JSON.stringify(nodeInfo);
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': body.length,
|
||||
};
|
||||
|
||||
resp.writeHead(200, headers);
|
||||
return resp.end(body);
|
||||
});
|
||||
}
|
||||
|
||||
_getNodeInfo(cb) {
|
||||
// https://github.com/jaywink/nodeinfo2/tree/master/schemas/1.0
|
||||
const config = Config();
|
||||
const nodeInfo = {
|
||||
version: '1.0',
|
||||
server: {
|
||||
baseUrl: this.webServer.baseUrl(),
|
||||
name: config.general.boardName,
|
||||
software: 'ENiGMA½ Bulletin Board Software',
|
||||
version: packageJson.version,
|
||||
},
|
||||
// :TODO: Only list what's enabled
|
||||
protocols: ['telnet', 'ssh', 'gopher', 'nntp', 'ws', 'activitypub'],
|
||||
services: {
|
||||
inbound: [],
|
||||
outbound: [''],
|
||||
},
|
||||
openRegistrations: !config.general.closedSystem,
|
||||
usage: {
|
||||
users: {
|
||||
total: StatLog.getSystemStatNum(SysProps.TotalUserCount) || 1,
|
||||
// others fetched dynamically below
|
||||
},
|
||||
|
||||
// :TODO: pop with local message
|
||||
// select count() from message_meta where meta_name='local_from_user_id';
|
||||
localPosts: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const setActive = (since, name, next) => {
|
||||
const filter = {
|
||||
logName: SysLogKeys.UserLoginHistory,
|
||||
resultType: 'count',
|
||||
dateNewer: moment().subtract(moment.duration(since, 'days')),
|
||||
};
|
||||
StatLog.findSystemLogEntries(filter, (err, count) => {
|
||||
if (!err) {
|
||||
nodeInfo.usage[name] = count;
|
||||
}
|
||||
return next(null);
|
||||
});
|
||||
};
|
||||
|
||||
async.series(
|
||||
[
|
||||
callback => {
|
||||
return setActive(180, 'activeHalfyear', callback);
|
||||
},
|
||||
callback => {
|
||||
return setActive(30, 'activeMonth', callback);
|
||||
},
|
||||
callback => {
|
||||
return setActive(7, 'activeWeek', callback);
|
||||
},
|
||||
],
|
||||
() => {
|
||||
return cb(nodeInfo);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
|
@ -8,6 +8,7 @@ const SysProps = require('./system_property.js');
|
|||
const UserProps = require('./user_property');
|
||||
const Message = require('./message');
|
||||
const { getActiveConnections, AllConnections } = require('./client_connections');
|
||||
const Log = require('./logger').log;
|
||||
|
||||
// deps
|
||||
const _ = require('lodash');
|
||||
|
@ -349,6 +350,7 @@ class StatLog {
|
|||
// - resultType: 'obj' | 'count' (default='obj')
|
||||
// - limit: Limit returned results
|
||||
// - date: exact date to filter against
|
||||
// - dateNewer: Entries newer than this value
|
||||
// - order: 'timestamp' | 'timestamp_asc' | 'timestamp_desc' | 'random'
|
||||
// (default='timestamp')
|
||||
//
|
||||
|
@ -402,7 +404,9 @@ class StatLog {
|
|||
this.setNonPersistentSystemStat(SysProps.SystemLoadStats, loadStats);
|
||||
})
|
||||
.catch(err => {
|
||||
// :TODO: log me
|
||||
if (err) {
|
||||
Log.err({ error: err.message }, 'Error refreshing system stats');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -509,6 +513,11 @@ class StatLog {
|
|||
sql += ` AND DATE(timestamp, "localtime") = DATE("${filter.date.format(
|
||||
'YYYY-MM-DD'
|
||||
)}")`;
|
||||
} else if (filter.dateNewer) {
|
||||
filter.dateNewer = moment(filter.dateNewer);
|
||||
sql += ` AND DATE(timestamp, "localtime") > DATE("${filter.dateNewer.format(
|
||||
'YYYY-MM-DD'
|
||||
)}")`;
|
||||
}
|
||||
|
||||
if ('count' !== filter.resultType) {
|
||||
|
|
Loading…
Reference in New Issue