X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=src%2Fservice.js;h=fbbb1c48238142b620ccc7d162ba29244ccaaa5c;hb=3ca7fccb306d0b23626befc3791ffa360b3db1e7;hp=742bcda0f7ae46bfa46237cb28d6272f2327c95b;hpb=1c37a7c533a5530390489ea9a49dcca492db1074;p=websub-hub diff --git a/src/service.js b/src/service.js index 742bcda..fbbb1c4 100644 --- a/src/service.js +++ b/src/service.js @@ -10,6 +10,7 @@ const common = require('./common'); const Enum = require('./enum'); const Manager = require('./manager'); const { Authenticator, SessionManager } = require('@squeep/authentication-module'); +const { initContext, navLinks } = require('./template/template-helper'); const path = require('path'); const _fileScope = common.fileScope(__filename); @@ -31,10 +32,10 @@ class Service extends Dingus { this.on('POST', '/', this.handlerPostRoot.bind(this)); // Information page about service - this.on(['GET', 'HEAD'], '/', this.handlerGetRoot.bind(this)); + this.on(['GET'], '/', this.handlerGetRoot.bind(this)); // Give load-balancers something to check - this.on(['GET', 'HEAD'], '/healthcheck', this.handlerGetHealthcheck.bind(this)); + this.on(['GET'], '/healthcheck', this.handlerGetHealthcheck.bind(this)); // Public information about topics this.on('GET', '/info', this.handlerGetInfo.bind(this)); @@ -42,17 +43,17 @@ class Service extends Dingus { // These routes are intended for accessing static content during development. // In production, a proxy server would likely handle these first. - this.on(['GET', 'HEAD'], '/static', this.handlerRedirect.bind(this), `${options.dingus.proxyPrefix}/static/`); - this.on(['GET', 'HEAD'], '/static/', this.handlerGetStaticFile.bind(this), 'index.html'); - this.on(['GET', 'HEAD'], '/static/:file', this.handlerGetStaticFile.bind(this)); - this.on(['GET', 'HEAD'], '/favicon.ico', this.handlerGetStaticFile.bind(this), 'favicon.ico'); - this.on(['GET', 'HEAD'], '/robots.txt', this.handlerGetStaticFile.bind(this), 'robots.txt'); + this.on(['GET'], '/static', this.handlerRedirect.bind(this), `${options.dingus.proxyPrefix}/static/`); + this.on(['GET'], '/static/', this.handlerGetStaticFile.bind(this), 'index.html'); + this.on(['GET'], '/static/:file', this.handlerGetStaticFile.bind(this)); + this.on(['GET'], '/favicon.ico', this.handlerGetStaticFile.bind(this), 'favicon.ico'); + this.on(['GET'], '/robots.txt', this.handlerGetStaticFile.bind(this), 'robots.txt'); // Private informational endpoints - this.on(['GET', 'HEAD'], '/admin', this.handlerRedirect.bind(this), `${options.dingus.proxyPrefix}/admin/`); - this.on(['GET', 'HEAD'], '/admin/', this.handlerGetAdminOverview.bind(this)); - this.on(['GET', 'HEAD'], '/admin/topic/:topicId', this.handlerGetAdminTopicDetails.bind(this)); - this.on(['GET', 'HEAD'], '/admin/topic/:topicId/history.svg', this.handlerGetHistorySVG.bind(this)); + this.on(['GET'], '/admin', this.handlerRedirect.bind(this), `${options.dingus.proxyPrefix}/admin/`); + this.on(['GET'], '/admin/', this.handlerGetAdminOverview.bind(this)); + this.on(['GET'], '/admin/topic/:topicId', this.handlerGetAdminTopicDetails.bind(this)); + this.on(['GET'], '/admin/topic/:topicId/history.svg', this.handlerGetHistorySVG.bind(this)); // Private data-editing endpoints this.on(['PATCH', 'DELETE'], '/admin/topic/:topicId', this.handlerUpdateTopic.bind(this)); @@ -62,10 +63,12 @@ class Service extends Dingus { this.on('POST', '/admin/process', this.handlerPostAdminProcess.bind(this)); // Admin login - this.on(['GET', 'HEAD'], '/admin/login', this.handlerGetAdminLogin.bind(this)); + this.on(['GET'], '/admin/login', this.handlerGetAdminLogin.bind(this)); this.on(['POST'], '/admin/login', this.handlerPostAdminLogin.bind(this)); this.on(['GET'], '/admin/logout', this.handlerGetAdminLogout.bind(this)); this.on(['GET'], '/admin/_ia', this.handlerGetAdminIA.bind(this)); + this.on(['GET'], '/admin/settings', this.handlerGetAdminSettings.bind(this)); + this.on(['POST'], '/admin/settings', this.handlerPostAdminSettings.bind(this)); } @@ -81,6 +84,8 @@ class Service extends Dingus { */ async preHandler(req, res, ctx) { await super.preHandler(req, res, ctx); + ctx.url = req.url; // Persisted for logout redirect + const logObject = this.asyncLocalStorage.getStore(); // FIXME: for some reason, returning from the super.preHandler sometimes loses async context? // Workaround until cause and solution are found. @@ -102,6 +107,8 @@ class Service extends Dingus { const _scope = _fileScope('handlerPostRoot'); this.logger.debug(_scope, 'called', { req, ctx }); + initContext(ctx); + this.setResponseType(this.responseTypes, req, res, ctx); await this.ingestBody(req, res, ctx); @@ -121,7 +128,7 @@ class Service extends Dingus { ]; this.logger.debug(_scope, 'called', { req, ctx }); - Dingus.setHeadHandler(req, res, ctx); + initContext(ctx); this.setResponseType(responseTypes, req, res, ctx); @@ -139,8 +146,6 @@ class Service extends Dingus { async handlerGetHealthcheck(req, res, ctx) { const _scope = _fileScope('handlerGetHealthcheck'); this.logger.debug(_scope, 'called', { req, ctx }); - - Dingus.setHeadHandler(req, res, ctx); this.setResponseType(this.responseTypes, req, res, ctx); @@ -159,8 +164,6 @@ class Service extends Dingus { const responseTypes = [...this.responseTypes, Enum.ContentType.ImageSVG]; - Dingus.setHeadHandler(req, res, ctx); - this.setResponseType(responseTypes, req, res, ctx); await this.manager.getInfo(res, ctx); @@ -173,8 +176,6 @@ class Service extends Dingus { const responseTypes = [Enum.ContentType.ImageSVG]; - Dingus.setHeadHandler(req, res, ctx); - this.setResponseType(responseTypes, req, res, ctx); await this.manager.getHistorySVG(res, ctx); @@ -190,7 +191,7 @@ class Service extends Dingus { const _scope = _fileScope('handlerGetAdminOverview'); this.logger.debug(_scope, 'called', { req, ctx }); - Dingus.setHeadHandler(req, res, ctx); + initContext(ctx); this.setResponseType(this.responseTypes, req, res, ctx); @@ -209,7 +210,7 @@ class Service extends Dingus { const _scope = _fileScope('handlerGetAdminTopicDetails'); this.logger.debug(_scope, 'called', { req, ctx }); - Dingus.setHeadHandler(req, res, ctx); + initContext(ctx); this.setResponseType(this.responseTypes, req, res, ctx); @@ -269,7 +270,7 @@ class Service extends Dingus { ctx.method = req.method; await this.manager.updateSubscription(res, ctx); } - + /** * @param {http.ClientRequest} req request @@ -298,7 +299,7 @@ class Service extends Dingus { const _scope = _fileScope('handlerGetAdminLogin'); this.logger.debug(_scope, 'called', { req, ctx }); - Dingus.setHeadHandler(req, res, ctx); + initContext(ctx); this.setResponseType(this.responseTypes, req, res, ctx); @@ -316,6 +317,8 @@ class Service extends Dingus { const _scope = _fileScope('handlerPostAdminLogin'); this.logger.debug(_scope, 'called', { req, ctx }); + initContext(ctx); + this.setResponseType(this.responseTypes, req, res, ctx); await this.authenticator.sessionOptionalLocal(req, res, ctx); @@ -326,6 +329,47 @@ class Service extends Dingus { } + /** + * Delegate account settings to authentication module. + * @param {http.ClientRequest} req request + * @param {http.ServerResponse} res response + * @param {object} ctx context + */ + async handlerGetAdminSettings(req, res, ctx) { + const _scope = _fileScope('handlerGetAdminSettings'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + if (await this.authenticator.sessionRequiredLocal(req, res, ctx)) { + await this.sessionManager.getAdminSettings(res, ctx, navLinks); + } + } + + + /** + * Delegate account settings to authentication module. + * @param {http.ClientRequest} req request + * @param {http.ServerResponse} res response + * @param {object} ctx context + */ + async handlerPostAdminSettings(req, res, ctx) { + const _scope = _fileScope('handlerPostAdminSettings'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + if (await this.authenticator.sessionRequiredLocal(req, res, ctx)) { + await this.maybeIngestBody(req, res, ctx); + await this.sessionManager.postAdminSettings(res, ctx, navLinks); + } + } + + /** * Delegate login to authentication module. * @param {http.ClientRequest} req request @@ -336,6 +380,8 @@ class Service extends Dingus { const _scope = _fileScope('handlerGetAdminLogout'); this.logger.debug(_scope, 'called', { req, ctx }); + initContext(ctx); + this.setResponseType(this.responseTypes, req, res, ctx); await this.authenticator.sessionOptionalLocal(req, res, ctx); @@ -354,10 +400,9 @@ class Service extends Dingus { const _scope = _fileScope('handlerGetAdminIA'); this.logger.debug(_scope, 'called', { req, ctx }); - this.setResponseType(this.responseTypes, req, res, ctx); + initContext(ctx); - // Special case here, to see cookie before session established - ctx.cookie = req.getHeader(Enum.Header.Cookie); + this.setResponseType(this.responseTypes, req, res, ctx); await this.sessionManager.getAdminIA(res, ctx); }