integrating change from Core to Base for all projects

master
rob 2 years ago
parent f60ea876f4
commit f57741c365

@ -23,9 +23,12 @@ class ServiceNodeController extends SiteController {
});
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));
@ -46,6 +49,25 @@ class ServiceNodeController extends SiteController {
}
}
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 {
@ -57,6 +79,18 @@ class ServiceNodeController extends SiteController {
}
}
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');
}

@ -33,7 +33,7 @@ class HiveController extends SiteController {
},
);
router.use('/kaleidoscope',await this.loadChild(path.join(__dirname, 'hive', 'kaleidoscope')));
router.use('/kaleidoscope', await this.loadChild(path.join(__dirname, 'hive', 'kaleidoscope')));
this.services.push({ name: 'kaleidoscope', url: '/hive/kaleidoscope' });
router.get('/', this.getHiveRoot.bind(this));

@ -0,0 +1,33 @@
// core-node-connect.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0
'use strict';
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CONNECT_STATUS_LIST = ['pending', 'accepted', 'rejected'];
const CoreNodeConnectSchema = new Schema({
created: { type: Date, default: Date.now, required: true, index: 1, expires: '30d' },
token: { type: String, required: true },
status: { type: String, enum: CONNECT_STATUS_LIST, default: 'pending', required: true, index: true },
pkg: {
name: { type: String, required: true },
version: { type: String, required: true },
},
site: {
domain: { type: String, required: true, index: 1 },
domainKey: { type: String, required: true, lowercase: true, index: 1 },
name: { type: String, required: true },
description: { type: String, required: true },
company: { type: String, required: true },
coreAuth: {
scopes: { type: [String], required: true },
callbackUrl: { type: String, required: true },
},
},
});
module.exports = mongoose.model('CoreNodeConnect', CoreNodeConnectSchema);

@ -11,6 +11,8 @@ const mongoose = require('mongoose');
const CoreNode = mongoose.model('CoreNode');
const CoreUser = mongoose.model('CoreUser');
const CoreNodeConnect = mongoose.model('CoreNodeConnect');
const CoreNodeRequest = mongoose.model('CoreNodeRequest');
const passport = require('passport');
@ -416,6 +418,79 @@ class CoreNodeService extends SiteService {
);
}
async queueServiceNodeConnect (requestToken, appNode) {
const NOW = new Date();
appNode.site.domain = striptags(appNode.site.domain.trim().toLowerCase());
appNode.site.domainKey = striptags(appNode.site.domainKey.trim().toLowerCase());
appNode.site.name = striptags(appNode.site.name.trim());
appNode.site.description = striptags(appNode.site.description.trim());
appNode.site.company = striptags(appNode.site.company.trim());
appNode.site.coreAuth.scopes = appNode.site.coreAuth.scopes.map((scope) => scope.trim().toLowerCase());
appNode.site.coreAuth.callbackUrl = striptags(appNode.site.coreAuth.callbackUrl.trim());
let request = await CoreNodeConnect.findOne({
$or: [
{ domain: appNode.site.domain },
{ domainKey: appNode.site.domainKey },
],
});
if (request) {
throw new SiteError(406, 'You already have a pending Core Connect request');
}
request = new CoreNodeConnect();
request.created = NOW;
request.token = requestToken;
request.status = 'pending';
request.pkg = {
name: appNode.pkg.name,
version: appNode.pkg.version,
};
request.site = {
domain: appNode.site.domain,
domainKey: appNode.site.domainKey,
name: appNode.site.name,
description: appNode.site.description,
company: appNode.site.company,
coreAuth: {
scopes: appNode.site.coreAuth.scopes,
callbackUrl: appNode.site.coreAuth.callbackUrl,
},
};
await request.save();
return request.toObject();
}
async getServiceNodeQueue (pagination) {
const queue = await CoreNodeConnect
.find({ status: 'pending' })
.sort({ created: -1 })
.skip(pagination.skip)
.limit(pagination.cpp)
.lean();
return queue;
}
async getCoreConnectRequest (requestId) {
const request = await CoreNodeConnect
.findOne({ _id: requestId })
.lean();
return request;
}
async acceptServiceNode (requestToken, appNode) {
const { oauth2: oauth2Service } = this.dtp.services;
const response = { token: requestToken };
this.log.info('accepting app node', { requestToken, appNode });
response.client = await oauth2Service.createClient(appNode.site);
return response;
}
async setCoreOAuth2Credentials (core, credentials) {
const { client } = credentials;
this.log.info('updating Core Connect credentials', { core, client });

@ -44,6 +44,12 @@ ul.uk-nav.uk-nav-default
i.fas.fa-puzzle-piece
span.uk-margin-small-left Service Nodes
li(class={ 'uk-active': (adminView === 'connect-queue') })
a(href="/admin/service-node/connect-queue")
span.nav-item-icon
i.fas.fa-plug
span.uk-margin-small-left Connect Queue
li(class={ 'uk-active': (adminView === 'host') })
a(href="/admin/host")
span.nav-item-icon

@ -0,0 +1,41 @@
extends ../layouts/main
block content
h1 Service Node Connect Queue
if Array.isArray(connectQueue) && (connectQueue.length > 0)
table.uk-table.uk-table-small
thead
tr
th Actions
th Name
th Domain
th Key
th Received
tbody
each connectRequest in connectQueue
tr
td
button(
type="button",
data-request-id= connectRequest._id,
onclick="return dtp.adminApp.postCoreConnectResponse(event, 'approve');",
).uk-button.uk-button-default.uk-button-small.uk-border-rounded
span
i.fas.fa-check
button(
type="button",
data-request-id= connectRequest._id,
onclick="return dtp.adminApp.postCoreConnectResponse(event, 'reject');"
).uk-button.uk-button-danger.uk-button-small.uk-border-rounded
span
i.fas.fa-times
td
- var CORE_SCHEME = process.env.DTP_CORE_AUTH_SCHEME || 'https';
a(href=`${CORE_SCHEME}://${connectRequest.site.domain}/`, target="_blank")= connectRequest.site.name
td= connectRequest.site.domain
td= connectRequest.site.domainKey
td= moment(connectRequest.created).fromNow()
else
div The pending Core Connect queue is empty.

@ -286,6 +286,25 @@ export default class DtpSiteAdminHostStatsApp extends DtpApp {
UIkit.modal.alert(`Failed to delete post: ${error.message}`);
}
}
async postCoreConnectResponse (event, action) {
const target = event.currentTarget || event.target;
const requestId = target.getAttribute('data-request-id');
try {
this.log.info('postCoreConnectResponse', 'posting Core Connect response', { requestId, action });
const requestUrl = `/admin/service-node/connect-queue/${requestId}`;
const response = await fetch(requestUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ action }),
});
await this.processResponse(response);
} catch (error) {
UIkit.modal.alert(`Failed to send Core Connect response: ${error.message}`);
}
}
}
dtp.DtpSiteAdminHostStatsApp = DtpSiteAdminHostStatsApp;
Loading…
Cancel
Save