// admin/service-node.js // Copyright (C) 2022 DTP Technologies, LLC // License: Apache-2.0 'use strict'; const express = require('express'); const { SiteController, SiteError } = require('../../../lib/site-lib'); class ServiceNodeAdminController extends SiteController { constructor (dtp) { super(dtp, module.exports); } async start ( ) { const router = express.Router(); router.use(async (req, res, next) => { res.locals.currentView = 'admin'; res.locals.adminView = 'service-node'; return next(); }); router.param('clientId', this.populateClientId.bind(this)); router.param('connectRequestId', this.populateConnectRequestId.bind(this)); router.post('/connect-queue/:connectRequestId', this.postConnectRequestResponse.bind(this)); router.post('/:clientId', this.postClientUpdate.bind(this)); router.get('/connect-queue', this.getServiceNodeConnectQueue.bind(this)); router.get('/:clientId', this.getClientView.bind(this)); router.get('/', this.getIndex.bind(this)); router.delete('/:clientId', this.deleteClient.bind(this)); return router; } async populateClientId (req, res, next, clientId) { const { oauth2: oauth2Service } = this.dtp.services; try { res.locals.serviceNode = await oauth2Service.getClientById(clientId); if (!res.locals.serviceNode) { throw new SiteError(404, 'Service node not found'); } return next(); } catch (error) { this.log.error('failed to populate OAuth2 client', { clientId, error }); return next(error); } } async populateConnectRequestId (req, res, next, connectRequestId) { const { coreNode: coreNodeService } = this.dtp.services; try { res.locals.coreConnect = await coreNodeService.getCoreConnectRequest(connectRequestId); if (!res.locals.coreConnect) { throw new SiteError(404, 'Core Connect request not found'); } return next(); } catch (error) { this.log.error('failed to populate connectRequestId', { connectRequestId, error }); return next(error); } } async postConnectRequestResponse (req, res/*, next*/) { this.log.info('processing Core Connect response', { coreConnect: res.locals.coreConnect, action: req.body.action }); res.status(200).json({ success: true, coreConnect: res.locals.coreConnect }); } async postClientUpdate (req, res, next) { const { oauth2: oauth2Service } = this.dtp.services; try { await oauth2Service.updateClient(res.locals.serviceNode, req.body); res.redirect('/admin/service-node'); } catch (error) { this.log.error('failed to update OAuth2 client', { error }); return next(error); } } async getServiceNodeConnectQueue (req, res, next) { const { coreNode: coreNodeService } = this.dtp.services; try { res.locals.pagination = this.getPaginationParameters(req, 20); res.locals.connectQueue = await coreNodeService.getServiceNodeQueue(res.locals.pagination); res.render('admin/service-node/connect-queue'); } catch (error) { this.log.error('failed to render Core Connect queue', { error }); return next(error); } } async getClientView (req, res) { res.render('admin/service-node/editor'); } async getIndex (req, res, next) { const { oauth2: oauth2Service } = this.dtp.services; try { res.locals.pagination = this.getPaginationParameters(req, 20); res.locals.serviceNodes = await oauth2Service.getClients({ }, res.locals.pagination); res.render('admin/service-node/index'); } catch (error) { this.log.error('failed to render Service Node home', { error }); return next(error); } } async deleteClient (req, res) { const { oauth2: oauth2Service } = this.dtp.services; try { await oauth2Service.removeClient(res.locals.serviceNode); const displayList = this.createDisplayList('delete-newsletter'); displayList.navigateTo('/admin/service-node'); res.status(200).json({ success: true, displayList }); } catch (error) { this.log.error('failed to delete client', { clientId: res.locals.serviceNode._id, error }); return res.status(error.statusCode || 500).json({ success: false, message: error.message, }); } } } module.exports = { name: 'adminServiceNode', slug: 'admin-service-node', className: 'ServiceNodeAdminController', create: async (dtp) => { return new ServiceNodeAdminController(dtp); }, };