Compare commits

...

2 Commits

Author SHA1 Message Date
061188a3c0 added hotReload saveFile 2026-04-28 14:30:53 +02:00
9ffea9ee45 app.locals repalced 2026-04-28 12:51:46 +02:00
15 changed files with 202 additions and 241 deletions

View File

@@ -2,6 +2,15 @@ DEMO IS RUNNING:
https://demo.sowadanas.dynv6.net/ https://demo.sowadanas.dynv6.net/
globalize:
--> Global environment objects
├─ path
│ └─ includes filepaths to mandatory files
├─ cache
│ └─ cached objects, which contains content of executed functions
└─ runtimeFile
└─ HotReload-Files. Detects filechanges, can be handeled by file-proxy (.live object)
howto: howto:
--> Watch out for names. Stylesheet and javascript names, will be used global! --> Watch out for names. Stylesheet and javascript names, will be used global!
----------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------

View File

@@ -17,33 +17,33 @@ GO
CLEAN RESET CLEAN RESET
========================================================= */ ========================================================= */
DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions; -- DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions;
DROP VIEW IF EXISTS dbo.vAuthenticationRoles; -- DROP VIEW IF EXISTS dbo.vAuthenticationRoles;
DROP VIEW IF EXISTS dbo.vAuthenticationGroups; -- DROP VIEW IF EXISTS dbo.vAuthenticationGroups;
DROP VIEW IF EXISTS dbo.vGroupHierarchy; -- DROP VIEW IF EXISTS dbo.vGroupHierarchy;
DROP VIEW IF EXISTS dbo.vAuthentications; -- DROP VIEW IF EXISTS dbo.vAuthentications;
DROP VIEW IF EXISTS dbo.vEventLog; -- DROP VIEW IF EXISTS dbo.vEventLog;
DROP VIEW IF EXISTS dbo.vNotifyTray; -- DROP VIEW IF EXISTS dbo.vNotifyTray;
DROP TABLE IF EXISTS dbo.AuthenticationRoles; -- DROP TABLE IF EXISTS dbo.AuthenticationRoles;
DROP TABLE IF EXISTS dbo.AuthenticationGroups; -- DROP TABLE IF EXISTS dbo.AuthenticationGroups;
DROP TABLE IF EXISTS dbo.GroupRoles; -- DROP TABLE IF EXISTS dbo.GroupRoles;
DROP TABLE IF EXISTS dbo.RolePermissions; -- DROP TABLE IF EXISTS dbo.RolePermissions;
DROP TABLE IF EXISTS dbo.GroupClosure; -- DROP TABLE IF EXISTS dbo.GroupClosure;
DROP TABLE IF EXISTS dbo.NotifyTray; -- DROP TABLE IF EXISTS dbo.NotifyTray;
DROP TABLE IF EXISTS dbo.NotifyTrayObjects; -- DROP TABLE IF EXISTS dbo.NotifyTrayObjects;
DROP TABLE IF EXISTS dbo.EventLog; -- DROP TABLE IF EXISTS dbo.EventLog;
DROP TABLE IF EXISTS dbo.EventLevels; -- DROP TABLE IF EXISTS dbo.EventLevels;
DROP TABLE IF EXISTS dbo.Authentication; -- DROP TABLE IF EXISTS dbo.Authentication;
DROP TABLE IF EXISTS dbo.[Group]; -- DROP TABLE IF EXISTS dbo.[Group];
DROP TABLE IF EXISTS dbo.[Role]; -- DROP TABLE IF EXISTS dbo.[Role];
DROP TABLE IF EXISTS dbo.Permission; -- DROP TABLE IF EXISTS dbo.Permission;
DROP TABLE IF EXISTS dbo.Plugins; -- DROP TABLE IF EXISTS dbo.Plugins;
DROP TABLE IF EXISTS dbo.ObjectSource; -- DROP TABLE IF EXISTS dbo.ObjectSource;
DROP TABLE IF EXISTS dbo.AuthenticationUAC; -- DROP TABLE IF EXISTS dbo.AuthenticationUAC;
DROP TABLE IF EXISTS dbo.Vault; -- DROP TABLE IF EXISTS dbo.Vault;
GO GO

View File

