Move avatar handler to generic system general handler
This commit is contained in:
parent
3409c99f2d
commit
d03718d55e
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -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' });
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue