Move avatar handler to generic system general handler

This commit is contained in:
Bryan Ashby 2023-01-22 10:18:52 -07:00
parent 3409c99f2d
commit d03718d55e
No known key found for this signature in database
GPG Key ID: C2C1B501E4EFD994
6 changed files with 86 additions and 47 deletions

View File

@ -8,7 +8,7 @@ This document attempts to track **major** changes and additions in ENiGMA½. For
* Routes for the file base now default to `/_f/` prefixed instead of just `/f/`. If `/f/` is in your `config.hjson` you are encouraged to update it! * Routes for the file base now default to `/_f/` prefixed instead of just `/f/`. If `/f/` is in your `config.hjson` you are encouraged to update it!
* Finally, the system will search for `index.html` and `index.htm` in that order, if another suitable route cannot be established. * Finally, the system will search for `index.html` and `index.htm` in that order, if another suitable route cannot be established.
* [WebFinger](/docs/_docs/servers/contentservers/webfinger-handler.md) support. * [WebFinger](/docs/_docs/servers/contentservers/webfinger-handler.md) support.
* New users now have randomly generated avatars assigned to them that can be served up via, for example, the ActivityPub [Web Handler](/docs/_docs/servers/contentservers/web-handlers.md). * New users now have randomly generated avatars assigned to them that can be served up via the new System General [Web Handler](/docs/_docs/servers/contentservers/web-handlers.md).
* CombatNet has shut down, so the module (`combatnet.js`) has been removed. * CombatNet has shut down, so the module (`combatnet.js`) has been removed.
## 0.0.13-beta ## 0.0.13-beta

View File