@@ -17,33 +17,33 @@ GO
CLEAN RESET CLEAN RESET
========================================================= */ ========================================================= */
DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions; -- DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions;
DROP VIEW IF EXISTS dbo.vAuthenticationRoles; -- DROP VIEW IF EXISTS dbo.vAuthenticationRoles;
DROP VIEW IF EXISTS dbo.vAuthenticationGroups; -- DROP VIEW IF EXISTS dbo.vAuthenticationGroups;
DROP VIEW IF EXISTS dbo.vGroupHierarchy; -- DROP VIEW IF EXISTS dbo.vGroupHierarchy;
DROP VIEW IF EXISTS dbo.vAuthentications; -- DROP VIEW IF EXISTS dbo.vAuthentications;
DROP VIEW IF EXISTS dbo.vEventLog; -- DROP VIEW IF EXISTS dbo.vEventLog;
DROP VIEW IF EXISTS dbo.vNotifyTray; -- DROP VIEW IF EXISTS dbo.vNotifyTray;
DROP TABLE IF EXISTS dbo.AuthenticationRoles; -- DROP TABLE IF EXISTS dbo.AuthenticationRoles;
DROP TABLE IF EXISTS dbo.AuthenticationGroups; -- DROP TABLE IF EXISTS dbo.AuthenticationGroups;
DROP TABLE IF EXISTS dbo.GroupRoles; -- DROP TABLE IF EXISTS dbo.GroupRoles;
DROP TABLE IF EXISTS dbo.RolePermissions; -- DROP TABLE IF EXISTS dbo.RolePermissions;
DROP TABLE IF EXISTS dbo.GroupClosure; -- DROP TABLE IF EXISTS dbo.GroupClosure;
DROP TABLE IF EXISTS dbo.NotifyTray; -- DROP TABLE IF EXISTS dbo.NotifyTray;
DROP TABLE IF EXISTS dbo.NotifyTrayObjects; -- DROP TABLE IF EXISTS dbo.NotifyTrayObjects;
DROP TABLE IF EXISTS dbo.EventLog; -- DROP TABLE IF EXISTS dbo.EventLog;
DROP TABLE IF EXISTS dbo.EventLevels; -- DROP TABLE IF EXISTS dbo.EventLevels;
DROP TABLE IF EXISTS dbo.Authentication; -- DROP TABLE IF EXISTS dbo.Authentication;
DROP TABLE IF EXISTS dbo.[Group]; -- DROP TABLE IF EXISTS dbo.[Group];
DROP TABLE IF EXISTS dbo.[Role]; -- DROP TABLE IF EXISTS dbo.[Role];
DROP TABLE IF EXISTS dbo.Permission; -- DROP TABLE IF EXISTS dbo.Permission;
DROP TABLE IF EXISTS dbo.Plugins; -- DROP TABLE IF EXISTS dbo.Plugins;
DROP TABLE IF EXISTS dbo.ObjectSource; -- DROP TABLE IF EXISTS dbo.ObjectSource;
DROP TABLE IF EXISTS dbo.AuthenticationUAC; -- DROP TABLE IF EXISTS dbo.AuthenticationUAC;
DROP TABLE IF EXISTS dbo.Vault; -- DROP TABLE IF EXISTS dbo.Vault;
GO GO

View File

@@ -16,11 +16,10 @@ module.exports = {
startMenuItems: [], startMenuItems: [],
}, },
runtimeFile: { runtimeFile: {
package: new HotReload(path.join(localPath.source, 'package.json')), package: new HotReload(path.join(localPath.root, 'package.json')),
releaseNotes: new HotReload(path.join(localPath.source, 'models', 'releasenotes.json')), releaseNotes: new HotReload(path.join(localPath.source, 'models', 'releasenotes.json')),
configuration: new HotReload(path.join(localPath.source, 'models', 'configuration.json')), configuration: new HotReload(path.join(localPath.source, 'models', 'configuration.json')),
stylesheet: new HotReload(path.join(localPath.source, 'models', 'stylesheet.json')), stylesheet: new HotReload(path.join(localPath.source, 'models', 'stylesheet.json')),
indexRoutes: new HotReload(path.join(localPath.source, 'routes', 'indexRoutes.js'), { historyLimit: 50, fileType: 'js' }),
startMenuItems: new HotReload(path.join(localPath.source, 'models', 'integratedStartMenuItems.json')) startMenuItems: new HotReload(path.join(localPath.source, 'models', 'integratedStartMenuItems.json'))
}, },
} }

View File

@@ -23,11 +23,12 @@
data: json, data: json,
expandInitially: true, expandInitially: true,
onSave: json => { onSave: json => {
console.log(JSON.stringify(tree.getChanges()));
fetch('/config', { fetch('/config', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json, null, 2) body: JSON.stringify(tree.getChanges(), null, 2)
}).then(() => writeEventLog(0, 'Serverconfig', tree.getChanges()) ); }).then(() => writeEventLog(0, 'Serverconfig', JSON.stringify(tree.getChanges())) );
} }
}); });
}); });

View File

@@ -21,7 +21,7 @@
fetch('/style', { fetch('/style', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json, null, 2) body: JSON.stringify(tree.getChanges(), null, 2)
}).then(() => writeEventLog(0, 'Stylesheet', JSON.stringify(tree.getChanges())) ); }).then(() => writeEventLog(0, 'Stylesheet', JSON.stringify(tree.getChanges())) );
} }
}); });

View File

