diff --git a/nodejs/app.js b/nodejs/app.js
index f5b453e..c278ff0 100755
--- a/nodejs/app.js
+++ b/nodejs/app.js
@@ -7,27 +7,36 @@ const express = require('express');
// Set up the express app.
const app = express();
+// Hold list of functions to run when the server is ready
+app.onListen = [];
+
// Allow the express app to be exported into other files.
module.exports = app;
-// Build the conf object from the conf files.
-app.conf = require('./conf/conf');
-
-// List of front end node modules to be served
-const frontEndModules = ['bootstrap', 'mustache', 'jquery', 'jquery-ui','@fortawesome',
- 'moment',
-];
-
-// Server front end modules
-// https://stackoverflow.com/a/55700773/3140931
-frontEndModules.forEach(dep => {
- app.use(`/static-modules/${dep}`, express.static(path.join(__dirname, `node_modules/${dep}`)))
-});
-
-
// Hold onto the auth middleware
const middleware = require('./middleware/auth');
+// Grab the projects PubSub
+app.contoller = require('./controller');
+
+// Push pubsub over the socket and back.
+app.onListen.push(function(){
+ app.io.use(middleware.authIO);
+
+ app.contoller.ps.subscribe(/./g, function(data, topic){
+ app.io.emit('P2PSub', { topic, data });
+ });
+
+ app.io.on('connection', (socket) => {
+ // console.log('socket', socket)
+ var user = socket.user;
+ socket.on('P2PSub', (msg) => {
+ app.contoller.ps.publish(msg.topic, {...msg.data, __from:socket.user});
+ // socket.broadcast.emit('P2PSub', msg);
+ });
+ });
+});
+
// load the JSON parser middleware. Express will parse JSON into native objects
// for any request that has JSON in its content type.
app.use(express.json());
@@ -36,29 +45,11 @@ app.use(express.json());
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
-// Have express server static content( images, CSS, browser JS) from the public
-// local folder.
-app.use('/static', express.static(path.join(__dirname, 'public')))
-
// Routes for front end content.
app.use('/', require('./routes/render'));
-// API routes for authentication.
-app.use('/api/auth', require('./routes/auth'));
-
-
-// API routes for working with users. All endpoints need to be have valid user.
-app.use('/api/user', middleware.auth, require('./routes/user'));
-
-// API routes for working with hosts. All endpoints need to be have valid user.
-app.use('/api/host', middleware.auth, require('./routes/host'));
-
-// API routes for working with hosts. All endpoints need to be have valid user.
-app.use('/api/cert', middleware.auth, require('./routes/cert'));
-
-app.controler = {
- host: require('./controler/host')
-}
+// Routes for API
+app.use('/api', require('./routes/api'));
// Catch 404 and forward to error handler. If none of the above routes are
// used, this is what will be called.
diff --git a/nodejs/bin/www b/nodejs/bin/www
index 93acb9a..69ccee7 100755
--- a/nodejs/bin/www
+++ b/nodejs/bin/www
@@ -7,12 +7,13 @@
var app = require('../app');
var debug = require('debug')('proxy-api:server');
var http = require('http');
+const conf = require('../conf');
/**
* Get port from environment and store in Express.
*/
-var port = normalizePort(process.env.NODE_PORT || '3000');
+var port = normalizePort(process.env.NODE_PORT || conf.port || '3000');
app.set('port', port);
/**
@@ -21,6 +22,9 @@ app.set('port', port);
var server = http.createServer(app);
+var io = require('socket.io')(server);
+app.io = io;
+
/**
* Listen on provided port, on all network interfaces.
*/
@@ -86,5 +90,9 @@ function onListening() {
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
- debug('Listening on ' + bind);
-}
+ console.log('Listening on ' + bind);
+
+ for(let listener of app.onListen){
+ listener()
+ }
+}
\ No newline at end of file
diff --git a/nodejs/controller/auth.js b/nodejs/controller/auth.js
new file mode 100644
index 0000000..f57b140
--- /dev/null
+++ b/nodejs/controller/auth.js
@@ -0,0 +1,56 @@
+'use strict';
+
+const {User} = require('../models/user');
+const {AuthToken} = require('../models/token');
+
+
+class Auth{
+ static errors = {
+ login: function(){
+ let error = new Error('LoginFailed');
+ error.name = 'LoginFailed';
+ error.message = `Invalid Credentials, login failed.`;
+ error.status = 401;
+
+ return error;
+ }
+ }
+
+ static async login(data){
+ try{
+ let user = await User.login(data);
+ let token = await AuthToken.create({username: user.username});
+
+ return {user, token}
+ }catch(error){
+ console.log('login error', error);
+ throw this.errors.login();
+ }
+ }
+
+ static async checkToken(token){
+ try{
+ token = await AuthToken.get(token);
+ if(token && token.check()) return token;
+
+ throw this.errors.login();
+ }catch(error){
+ throw this.errors.login();
+ }
+ }
+
+ static async logout(data){
+ let token = await AuthToken.get(data);
+ await token.destroy();
+ }
+}
+
+
+Auth.logOut = async function(data){
+ try{
+ }catch(error){
+ throw error;
+ }
+}
+
+module.exports = {Auth};
diff --git a/nodejs/controler/host.js b/nodejs/controller/host.js
similarity index 95%
rename from nodejs/controler/host.js
rename to nodejs/controller/host.js
index b0d64f5..706f73b 100644
--- a/nodejs/controler/host.js
+++ b/nodejs/controller/host.js
@@ -2,7 +2,7 @@
const {Host} = require('../models/host');
const {SocketServerJson} = require('../models/socket_server_json');
-const conf = require('../app').conf;
+const conf = require('../conf');
const socket = new SocketServerJson({
diff --git a/nodejs/controller/index.js b/nodejs/controller/index.js
new file mode 100644
index 0000000..32084e9
--- /dev/null
+++ b/nodejs/controller/index.js
@@ -0,0 +1,8 @@
+'use strict';
+
+module.exports = {
+ auth: require('./auth'),
+ ps: require('./pubsub'),
+ host: require('./host'),
+}
+
diff --git a/nodejs/controller/pubsub.js b/nodejs/controller/pubsub.js
new file mode 100644
index 0000000..cf0e5ec
--- /dev/null
+++ b/nodejs/controller/pubsub.js
@@ -0,0 +1,5 @@
+const {PubSub} = require('p2psub');
+
+ps = new PubSub();
+
+module.exports = ps;
diff --git a/nodejs/le_key b/nodejs/le_key
new file mode 100644
index 0000000..2d633bc
--- /dev/null
+++ b/nodejs/le_key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDAykMghkRxBOfK
+niTICXpW3CahhIHf/uCDF1ENMf1uTfaextHtIn/SVvpQ+CcOWmNNb34aW/VYNGa9
+P/AidMTRVPRWUuyEjsRSS8lhH6xRmnEeX6dnIfY7XfJQ3HEoIY7yoRgu2udltCgq
+qSedyQ5l3F6h9r4gxWyNXcZuYeyXR2YAyRwKIsH7I58I0rgq/sw4Lgb+wFiQHXu/
+ocfnTcAqhikiFJcgZUkIO3HmrTeKjT2T1LrZZ84uWEZ5NHnN4TmpaTAsLrhiNU8d
+LXkPR61Y8tr7IGouvsoKj6PQHtm6bqjRp1iKQJ9aTUcFn7EEf/hFijHLPC1nIA+S
+czY/BiR9AgMBAAECggEAK/fVEF1ezZHLVUv04oQ62QVzcAG65v2HcY5HR2WfwWDZ
+foOki9sC4NNCWmYF7kGSBS6IyXUwgrHMvpuO5iTQYFdqNCfMVj0DLCupnVNuZtv8
+sWsqUByQPiDiayujSP5CTjaMP99fx7OrN3OFm/gnJvb3xCN0YB/2blU1NKZzoVpa
+nCJDfa632Aci2pMbyOSx++HeH89dCY+ruWFn36Bz9MJ1jgOZ1dBKxfUogPHI/O2u
+9tFLsLHxSfyPIjLfLrwZ0NGpmiRROUQeVQJBKhEaQPfIa7axq3fz6yPZZ+H6ExKp
+LATKuLDTo8MzcSYTlL8UAvCU+P9chklM8ZYmtQCypwKBgQD7mTaFLkjH9u2A0TPt
+HUn5yjpg0TMCXj06AISoPg+NGBB8UIyuZME2tbkT2J4sPMAergHb9sMmae2paSz3
+8w4AZF5HL/A6eaAdzYtGc2YT+mTAV9zBJ0HzoNY/YPBdBXqRQwsmqph5NZOv3NzQ
+QoNeDij7HJBR/fIqvoZ7JMxs1wKBgQDEKazRfO8274esgtQzLoPQIg+rhv5Sktda
+pA7pbx92WtfPzWi0deT+Ks7rqlpoTdDA7SIAML5UgqyWa9NP/EmyDlZBpoeWOn+9
+CYCkNjkzu2dudgcmYD3X9iIIl1+2ibF8jm5QYxX5nkq8cuySUM/2iw5IUpHUwRLG
+1Juz91IaywKBgQDjRzprAK6ahMNztIgV0Hl8/mPSBejwYLUqakFrwfRGXtC1nAYZ
+m8a2Z15zQSFRkOd0T3g6fiU31ETu3qXSrmudiw1nfTSjfi9X/M+tqp0xuuW8oyI2
+EgKP1GD2C9nWDhb0lf3CxiTKic2J9hg6wXruQhhfDySIDMDwQAA3ybwpLQKBgC8+
+ekjZ9iMc/Wgm+kR5Z3WxPmTpVkc85nEGIjFGeiVfK6r4pccQvd4ZIUzQ8oU8eJJ+
+ijnRg4WHE1oHDhWthXJE0bFuEim0XR+CMmFaTdyPvhF0i7RKaZqhxQCctIiaEQ0W
+oKrrslc0MHvCkgeLPwr54q64dDbxaTxJ6FYnsraRAoGAYkxElEMtmF1jh6Mb/txJ
+S0ElZdSTFgHQE2VquSxr1yAHac6894jEsY22OrPmSSWlELZ74w/NsZqs1zO8lPTH
+jrUj2DAuQUx38SZcrijs9Rz5fhE0dk9ofNXlz8Cvyj6cXnogEy0bx+owqqIqVCpl
+aL9umqfjjonJzMQUefQLIqU=
+-----END PRIVATE KEY-----
diff --git a/nodejs/middleware/auth.js b/nodejs/middleware/auth.js
index 6b98731..09ea20b 100755
--- a/nodejs/middleware/auth.js
+++ b/nodejs/middleware/auth.js
@@ -1,17 +1,27 @@
'use strict';
-const {Auth} = require('../models/auth');
+const { Auth } = require('../controller/auth');
async function auth(req, res, next){
try{
- let user = await Auth.checkToken({token: req.header('auth-token')});
- if(user.username){
- req.user = user;
- return next();
- }
+ req.token = await Auth.checkToken(req.header('auth-token'));
+ req.user = await req.token.getUser();
+ return next();
}catch(error){
next(error);
}
}
-module.exports = {auth};
+async function authIO(socket, next){
+ try{
+ let token = await Auth.checkToken(socket.handshake.auth.token || 0);
+ socket.user = await token.getUser();
+ console.log('socket is good!')
+ next();
+ }catch(error){
+ console.log('reject for', socket.handshake.auth.token)
+ next(error);
+ }
+}
+
+module.exports = {auth, authIO};
diff --git a/nodejs/models/auth.js b/nodejs/models/_auth.js
similarity index 96%
rename from nodejs/models/auth.js
rename to nodejs/models/_auth.js
index 834f98f..c5de599 100644
--- a/nodejs/models/auth.js
+++ b/nodejs/models/_auth.js
@@ -1,7 +1,9 @@
+'use strict';
+
const {User} = require('./user');
const {Token, AuthToken} = require('./token');
-Auth = {}
+let Auth = {}
Auth.errors = {}
Auth.errors.login = function(){
diff --git a/nodejs/models/host.js b/nodejs/models/host.js
index 0a29fff..f2e1417 100755
--- a/nodejs/models/host.js
+++ b/nodejs/models/host.js
@@ -1,11 +1,12 @@
'use strict';
const Table = require('../utils/redis_model');
+const ModelPs = require('../utils/model_pubsub');
const tldExtract = require('tld-extract').parse_host;
const PorkBun = require('../utils/porkbun');
const LetsEncrypt = require('../utils/letsencrypt');
-const conf = require('../conf/conf');
+const conf = require('../conf');
let porkBun = new PorkBun(conf.porkBun.apiKey, conf.porkBun.secretApiKey);
let letsEncrypt = new LetsEncrypt({
@@ -13,7 +14,6 @@ let letsEncrypt = new LetsEncrypt({
});
-
class Host extends Table{
static _key = 'host';
static _keyMap = {
@@ -86,7 +86,6 @@ class Host extends Table{
static async add(data, ...args){
try{
-
let out = await super.add(data, ...args)
await this.buildLookUpObj()
if(out.is_wildcard) await out.createWildcardCert()
@@ -246,8 +245,13 @@ class Host extends Table{
return true;
}
+ static test(pass){
+ return `yes ${pass}`
+ }
+
}
+
class Cached extends Table{
static _key = 'host';
static _keyMap = {
@@ -262,7 +266,7 @@ class Cached extends Table{
await Host.buildLookUpObj();
})()
-module.exports = {Host};
+module.exports = {Host: ModelPs(Host)};
(async function(){
try{
@@ -279,8 +283,8 @@ try{
// })
// console.log('IIFE res:\n', res)
-
- console.log(await Host.listDetail())
+ // console.log(Host.test(55))
+ // console.log(await Host.listDetail())
// console.log('IIFE lookup:', Host.lookUp('bld3324sdf.test.holycore.quest'))
diff --git a/nodejs/models/token.js b/nodejs/models/token.js
index bfa6229..a6cb236 100644
--- a/nodejs/models/token.js
+++ b/nodejs/models/token.js
@@ -1,6 +1,7 @@
'use strict';
const Table = require('../utils/redis_model');
+const {User} = require('./user');
const UUID = function b(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,b)};
@@ -32,6 +33,10 @@ class AuthToken extends Token{
super(...args);
}
+ async getUser(){
+ return await User.get(this.created_by);
+ }
+
static async add(data){
data.created_by = data.username;
return super.add(data)
diff --git a/nodejs/models/user.js b/nodejs/models/user.js
index 67338a0..ecc284f 100644
--- a/nodejs/models/user.js
+++ b/nodejs/models/user.js
@@ -1,6 +1,6 @@
'use strict';
-const conf = require('../app').conf;
+const conf = require('../conf');
const User = require(`./user_${conf.userModel}`)
diff --git a/nodejs/models/user_redis.js b/nodejs/models/user_redis.js
index 9410289..e638aee 100644
--- a/nodejs/models/user_redis.js
+++ b/nodejs/models/user_redis.js
@@ -1,7 +1,7 @@
'use strict';
const Table = require('../utils/redis_model');
-const {Token, InviteToken} = require('./token');
+// const {Token, InviteToken} = require('./token');
const bcrypt = require('bcrypt');
const saltRounds = 10;
@@ -32,7 +32,7 @@ class User extends Table{
}
}
- static async addByInvite(data){
+/* static async addByInvite(data){
try{
let token = await InviteToken.get(data.token);
@@ -55,7 +55,7 @@ class User extends Table{
throw error;
}
- };
+ };*/
async setPassword(data){
try{
@@ -67,7 +67,7 @@ class User extends Table{
}
}
- async invite(){
+/* async invite(){
try{
let token = await InviteToken.add({created_by: this.username});
@@ -76,7 +76,7 @@ class User extends Table{
}catch(error){
throw error;
}
- }
+ }*/
static async login(data){
try{
diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json
index adab679..7c8f5d2 100644
--- a/nodejs/package-lock.json
+++ b/nodejs/package-lock.json
@@ -24,7 +24,9 @@
"linux-sys-user": "^1.1.8",
"moment": "^2.29.4",
"mustache": "^4.2.0",
+ "p2psub": "^0.1.9",
"redis": "^4.6.7",
+ "socket.io": "^4.7.5",
"tld-extract": "^2.1.0"
},
"devDependencies": {
@@ -264,6 +266,11 @@
"@redis/client": "^1.0.0"
}
},
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
+ },
"node_modules/@types/asn1": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@types/asn1/-/asn1-0.2.1.tgz",
@@ -272,6 +279,19 @@
"@types/node": "*"
}
},
+ "node_modules/@types/cookie": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
+ "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
+ },
+ "node_modules/@types/cors": {
+ "version": "2.8.17",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
+ "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/node": {
"version": "14.14.45",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.45.tgz",
@@ -470,6 +490,14 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
+ "node_modules/base64id": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+ "engines": {
+ "node": "^4.5.0 || >= 5.9"
+ }
+ },
"node_modules/bcrypt": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
@@ -709,6 +737,18 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -787,6 +827,63 @@
"node": ">= 0.8"
}
},
+ "node_modules/engine.io": {
+ "version": "6.5.5",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz",
+ "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==",
+ "dependencies": {
+ "@types/cookie": "^0.4.1",
+ "@types/cors": "^2.8.12",
+ "@types/node": ">=10.0.0",
+ "accepts": "~1.3.4",
+ "base64id": "2.0.0",
+ "cookie": "~0.4.1",
+ "cors": "~2.8.5",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.17.1"
+ },
+ "engines": {
+ "node": ">=10.2.0"
+ }
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
+ "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/engine.io/node_modules/cookie": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
+ "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/engine.io/node_modules/debug": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/engine.io/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -1668,6 +1765,11 @@
"wrappy": "1"
}
},
+ "node_modules/p2psub": {
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/p2psub/-/p2psub-0.1.9.tgz",
+ "integrity": "sha512-5za6YUq6GLH+iZCqOF7YaOd13joJyqJyjp/6o3wcy9hj969EJq7sJGsU5b3MB7tjMoaHAaIKZ01j99Y9QficUQ=="
+ },
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -1953,6 +2055,107 @@
"node": ">=10"
}
},
+ "node_modules/socket.io": {
+ "version": "4.7.5",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
+ "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "base64id": "~2.0.0",
+ "cors": "~2.8.5",
+ "debug": "~4.3.2",
+ "engine.io": "~6.5.2",
+ "socket.io-adapter": "~2.5.2",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.2.0"
+ }
+ },
+ "node_modules/socket.io-adapter": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
+ "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
+ "dependencies": {
+ "debug": "~4.3.4",
+ "ws": "~8.17.1"
+ }
+ },
+ "node_modules/socket.io-adapter/node_modules/debug": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io-adapter/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
+ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-parser/node_modules/debug": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io-parser/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/socket.io/node_modules/debug": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -2167,6 +2370,26 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
+ "node_modules/ws": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+ "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
diff --git a/nodejs/package.json b/nodejs/package.json
index 6765550..59121e5 100755
--- a/nodejs/package.json
+++ b/nodejs/package.json
@@ -22,12 +22,13 @@
"extend": "^3.0.2",
"get-root-domain": "^0.0.1",
"jquery": "^3.7.1",
- "jquery-ui": "^1.13.3",
"ldapts": "^2.12.0",
"linux-sys-user": "^1.1.8",
"moment": "^2.29.4",
"mustache": "^4.2.0",
+ "p2psub": "^0.1.9",
"redis": "^4.6.7",
+ "socket.io": "^4.7.5",
"tld-extract": "^2.1.0"
},
"license": "MIT",
diff --git a/nodejs/public/lib/js/app-base.js b/nodejs/public/lib/js/app-base.js
index c4ec287..e061205 100644
--- a/nodejs/public/lib/js/app-base.js
+++ b/nodejs/public/lib/js/app-base.js
@@ -1,66 +1,76 @@
var app = {};
-// app.pubsub = (function(){
-// app.topics = {};
+app.pubsub = (function(){
+ app.topics = {};
-// app.subscribe = function(topic, listener){
-// if(topic instanceof RegExp){
-// listener.match = topic;
-// topic = "__REGEX__";
-// }
+ app.subscribe = function(topic, listener){
+ if(topic instanceof RegExp){
+ listener.match = topic;
+ topic = "__REGEX__";
+ }
-// // create the topic if not yet created
-// if(!app.topics[topic]) app.topics[topic] = [];
+ // create the topic if not yet created
+ if(!app.topics[topic]) app.topics[topic] = [];
-// // add the listener
-// app.topics[topic].push(listener);
-// }
+ // add the listener
+ app.topics[topic].push(listener);
+ }
-// app.matchTopics = function(topic){
-// topic = topic || '';
-// var matches = [... app.topics[topic] ? app.topics[topic] : []];
+ app.matchTopics = function(topic){
+ topic = topic || '';
+ var matches = [... app.topics[topic] ? app.topics[topic] : []];
-// if(!app.topics['__REGEX__']) return matches;
+ if(!app.topics['__REGEX__']) return matches;
-// for(var listener of app.topics['__REGEX__']){
-// if(topic.match(listener.match)) matches.push(listener);
-// }
+ for(var listener of app.topics['__REGEX__']){
+ if(topic.match(listener.match)) matches.push(listener);
+ }
-// return matches;
-// }
+ return matches;
+ }
-// app.publish = function(topic, data){
+ app.publish = function(topic, data){
-// // send the event to all listeners
-// app.matchTopics(topic).forEach(function(listener){
-// setTimeout(function(data, topic){
-// listener(data || {}, topic);
-// }, 0, data, topic);
-// });
-// }
+ // send the event to all listeners
+ app.matchTopics(topic).forEach(function(listener){
+ setTimeout(function(data, topic){
+ listener(data || {}, topic);
+ }, 0, data, topic);
+ });
+ }
-// return this;
-// })(app);
+ return this;
+})(app);
-// app.socket = (function(app){
-// var socket = io();
-// // socket.emit('chat message', $('#m').val());
-// socket.on('P2PSub', function(msg){
-// msg.data.__noSocket = true;
-// app.publish(msg.topic, msg.data);
-// });
+app.socket = (function(app){
+ // $.getScript('/socket.io/socket.io.js')
+ //
+
+ var socket;
+ $(document).ready(function(){
+ socket = io({
+ auth: {
+ token: app.auth.getToken()
+ }
+ });
+ // socket.emit('chat message', $('#m').val());
+ socket.on('P2PSub', function(msg){
+ msg.data.__noSocket = true;
+ app.publish(msg.topic, msg.data);
+ });
-// app.subscribe(/./g, function(data, topic){
-// // console.log('local_pubs', data, topic)
-// if(data.__noSocket) return;
-// // console.log('local_pubs 2', data, topic)
+ app.subscribe(/./g, function(data, topic){
+ // console.log('local_pubs', data, topic)
+ if(data.__noSocket) return;
+ // console.log('local_pubs 2', data, topic)
-// socket.emit('P2PSub', { topic, data })
-// });
+ socket.emit('P2PSub', { topic, data });
+ });
+ })
-// return socket;
+ return socket;
-// })(app);
+})(app);
app.api = (function(app){
var baseURL = '/api/'
diff --git a/nodejs/routes/api.js b/nodejs/routes/api.js
new file mode 100644
index 0000000..5f51432
--- /dev/null
+++ b/nodejs/routes/api.js
@@ -0,0 +1,19 @@
+'use strict';
+
+const router = require('express').Router();
+const conf = require('../conf');
+const middleware = require('../middleware/auth');
+
+// API routes for authentication.
+router.use('/auth', require('./auth'));
+
+// API routes for working with users. All endpoints need to be have valid user.
+router.use('/user', middleware.auth, require('./user'));
+
+// API routes for working with hosts. All endpoints need to be have valid user.
+router.use('/host', middleware.auth, require('./host'));
+
+// API routes for working with hosts. All endpoints need to be have valid user.
+router.use('/cert', middleware.auth, require('./cert'));
+
+module.exports = router;
\ No newline at end of file
diff --git a/nodejs/routes/auth.js b/nodejs/routes/auth.js
index 3c5aa0d..d651cb8 100755
--- a/nodejs/routes/auth.js
+++ b/nodejs/routes/auth.js
@@ -1,9 +1,7 @@
'use strict';
const router = require('express').Router();
-const {User} = require('../models/user');
-const {Auth, AuthToken} = require('../models/auth');
-
+const { Auth } = require('../controller/auth');
router.post('/login', async function(req, res, next){
try{
@@ -11,6 +9,7 @@ router.post('/login', async function(req, res, next){
return res.json({
login: true,
token: auth.token.token,
+ message:`${req.body.username} logged in!`,
});
}catch(error){
next(error);
@@ -29,39 +28,4 @@ router.all('/logout', async function(req, res, next){
}
});
-router.post('/invite/:token', async function(req, res, next) {
- try{
- req.body.token = req.params.token;
- let user = await User.addByInvite(req.body);
- let token = await AuthToken.add(user);
-
- return res.json({
- user: user.username,
- token: token.token
- });
-
- }catch(error){
- next(error);
- }
-
-});
-
module.exports = router;
-
-/*
- verify public ssh key
-*/
-// router.post('/verifykey', async function(req, res){
-// let key = req.body.key;
-
-// try{
-// return res.json({
-// info: await Users.verifyKey(key)
-// });
-// }catch(error){
-// return res.status(400).json({
-// message: 'Key is not a public key file!'
-// });
-// }
-
-// });
\ No newline at end of file
diff --git a/nodejs/routes/host.js b/nodejs/routes/host.js
index f6051b9..9eac42a 100755
--- a/nodejs/routes/host.js
+++ b/nodejs/routes/host.js
@@ -3,7 +3,6 @@
const router = require('express').Router();
const {Host} = require('../models/host');
-
const Model = Host;
router.get('/', async function(req, res, next){
diff --git a/nodejs/routes/render.js b/nodejs/routes/render.js
index 114f191..c5d47d4 100644
--- a/nodejs/routes/render.js
+++ b/nodejs/routes/render.js
@@ -1,13 +1,29 @@
'use strict';
+const path = require('path');
+const express = require('express');
const router = require('express').Router();
-const conf = require('../conf')
-const middleware = require('../middleware/auth');
+const conf = require('../conf');
const values ={
title: conf.environment !== 'production' ? `` : ''
}
+// List of front end node modules to be served
+const frontEndModules = ['bootstrap', 'mustache', 'jquery', '@fortawesome',
+ 'moment',
+];
+
+// Server front end modules
+// https://stackoverflow.com/a/55700773/3140931
+frontEndModules.forEach(dep => {
+ router.use(`/static-modules/${dep}`, express.static(path.join(__dirname, `../node_modules/${dep}`)))
+});
+
+// Have express server static content( images, CSS, browser JS) from the public
+// local folder.
+router.use('/static', express.static(path.join(__dirname, '../public')))
+
router.get('/', async function(req, res, next) {
res.render('hosts', {...values});
});
diff --git a/nodejs/utils/model_pubsub.js b/nodejs/utils/model_pubsub.js
new file mode 100644
index 0000000..a352d4c
--- /dev/null
+++ b/nodejs/utils/model_pubsub.js
@@ -0,0 +1,49 @@
+'use strict';
+const ps = require('../controller/pubsub');
+
+
+function ModelPs(model){
+ const Model = model.constructor.name === 'Function' ? model : model.constructor
+
+ function getIndex(req, res){
+ if(model[Model._key]) return model[Model._key];
+ if(req && req[Model._key]) return req[Model._key];
+ if(res && res[Model._key]) return res[Model._key];
+ }
+
+ function publish(prop, res, req){
+ if(!['add', 'create', 'update', 'remove'].includes(prop)) return;
+
+ ps.publish(`model:${Model.name}:${prop}:${getIndex(res, req)}`, res);
+ }
+
+ return new Proxy(model, {
+ construct(target, args) {
+ let instance = ModelPs(new model(...args));
+
+ return instance;
+ },
+ get(target, propKey, receiver) {
+ if(propKey == 'constructor') return target.constructor;
+ if(propKey === 'isproxy') return 'YESSSSSSSSS'
+ const targetValue = Reflect.get(target, propKey, receiver);
+ if (typeof targetValue === 'function') {
+ return function(...args){
+ let res = targetValue.apply(this, args); // (A)
+ if(targetValue.constructor.name === 'AsyncFunction'){
+ res.then(function(res){
+ publish(propKey, res, ...args);
+ });
+ }else{
+ publish(propKey, res, ...args)
+ }
+ return res;
+ }
+ } else {
+ return targetValue;
+ }
+ }
+ });
+}
+
+module.exports = ModelPs;
diff --git a/nodejs/utils/redis_model.js b/nodejs/utils/redis_model.js
index c809ba9..5e21110 100644
--- a/nodejs/utils/redis_model.js
+++ b/nodejs/utils/redis_model.js
@@ -22,7 +22,6 @@ class Table{
static async get(index){
try{
-
if(typeof index === 'object'){
index = index[this._key];
}
@@ -43,7 +42,7 @@ class Table{
// back to native values.
result = objValidate.parseFromString(this._keyMap, result);
- return new this.prototype.constructor(result);
+ return new this(result);
}catch(error){
throw error;
@@ -84,6 +83,10 @@ class Table{
return out;
}
+ static async create(...args){
+ return this.add(...args);
+ }
+
static async add(data){
// Add a entry to this redis table.
try{
diff --git a/nodejs/views/top.ejs b/nodejs/views/top.ejs
index 9000439..404b824 100755
--- a/nodejs/views/top.ejs
+++ b/nodejs/views/top.ejs
@@ -10,9 +10,8 @@
-
+
-