@ -294,6 +294,12 @@ module.exports = () => {
staticRoot: paths.join(__dirname, './../www'), staticRoot: paths.join(__dirname, './../www'),
handlers: {
systemGeneral: {
enabled: true,
},
},
resetPassword: { resetPassword: {
// //
// The following templates have these variables available to them: // The following templates have these variables available to them:

View File

@ -17,9 +17,6 @@ const _ = require('lodash');
const enigma_assert = require('../../../enigma_assert'); const enigma_assert = require('../../../enigma_assert');
const httpSignature = require('http-signature'); const httpSignature = require('http-signature');
const async = require('async'); const async = require('async');
const paths = require('path');
const fs = require('fs');
const mimeTypes = require('mime-types');
exports.moduleInfo = { exports.moduleInfo = {
name: 'ActivityPub', name: 'ActivityPub',
@ -95,13 +92,6 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
}, },
}); });
// default avatar routing
this.webServer.addRoute({
method: 'GET',
path: /^\/_enig\/ap\/users\/.+\/avatar\/.+$/,
handler: this._avatarGetHandler.bind(this),
});
// :TODO: NYI // :TODO: NYI
// this.webServer.addRoute({ // this.webServer.addRoute({
// method: 'GET', // method: 'GET',
@ -267,37 +257,6 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
return this._getCollectionHandler('outbox', req, resp, signature); return this._getCollectionHandler('outbox', req, resp, signature);
} }
_avatarGetHandler(req, resp) {
const url = new URL(req.url, `https://${req.headers.host}`);
const filename = paths.basename(url.pathname);
if (!filename) {
return this.webServer.fileNotFound(resp);
}
const storagePath = _.get(Config(), 'users.avatars.storagePath');
if (!storagePath) {
return this.webServer.fileNotFound(resp);
}
const localPath = paths.join(storagePath, filename);
fs.stat(localPath, (err, stats) => {
if (err || !stats.isFile()) {
return this.webServer.accessDenied(resp);
}
const headers = {
'Content-Type':
mimeTypes.contentType(paths.basename(localPath)) ||
mimeTypes.contentType('.png'),
'Content-Length': stats.size,
};
const readStream = fs.createReadStream(localPath);
resp.writeHead(200, headers);
readStream.pipe(resp);
});
}
_accountNameFromUserPath(url, suffix) { _accountNameFromUserPath(url, suffix) {
const re = new RegExp(`^/_enig/ap/users/(.+)/${suffix}(\\?page=[0-9]+)?$`); const re = new RegExp(`^/_enig/ap/users/(.+)/${suffix}(\\?page=[0-9]+)?$`);
const m = url.pathname.match(re); const m = url.pathname.match(re);

View File

@ -0,0 +1,76 @@
const WebHandlerModule = require('../../../web_handler_module');
const { Errors } = require('../../../enig_error');
const EngiAssert = require('../../../enigma_assert');
const Config = require('../../../config').get;
// deps
const paths = require('path');
const fs = require('fs');
const mimeTypes = require('mime-types');
const get = require('lodash/get');
exports.moduleInfo = {
name: 'SystemGeneral',
desc: 'A general handler for system routes',
author: 'NuSkooler',
packageName: 'codes.l33t.enigma.web.handler.general_system',
};
exports.getModule = class SystemGeneralWebHandler extends WebHandlerModule {
constructor() {
super();
}
init(webServer, cb) {
// we rely on the web server
this.webServer = webServer;
EngiAssert(webServer, 'System General Web Handler init without webServer');
this.log = webServer.logger().child({ webHandler: 'SysGeneral' });
const domain = this.webServer.getDomain();
if (!domain) {
return cb(Errors.UnexpectedState('Web server does not have "domain" set'));
}
// default avatar routing
this.webServer.addRoute({
method: 'GET',
path: /^\/_enig\/users\/.+\/avatar\/.+\.(png|jpg|jpeg|gif|webp)$/,
handler: this._avatarGetHandler.bind(this),
});
return cb(null);
}
_avatarGetHandler(req, resp) {
const url = new URL(req.url, `https://${req.headers.host}`);
const filename = paths.basename(url.pathname);
if (!filename) {
return this.webServer.fileNotFound(resp);
}
const storagePath = get(Config(), 'users.avatars.storagePath');
if (!storagePath) {
return this.webServer.fileNotFound(resp);
}
const localPath = paths.join(storagePath, filename);
fs.stat(localPath, (err, stats) => {
if (err || !stats.isFile()) {
return this.webServer.accessDenied(resp);
}
const headers = {
'Content-Type':
mimeTypes.contentType(paths.basename(localPath)) ||
mimeTypes.contentType('.png'),
'Content-Length': stats.size,
};
const readStream = fs.createReadStream(localPath);
resp.writeHead(200, headers);
readStream.pipe(resp);
});
}
};

View File

@ -11,7 +11,7 @@ const {
} = require('../../../activitypub/util'); } = require('../../../activitypub/util');
const _ = require('lodash'); const _ = require('lodash');
const enigma_assert = require('../../../enigma_assert'); const EngiAssert = require('../../../enigma_assert');
exports.moduleInfo = { exports.moduleInfo = {
name: 'WebFinger', name: 'WebFinger',
@ -29,11 +29,9 @@ exports.getModule = class WebFingerWebHandler extends WebHandlerModule {
} }
init(webServer, cb) { init(webServer, cb) {
const config = Config();
// we rely on the web server // we rely on the web server
this.webServer = webServer; this.webServer = webServer;
enigma_assert(webServer, 'WebFinger Web Handler init without webServer'); EngiAssert(webServer, 'WebFinger Web Handler init without webServer');
this.log = webServer.logger().child({ webHandler: 'WebFinger' }); this.log = webServer.logger().child({ webHandler: 'WebFinger' });

View File

@ -533,7 +533,7 @@ module.exports = class User {
const { makeUserUrl } = require('./activitypub/util'); const { makeUserUrl } = require('./activitypub/util');
const filename = paths.basename(outPath); const filename = paths.basename(outPath);
const url = const url =
makeUserUrl(webServer.instance, self, '/ap/users/') + makeUserUrl(webServer.instance, self, '/users/') +
`/avatar/${filename}`; `/avatar/${filename}`;
apSettings.image = url; apSettings.image = url;