@@ -15,45 +15,24 @@ const { on } = require('cluster');
// const { start } = require('repl'); // const { start } = require('repl');
// const WebSocket = require('ws'); // const WebSocket = require('ws');
//#endregion //#endregion
require('module-alias/register'); // define paths in package.json require('module-alias/register'); // define paths in package.json
process.env.TZ = 'Europe/Berlin'; const { localPath, cache, runtimeFile } = require('@root/globalize.js');
//#region Paths process.env.TZ = 'Europe/Berlin';
app.locals.path = {
root: dirname(require.main.filename),
plugins: `${dirname(require.main.filename)}/plugins`,
public: `${dirname(require.main.filename)}/public`,
source: `${dirname(require.main.filename)}/src`,
}
//#endregion
//#region Nesessary json files //#region Nesessary json files
const jsonFiles = ['configuration.json', 'stylesheet.json']; const jsonFiles = ['configuration.json', 'stylesheet.json'];
for (var i = 0; i < jsonFiles.length; i++) { for (var i = 0; i < jsonFiles.length; i++) {
if(!fs.existsSync(`${app.locals.path.source}/models/${jsonFiles[i]}`)) { if(!fs.existsSync(`${localPath.source}/models/${jsonFiles[i]}`)) {
fs.copyFileSync(`${app.locals.path.source}/backups/${jsonFiles[i]}.temp`, `${app.locals.path.source}/models/${jsonFiles[i]}`); fs.copyFileSync(`${localPath.source}/backups/${jsonFiles[i]}.temp`, `${localPath.source}/models/${jsonFiles[i]}`);
} }
} }
app.locals.stylesheet = JSON.parse(fs.readFileSync(`${app.locals.path.source}/models/stylesheet.json`, 'utf-8'));
app.locals.configuration = JSON.parse(fs.readFileSync(`${app.locals.path.source}/models/configuration.json`, 'utf-8'));
app.locals.package = JSON.parse(fs.readFileSync(`${app.locals.path.root}/package.json`, 'utf-8'));
app.locals.startMenuItems = [ ];
(async () => { (async () => {
// const server = https.createServer({ const securePath = `${localPath.source}/secure`;
// key: fs.readFileSync(`${app.locals.path.source}/secure/${app.locals.configuration.certificate.key}`), const certConfig = runtimeFile.configuration.live.certificate;
// cert: fs.readFileSync(`${app.locals.path.source}/secure/${app.locals.configuration.certificate.chain}`),
// pfx: fs.readFileSync(`${app.locals.path.source}/secure/${app.locals.configuration.certificate.pfx}`),
// passphrase: "password",
// //cert: fs.readFileSync(`${app.locals.path.source}/secure/${app.locals.configuration.certificate.chain}`),
// }, app);
const securePath = `${app.locals.path.source}/secure`;
const certConfig = app.locals.configuration.certificate;
let httpsOptions = {}; let httpsOptions = {};
@@ -105,9 +84,9 @@ const server = https.createServer(httpsOptions, app);
await service.get('socketManager').addAsync('admin'); await service.get('socketManager').addAsync('admin');
service.set('sqlManager', new SqlManager()); service.set('sqlManager', new SqlManager());
service.get('sqlManager').addInstance('main', app.locals.configuration.integration.sql.connect); service.get('sqlManager').addInstance('main', runtimeFile.configuration.live.integration.sql.connect);
databaseModel.set('eventlog', require(`${app.locals.path.source}/models/eventlogModel`)(service.get('sqlManager').getInstance('main'))); databaseModel.set('eventlog', require(`${localPath.source}/models/eventlogModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('eventlogView', require(`@models/eventlogView`)(service.get('sqlManager').getInstance('main'))); databaseModel.set('eventlogView', require(`@models/eventlogView`)(service.get('sqlManager').getInstance('main')));
service.set('eventManager', new EventManager(app, databaseModel.get('eventlog'), databaseModel.get('eventlogView'), service.get('socketManager'))); service.set('eventManager', new EventManager(app, databaseModel.get('eventlog'), databaseModel.get('eventlogView'), service.get('socketManager')));
@@ -136,22 +115,22 @@ const server = https.createServer(httpsOptions, app);
databaseModel.set('rolePermissionsModel', require(`@models/rolePermissionsModel`)(service.get('sqlManager').getInstance('main'))); databaseModel.set('rolePermissionsModel', require(`@models/rolePermissionsModel`)(service.get('sqlManager').getInstance('main')));
service.set('rbacManager', new RBACManager(databaseModel)); service.set('rbacManager', new RBACManager(databaseModel));
service.set('authenticationManager', new AuthenticationManager(databaseModel.get('authentication'), app.locals.configuration.integration.token.secret)); service.set('authenticationManager', new AuthenticationManager(databaseModel.get('authentication'), runtimeFile.configuration.live.integration.token.secret));
service.set('activeDirectoryManager', new ActiveDirectory(app.locals.configuration.integration.activedirectory)) service.set('activeDirectoryManager', new ActiveDirectory(runtimeFile.configuration.live.integration.activedirectory))
// everytime last created service! // everytime last created service!
service.set('pluginManager', new PluginManager(app, databaseModel.get('plugin'), app.locals.path.plugins, app.locals.configuration.plugin.chown, service)); service.set('pluginManager', new PluginManager(app, databaseModel.get('plugin'), localPath.plugins, runtimeFile.configuration.live.plugin.chown, service));
exports.databaseModel = databaseModel; exports.databaseModel = databaseModel;
exports.service = service; exports.service = service;
exports.path = app.locals.path; exports.path = localPath;
//#endregion //#endregion
//#region Service-Registration/Middleware/Utils/Helpers //#region Service-Registration/Middleware/Utils/Helpers
require(`${app.locals.path.root}/utils.js`); require(`${localPath.root}/utils.js`);
let helpers = service.get('fileSystemManager').loadAllFiles(`${app.locals.path.public}/helpers`, '.js'); let helpers = service.get('fileSystemManager').loadAllFiles(`${localPath.public}/helpers`, '.js');
exports.helpers = helpers; exports.helpers = helpers;
// app.use(service.get('vaultifyManager').createMiddleware()); // app.use(service.get('vaultifyManager').createMiddleware());
@@ -160,17 +139,17 @@ const server = https.createServer(httpsOptions, app);
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
app.use(express.json()); app.use(express.json());
app.use(cookieParser()); app.use(cookieParser());
app.use(favicon(`${app.locals.path.public}/images/radix_os_icon.ico`)); app.use(favicon(`${localPath.public}/images/radix_os_icon.ico`));
app.use(express.static(app.locals.path.root)); app.use(express.static(localPath.root));
app.use(express.static(app.locals.path.public)); app.use(express.static(localPath.public));
app.use(express.static(app.locals.path.source)); app.use(express.static(localPath.source));
app.use(function(request, response, next) { app.use(function(request, response, next) {
if (!request.secure) { if (!request.secure) {
return response.redirect("https://" + request.headers.host + request.url + app.locals.configuration.server.port); return response.redirect("https://" + request.headers.host + request.url + runtimeFile.configuration.live.server.port);
} }
next(); // Http redirection to secure protocol next(); // Http redirection to secure protocol
}) })
@@ -180,8 +159,8 @@ const server = https.createServer(httpsOptions, app);
//#region App config values //#region App config values
app.set('view engine', '.hbs'); app.set('view engine', '.hbs');
app.set('views', [ app.set('views', [
`${app.locals.path.public}/views`, `${localPath.public}/views`,
`${app.locals.path.public}/views/integrated` `${localPath.public}/views/integrated`
]); ]);
app.set('trust proxy', true) app.set('trust proxy', true)
//#endregion //#endregion
@@ -196,13 +175,13 @@ const server = https.createServer(httpsOptions, app);
app.engine('hbs', create({ app.engine('hbs', create({
extname: 'hbs', extname: 'hbs',
helpers: helpers, helpers: helpers,
partialsDir: `${app.locals.path.public}/views/partials`, partialsDir: `${localPath.public}/views/partials`,
layoutsDir: `${app.locals.path.public}/views/layouts`, layoutsDir: `${localPath.public}/views/layouts`,
defaultLayout: `${app.locals.path.public}/views/layouts/default.hbs` defaultLayout: `${localPath.public}/views/layouts/default.hbs`
}).engine) }).engine)
server.listen(app.locals.configuration.server.port, () => { server.listen(runtimeFile.configuration.live.server.port, () => {
(async () => { (async () => {
const databaseTest = await service.get('sqlManager').test("main"); // Check if database connection is established const databaseTest = await service.get('sqlManager').test("main"); // Check if database connection is established
service.get('eventManager').write(null, databaseTest.levelId, null, databaseTest.message); service.get('eventManager').write(null, databaseTest.levelId, null, databaseTest.message);
@@ -223,15 +202,15 @@ const server = https.createServer(httpsOptions, app);
//#region Implement routes //#region Implement routes
require(`${app.locals.path.source}/routes/loginRoutes.js`).route(app, service); // #1 - no token security! important: first!!! require(`${localPath.source}/routes/loginRoutes.js`).route(app, service); // #1 - no token security! important: first!!!
require(`${app.locals.path.source}/routes/indexRoutes.js`).route(app, service); // #2 - token security enabled at this point require(`${localPath.source}/routes/indexRoutes.js`).route(app, service); // #2 - token security enabled at this point
require(`${app.locals.path.source}/routes/adminRoutes.js`).route(app, service); // #3 - token security always enabled require(`${localPath.source}/routes/adminRoutes.js`).route(app, service); // #3 - token security always enabled
//#endregion //#endregion
app.use(service.get('rbacManager').authenticate()); app.use(service.get('rbacManager').authenticate());
//#region Implements sockets //#region Implements sockets
require(`${app.locals.path.source}/sockets/mainSocket.js`)( require(`${localPath.source}/sockets/mainSocket.js`)(
app, app,
service.get('socketManager'), service.get('socketManager'),
'/', '/',
@@ -241,7 +220,7 @@ const server = https.createServer(httpsOptions, app);
service.get('eventManager'), service.get('eventManager'),
service.get('activeDirectoryManager') service.get('activeDirectoryManager')
); );
require(`${app.locals.path.source}/sockets/adminSocket.js`)( require(`${localPath.source}/sockets/adminSocket.js`)(
app, app,
service.get('socketManager'), service.get('socketManager'),
'admin', 'admin',
@@ -253,11 +232,11 @@ const server = https.createServer(httpsOptions, app);
setTimeout(() => { setTimeout(() => {
service.get('eventManager').write(null, 1, null, service.get('eventManager').write(null, 1, null,
`${app.locals.configuration.server.name} is running`, `${runtimeFile.configuration.live.server.name} is running`,
`fqdn: https://${os.hostname()}:${app.locals.configuration.server.port}/`, `fqdn: https://${os.hostname()}:${runtimeFile.configuration.live.server.port}/`,
`process id: ${process.pid}`, `process id: ${process.pid}`,
`url: ${os.hostname()}`, `url: ${os.hostname()}`,
`port: ${app.locals.configuration.server.port}` `port: ${runtimeFile.configuration.live.server.port}`
) )
}, 1000); }, 1000);
}); });

View File

@@ -15,7 +15,8 @@
"scope": "SYSTEM", "scope": "SYSTEM",
"action": "Administration" "action": "Administration"
} }
] ],
"authorized": true
}, },
{ {
"label": "Configs", "label": "Configs",
@@ -30,7 +31,8 @@
"scope": "SYSTEM", "scope": "SYSTEM",
"action": "Administration" "action": "Administration"
} }
] ],
"authorized": true
}, },
{ {
"label": "RBAC", "label": "RBAC",
@@ -46,9 +48,15 @@
"scope": "SYSTEM", "scope": "SYSTEM",
"action": "Administration" "action": "Administration"
} }
] ],
"authorized": true
} }
] ]
},
"onlyAdministration": false,
"defaultSize": {
"width": "800px",
"height": "600px"
} }
}, },
{ {
@@ -71,9 +79,15 @@
"scope": "SYSTEM", "scope": "SYSTEM",
"action": "Administration" "action": "Administration"
} }
] ],
"authorized": true
} }
] ]
},
"onlyAdministration": false,
"defaultSize": {
"width": "1200px",
"height": "1200px"
} }
}, },
{ {
@@ -96,9 +110,15 @@
"scope": "SYSTEM", "scope": "SYSTEM",
"action": "Administration" "action": "Administration"
} }
] ],
"authorized": true
} }
] ]
},
"onlyAdministration": false,
"defaultSize": {
"width": "900px",
"height": "800px"
} }
}, },
{ {
@@ -121,9 +141,15 @@
"scope": "SYSTEM", "scope": "SYSTEM",
"action": "Administration" "action": "Administration"
} }
] ],
"authorized": true
} }
] ]
},
"onlyAdministration": false,
"defaultSize": {
"width": "900px",
"height": "500px"
} }
}, },
{ {
@@ -146,9 +172,15 @@
"scope": "SYSTEM", "scope": "SYSTEM",
"action": "Default_Access" "action": "Default_Access"
} }
] ],
"authorized": true
} }
] ]
},
"onlyAdministration": false,
"defaultSize": {
"width": "460px",
"height": "515px"
} }
}, },
{ {
@@ -167,9 +199,15 @@
"scope": "SYSTEM", "scope": "SYSTEM",
"action": "Default_Access" "action": "Default_Access"
} }
] ],
"authorized": true
} }
] ]
},
"onlyAdministration": false,
"defaultSize": {
"width": 800,
"height": 600
} }
} }
] ]

View File

@@ -61,5 +61,12 @@
"datetime": "2026-04-23", "datetime": "2026-04-23",
"value": "Neues Stylesheet, integratedStartMenuItems JS > JSON, JSONtree Updates, OS-Styles (Mauszeiger, Scrollbalken, Responsive Design, Window-Resize)", "value": "Neues Stylesheet, integratedStartMenuItems JS > JSON, JSONtree Updates, OS-Styles (Mauszeiger, Scrollbalken, Responsive Design, Window-Resize)",
"finish": true "finish": true
},
{
"sAMAccountName": "manuel.sowada",
"plugin": "System",
"datetime": "2026-04-28",
"value": "Sicherheit durch Auslagern von Configs aus app.locals erhöht",
"finish": true
} }
] ]

View File

@@ -1,6 +1,7 @@
const { exec } = require('child_process'); const { exec } = require('child_process');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const { localPath, cache, runtimeFile } = require('@root/globalize.js');
const configurationFile = path.join(require('@root/server.js').path.source, 'models', 'configuration.json'); const configurationFile = path.join(require('@root/server.js').path.source, 'models', 'configuration.json');
@@ -12,31 +13,32 @@ module.exports = {
route(app, service) { route(app, service) {
// JSON configuration abrufen // JSON configuration abrufen
app.post('/api/getConfig', (req, res) => { app.post('/api/getConfig', (req, res) => {
fs.readFile(configurationFile, 'utf8', (err, data) => { res.status(200).send(runtimeFile.configuration.live);
if (err) return res.status(500).send(err);
res.status(200).send(JSON.parse(data));
});
}); });
// JSON configuration speichern // JSON configuration speichern
app.post('/config', (req, res) => { app.post('/config', (req, res) => {
fs.writeFile(configurationFile, JSON.stringify(req.body, null, 2), (err) => { try {
if (err) return res.status(500).send(err); runtimeFile.configuration.save(req.body);
res.status(200).send({ status: 'ok' }); res.status(200).send({ status: 'ok' });
}); } catch(err) {
return res.status(500).send(err)
}
}); });
// JSON stylesheet abrufen // JSON stylesheet abrufen
app.post('/api/getStyles', (req, res) => { app.post('/api/getStyles', (req, res) => {
fs.readFile(stylesheetFile, 'utf8', (err, data) => { try {
if (err) return res.status(500).send(err); runtimeFile.stylesheet.save(req.body);
res.status(200).send(JSON.parse(data)); res.status(200).send({ status: 'ok' });
}); } catch(err) {
return res.status(500).send(err)
}
}); });
// JSON stylesheet speichern // JSON stylesheet speichern
app.post('/style', (req, res) => { app.post('/style', (req, res) => {
fs.writeFile(stylesheetFile, JSON.stringify(req.body, null, 2), (err) => { fs.writeFile(runtimeFile.stylesheet.live, JSON.stringify(req.body, null, 2), (err) => {
if (err) return res.status(500).send(err); if (err) return res.status(500).send(err);
res.status(200).send({ status: 'ok' }); res.status(200).send({ status: 'ok' });
}); });
@@ -45,15 +47,12 @@ module.exports = {
// JSON package.json abrufen // JSON package.json abrufen
app.post('/api/getServerInfo', (req, res) => { app.post('/api/getServerInfo', (req, res) => {
fs.readFile(serverInfoFile, 'utf8', (err, data) => { res.status(200).send({ package: runtimeFile.package.live, pid: process.pid, releaseNotes: runtimeFile.releaseNotes.live });
if (err) { return res.status(500).send(err); }
res.status(200).send({ package: JSON.parse(data), pid: process.pid, releaseNotes: global.json.releaseNotes.live });
});
}); });
// JSON package.json speichern // JSON package.json speichern
app.post('/serverinfo', (req, res) => { app.post('/serverinfo', (req, res) => {
fs.writeFile(serverInfoFile, JSON.stringify(req.body, null, 2), (err) => { fs.writeFile(runtimeFile.package.live, JSON.stringify(req.body, null, 2), (err) => {
if (err) return res.status(500).send(err); if (err) return res.status(500).send(err);
res.status(200).send({ status: 'ok' }); res.status(200).send({ status: 'ok' });
}); });
@@ -120,7 +119,7 @@ module.exports = {
app.post('/api/plugins/integrated', async (req, res) => { app.post('/api/plugins/integrated', async (req, res) => {
try { try {
res.status(200).json(global.json.startMenuItems.live); res.status(200).json(cached.startMenuItems.live);
} catch (error) { } catch (error) {
res.status(500).json({ error: error.message }); res.status(500).json({ error: error.message });
} }

View File

@@ -4,9 +4,7 @@ const path = require('path');
const { renderWindow } = require('@services/renderWindow.js'); const { renderWindow } = require('@services/renderWindow.js');
const { service } = require('@root/server.js'); const { service } = require('@root/server.js');
const { File: HotReload } = require(`@services/hotReload.js`); const { File: HotReload } = require(`@services/hotReload.js`);
const { localPath, cache, runtimeFile } = require('@root/globalize.js');
const { doesNotReject } = require('assert');
// let startMenuItemContext = require('@models/integratedStartmenuItems.js')
module.exports = { module.exports = {
@@ -16,15 +14,14 @@ module.exports = {
res.render('desktop', { layout: 'default', startMenuItems: startMenuItems }); res.render('desktop', { layout: 'default', startMenuItems: startMenuItems });
}); });
app.post('/api/open_app', (req, res) => { app.post('/api/open_app', (req, res) => {
const { name, view, viewLabel, location, size, state, zIndex } = req.body; const { name, view, viewLabel, location, size, state, zIndex } = req.body;
const pluginPath = path.join(global.path.plugins, name, 'plugin.json'); const pluginPath = path.join(localPath.plugins, name, 'plugin.json');
let context = fs.existsSync(pluginPath) let context = fs.existsSync(pluginPath)
? service.get('fileSystemManager').loadJSON(pluginPath) ? service.get('fileSystemManager').loadJSON(pluginPath)
: (JSON.parse(JSON.stringify(global.json.startMenuItems.live))).find(item => item.name == name); : runtimeFile.startMenuItems.live.find(item => item.name == name);
context.defaultSize = context.defaultSize =
context.menu.items.find(item => item.label == viewLabel)?.defaultSize || context.menu.items.find(item => item.label == viewLabel)?.defaultSize ||
@@ -34,11 +31,8 @@ module.exports = {
res.json({ name, view, viewLabel, context, location, size, state, zIndex }); res.json({ name, view, viewLabel, context, location, size, state, zIndex });
}); });
app.get('/api/NotifyTray/getTrays', async (req, res) => { app.get('/api/NotifyTray/getTrays', async (req, res) => {
const objectGuid = req.cookies.ObjectGUID; const objectGuid = req.cookies.ObjectGUID;
// console.log(await service.get('notifyTray').getOpenNotifications(objectGuid))
res.status(200).json(await service.get('notifyTray').getOpenNotifications(objectGuid)); res.status(200).json(await service.get('notifyTray').getOpenNotifications(objectGuid));
}) })
@@ -64,8 +58,6 @@ module.exports = {
}); });
app.post('/window/Server/rbac', async (req, res) => { app.post('/window/Server/rbac', async (req, res) => {
await renderWindow(app, 'rbac.hbs', { }, { }, res) await renderWindow(app, 'rbac.hbs', { }, { }, res)
}); });
@@ -99,7 +91,7 @@ module.exports = {
}); });
app.get('/api/help/getTabs', async (req, res) => { app.get('/api/help/getTabs', async (req, res) => {
const tabNames = (await startMenuItems(app, req.cookies.sAMAccountName)) const tabNames = cache.startMenuItems
.filter(plugin => plugin.active && plugin.menu.items.some(i => i.authorized)) .filter(plugin => plugin.active && plugin.menu.items.some(i => i.authorized))
.map(plugin => ({ name: plugin.menu.label })); .map(plugin => ({ name: plugin.menu.label }));
res.status(200).json(tabNames); res.status(200).json(tabNames);
@@ -107,7 +99,7 @@ module.exports = {
app.post('/api/help/getHelp', async (req, res) => { app.post('/api/help/getHelp', async (req, res) => {
const { name } = req.body; const { name } = req.body;
const props = (await startMenuItems(app, req.cookies.sAMAccountName)) const props = cache.startMenuItems
.filter(plugin => plugin.name === name && plugin.active && plugin.menu.items.some(i => i.authorized)) .filter(plugin => plugin.name === name && plugin.active && plugin.menu.items.some(i => i.authorized))
.map(async plugin => ( .map(async plugin => (
{ {

View File

@@ -1,4 +1,5 @@
const { Op } = require('sequelize'); const { Op } = require('sequelize');
const { localPath, cache, runtimeFile } = require('@root/globalize.js');
/** /**
* Custom event logging class * Custom event logging class
* *
@@ -27,8 +28,8 @@ class EventManager {
async write(objectGuid, levelId, pluginName = null, ...args) { async write(objectGuid, levelId, pluginName = null, ...args) {
const err = new Error(); const err = new Error();
const stackLine = args[0].stack !== undefined ? args[0].stack : err.stack.split('\n')[2]; // calls trace-line const stackLine = args[0].stack !== undefined ? args[0].stack : err.stack.split('\n')[2]; // calls trace-line
//const trace = stackLine.split("\n") !== undefined ? stackLine.split("\n")[1].trim() : stackLine.match(/\/.*\d+/)[0].replace(this.app.locals.path.root, '') || ''; // path:line:column //const trace = stackLine.split("\n") !== undefined ? stackLine.split("\n")[1].trim() : stackLine.match(/\/.*\d+/)[0].replace(this.localPath.root, '') || ''; // path:line:column
const trace = stackLine?.split("\n")?.[1]?.trim() ?? stackLine?.match(/\/.*\d+/)?.[0]?.replace(this.app.locals.path.root, '') ?? ''; const trace = stackLine?.split("\n")?.[1]?.trim() ?? stackLine?.match(/\/.*\d+/)?.[0]?.replace(localPath.root, '') ?? '';
// const message = !Array.isArray(...args) ? [...args][0] : [...args][0][0] // const message = !Array.isArray(...args) ? [...args][0] : [...args][0][0]
const message = args[0].stack !== undefined ? args[0].message : args.join('\r\n\t'); const message = args[0].stack !== undefined ? args[0].message : args.join('\r\n\t');
@@ -48,7 +49,7 @@ class EventManager {
this.socketManager.broadcast('admin', 'eventlog_table', newLogEntry); this.socketManager.broadcast('admin', 'eventlog_table', newLogEntry);
} }
if(this.app.locals.configuration.debug.active && levelId >= this.app.locals.configuration.debug.levelId) { if(runtimeFile.configuration.live.debug.active && levelId >= runtimeFile.configuration.live.debug.levelId) {
this.socketManager.broadcast('admin', 'eventlog', { levelId: levelId, pluginName: pluginName, datetime: `[${dateFormat(new Date(), 'yyyy-mm-dd HH:MM:SS')}]`, trace: `[${trace}]`, message: message }) this.socketManager.broadcast('admin', 'eventlog', { levelId: levelId, pluginName: pluginName, datetime: `[${dateFormat(new Date(), 'yyyy-mm-dd HH:MM:SS')}]`, trace: `[${trace}]`, message: message })
} }
@@ -68,7 +69,7 @@ class EventManager {
async writeLog(objectGuid, levelId, pluginName = null, ...args) { async writeLog(objectGuid, levelId, pluginName = null, ...args) {
const err = new Error(); const err = new Error();
const stackLine = args[0].stack !== undefined ? args[0].stack : err.stack.split('\n')[2]; // calls trace-line const stackLine = args[0].stack !== undefined ? args[0].stack : err.stack.split('\n')[2]; // calls trace-line
const trace = args[0].stack !== undefined ? stackLine.split("\n")[1].trim() : stackLine.match(/\/.*\d+/)[0].replace(this.app.locals.path.root, ''); // path:line:column const trace = args[0].stack !== undefined ? stackLine.split("\n")[1].trim() : stackLine.match(/\/.*\d+/)[0].replace(localPath.root, ''); // path:line:column
// const message = !Array.isArray(...args) ? [...args][0] : [...args][0][0] // const message = !Array.isArray(...args) ? [...args][0] : [...args][0][0]
const message = args[0].stack !== undefined ? args[0].message : args.join('\r\n\t'); const message = args[0].stack !== undefined ? args[0].message : args.join('\r\n\t');
@@ -98,7 +99,7 @@ class EventManager {
async clear() { async clear() {
const err = new Error(); const err = new Error();
const stackLine = err.stack.split('\n')[2]; // calls trace-line const stackLine = err.stack.split('\n')[2]; // calls trace-line
const trace = stackLine.match(/\/.*\d+/)[0].replace(this.app.locals.path.root, ''); // path:line:column const trace = stackLine.match(/\/.*\d+/)[0].replace(localPath.root, ''); // path:line:column
const message = `${this.EventLog.tableName} cleared successfully`; const message = `${this.EventLog.tableName} cleared successfully`;
await this.EventLog.destroy({ await this.EventLog.destroy({

View File

@@ -211,6 +211,25 @@ module.exports = {
return value && typeof value === 'object' && !Array.isArray(value); return value && typeof value === 'object' && !Array.isArray(value);
} }
/**
* changes: string = key1.key2.key3...
*/
save(changes) {
Object.entries(changes).forEach(([path, value]) => {
path.split('.').reduce((acc, key, index, arr) => {
if (index === arr.length - 1) {
acc[key] = value; // 🔥 Proxy triggert
} else {
if (!acc[key] || typeof acc[key] !== 'object') {
acc[key] = {};
}
return acc[key];
}
}, this.live);
});
}
// Merge für Objekte und Arrays // Merge für Objekte und Arrays
mergeObjects(target, source, removeExtra = false) { mergeObjects(target, source, removeExtra = false) {
if (Array.isArray(target) && Array.isArray(source)) { if (Array.isArray(target) && Array.isArray(source)) {

View File

@@ -1,11 +1,12 @@
const { service } = require('@root/server.js'); const { service } = require('@root/server.js');
const { localPath, cache, runtimeFile } = require('@root/globalize.js');
module.exports = { module.exports = {
renderWindow: async function(app, view, data = {}, extraData = {}, res) { renderWindow: async function(app, view, data = {}, extraData = {}, res) {
const name = res.req.body.name; const name = res.req.body.name;
const label = res.req.body.viewLabel; const label = res.req.body.viewLabel;
try { try {
const plugin = app.locals.startMenuItems.find(plugin => plugin.name == name); const plugin = cache.startMenuItems.find(plugin => plugin.name == name);
const windowData = plugin.menu.items.find(item => item.label == label); const windowData = plugin.menu.items.find(item => item.label == label);
// Alle Daten zusammenführen // Alle Daten zusammenführen

View File

@@ -1,31 +1,13 @@
const { exec } = require('child_process'); const { exec } = require('child_process');
const path = require('path'); const path = require('path');
const { permission } = require('process');
const { dirname } = require('path'); const { dirname } = require('path');
const { File: HotReload } = require(`@services/hotReload.js`); const { File: HotReload } = require(`@services/hotReload.js`);
const { service } = require(`@root/server.js`); const { service } = require(`@root/server.js`);
const { json } = require('body-parser'); const { localPath, cache, runtimeFile } = require('@root/globalize.js');
// let integratedStartmenuItems = require('@models/integratedStartmenuItems');
global.path = {
root: dirname(require.main.filename),
source:`${dirname(require.main.filename)}/src`,
public: `${dirname(require.main.filename)}/public`,
plugins: `${dirname(require.main.filename)}/plugins`
};
global.json = {
releaseNotes: new HotReload(path.join(global.path.source, 'models', 'releasenotes.json')),
configuration: new HotReload(path.join(global.path.source, 'models', 'configuration.json')),
stylesheet: new HotReload(path.join(global.path.source, 'models', 'stylesheet.json')),
indexRoutes: new HotReload(path.join(global.path.source, 'routes', 'indexRoutes.js'), { historyLimit: 50, fileType: 'js' }),
startMenuItems: new HotReload(path.join(global.path.source, 'models', 'integratedStartMenuItems.json'))
}
module.exports = startMenuItems = async function (app, objectGuid) { module.exports = startMenuItems = async function (app, objectGuid) {
const debug = global.json.configuration.live.debug.startMenuItems; const debug = runtimeFile.configuration.live.debug.startMenuItems;
let logContent = []; let logContent = [];
function safeClone(obj) { function safeClone(obj) {
@@ -39,9 +21,7 @@ module.exports = startMenuItems = async function (app, objectGuid) {
// ========================= // =========================
// Load menu sources // Load menu sources
// ========================= // =========================
const integratedStartmenuItems = const integratedStartmenuItems = runtimeFile.startMenuItems.live;
service.get('fileSystemManager')
.loadJSON(global.json.startMenuItems.filePath) || [];
const plugins = service const plugins = service
.get('pluginManager') .get('pluginManager')
@@ -149,77 +129,13 @@ module.exports = startMenuItems = async function (app, objectGuid) {
allPlugins = allPlugins allPlugins = allPlugins
.filter(p => !p.onlyAdministration) .filter(p => !p.onlyAdministration)
.filter(p => p.active); .filter(p => p.active);
app.locals.startMenuItems = allPlugins; cache.startMenuItems = allPlugins;
if(debug) { if(debug) {
service.get('eventManager').writeLog(objectGuid, 0, 'StartMenuItems', logContent); service.get('eventManager').writeLog(objectGuid, 0, 'StartMenuItems', logContent);
} }
return allPlugins; return allPlugins;
}; };
// module.exports = startMenuItems = async function (app, sAMAccountName) {
// function safeClone(obj) {
// return JSON.parse(JSON.stringify(obj));
// }
// const integratedStartmenuItems = safeClone(service.get('fileSystemManager').loadJSON(global.json.startMenuItems.filePath));
// const plugins = service
// .get('pluginManager')
// .getStatus()
// .map(({ config, ...plugin }) => ({
// ...safeClone(plugin),
// section: 'Plugin'
// }));
// let getAllPlugins = [...plugins, ...integratedStartmenuItems];
// for (const plugin of getAllPlugins) {
// plugin.menu.items = await Promise.all(
// (plugin.menu.items || []).map(async item => {
// const authorized =
// item.label === 'hr' ||
// item.permissions.includes('Administration')
// ? global.json.configuration.live.administration.some(
// name => name.toLowerCase() === sAMAccountName.toLowerCase()
// )
// : item.permissions.includes('*') ||
// (
// await Promise.all(
// item.permissions.map(async permission =>
// (await service.get('activeDirectoryManager').getGroup(permission)) &&
// (await service.get('activeDirectoryManager').isUserMemberOfRecursive(
// sAMAccountName,
// permission
// ))
// )
// )
// ).some(Boolean);
// return {
// ...safeClone(item),
// authorized
// };
// })
// );
// plugin.onlyAdministration =
// plugin.menu.items.every(item => !item.authorized) &&
// !global.json.configuration.live.administration.includes(sAMAccountName);
// }
// getAllPlugins = getAllPlugins
// .filter(plugin => !plugin.onlyAdministration)
// .filter(plugin => plugin.active);
// app.locals.startMenuItems = getAllPlugins;
// return [...getAllPlugins];
// };
/** /**
* Convert date into custom dateformat * Convert date into custom dateformat