diff --git a/README.txt b/README.txt index 76f93ee..73543cc 100644 --- a/README.txt +++ b/README.txt @@ -2,6 +2,15 @@ DEMO IS RUNNING: 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: --> Watch out for names. Stylesheet and javascript names, will be used global! ----------------------------------------------------------------------------------------------------------------------- diff --git a/dbcreate.sql b/dbcreate.sql index 7b555aa..4d0aeab 100644 --- a/dbcreate.sql +++ b/dbcreate.sql @@ -17,33 +17,33 @@ GO CLEAN RESET ========================================================= */ -DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions; -DROP VIEW IF EXISTS dbo.vAuthenticationRoles; -DROP VIEW IF EXISTS dbo.vAuthenticationGroups; -DROP VIEW IF EXISTS dbo.vGroupHierarchy; -DROP VIEW IF EXISTS dbo.vAuthentications; -DROP VIEW IF EXISTS dbo.vEventLog; -DROP VIEW IF EXISTS dbo.vNotifyTray; +-- DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions; +-- DROP VIEW IF EXISTS dbo.vAuthenticationRoles; +-- DROP VIEW IF EXISTS dbo.vAuthenticationGroups; +-- DROP VIEW IF EXISTS dbo.vGroupHierarchy; +-- DROP VIEW IF EXISTS dbo.vAuthentications; +-- DROP VIEW IF EXISTS dbo.vEventLog; +-- DROP VIEW IF EXISTS dbo.vNotifyTray; -DROP TABLE IF EXISTS dbo.AuthenticationRoles; -DROP TABLE IF EXISTS dbo.AuthenticationGroups; -DROP TABLE IF EXISTS dbo.GroupRoles; -DROP TABLE IF EXISTS dbo.RolePermissions; -DROP TABLE IF EXISTS dbo.GroupClosure; +-- DROP TABLE IF EXISTS dbo.AuthenticationRoles; +-- DROP TABLE IF EXISTS dbo.AuthenticationGroups; +-- DROP TABLE IF EXISTS dbo.GroupRoles; +-- DROP TABLE IF EXISTS dbo.RolePermissions; +-- DROP TABLE IF EXISTS dbo.GroupClosure; -DROP TABLE IF EXISTS dbo.NotifyTray; -DROP TABLE IF EXISTS dbo.NotifyTrayObjects; -DROP TABLE IF EXISTS dbo.EventLog; -DROP TABLE IF EXISTS dbo.EventLevels; +-- DROP TABLE IF EXISTS dbo.NotifyTray; +-- DROP TABLE IF EXISTS dbo.NotifyTrayObjects; +-- DROP TABLE IF EXISTS dbo.EventLog; +-- DROP TABLE IF EXISTS dbo.EventLevels; -DROP TABLE IF EXISTS dbo.Authentication; -DROP TABLE IF EXISTS dbo.[Group]; -DROP TABLE IF EXISTS dbo.[Role]; -DROP TABLE IF EXISTS dbo.Permission; -DROP TABLE IF EXISTS dbo.Plugins; -DROP TABLE IF EXISTS dbo.ObjectSource; -DROP TABLE IF EXISTS dbo.AuthenticationUAC; -DROP TABLE IF EXISTS dbo.Vault; +-- DROP TABLE IF EXISTS dbo.Authentication; +-- DROP TABLE IF EXISTS dbo.[Group]; +-- DROP TABLE IF EXISTS dbo.[Role]; +-- DROP TABLE IF EXISTS dbo.Permission; +-- DROP TABLE IF EXISTS dbo.Plugins; +-- DROP TABLE IF EXISTS dbo.ObjectSource; +-- DROP TABLE IF EXISTS dbo.AuthenticationUAC; +-- DROP TABLE IF EXISTS dbo.Vault; GO diff --git a/dbcreate_with_untested_views.sql b/dbcreate_with_untested_views.sql index 4a3f340..e90e9d4 100644 --- a/dbcreate_with_untested_views.sql +++ b/dbcreate_with_untested_views.sql @@ -17,33 +17,33 @@ GO CLEAN RESET ========================================================= */ -DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions; -DROP VIEW IF EXISTS dbo.vAuthenticationRoles; -DROP VIEW IF EXISTS dbo.vAuthenticationGroups; -DROP VIEW IF EXISTS dbo.vGroupHierarchy; -DROP VIEW IF EXISTS dbo.vAuthentications; -DROP VIEW IF EXISTS dbo.vEventLog; -DROP VIEW IF EXISTS dbo.vNotifyTray; +-- DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions; +-- DROP VIEW IF EXISTS dbo.vAuthenticationRoles; +-- DROP VIEW IF EXISTS dbo.vAuthenticationGroups; +-- DROP VIEW IF EXISTS dbo.vGroupHierarchy; +-- DROP VIEW IF EXISTS dbo.vAuthentications; +-- DROP VIEW IF EXISTS dbo.vEventLog; +-- DROP VIEW IF EXISTS dbo.vNotifyTray; -DROP TABLE IF EXISTS dbo.AuthenticationRoles; -DROP TABLE IF EXISTS dbo.AuthenticationGroups; -DROP TABLE IF EXISTS dbo.GroupRoles; -DROP TABLE IF EXISTS dbo.RolePermissions; -DROP TABLE IF EXISTS dbo.GroupClosure; +-- DROP TABLE IF EXISTS dbo.AuthenticationRoles; +-- DROP TABLE IF EXISTS dbo.AuthenticationGroups; +-- DROP TABLE IF EXISTS dbo.GroupRoles; +-- DROP TABLE IF EXISTS dbo.RolePermissions; +-- DROP TABLE IF EXISTS dbo.GroupClosure; -DROP TABLE IF EXISTS dbo.NotifyTray; -DROP TABLE IF EXISTS dbo.NotifyTrayObjects; -DROP TABLE IF EXISTS dbo.EventLog; -DROP TABLE IF EXISTS dbo.EventLevels; +-- DROP TABLE IF EXISTS dbo.NotifyTray; +-- DROP TABLE IF EXISTS dbo.NotifyTrayObjects; +-- DROP TABLE IF EXISTS dbo.EventLog; +-- DROP TABLE IF EXISTS dbo.EventLevels; -DROP TABLE IF EXISTS dbo.Authentication; -DROP TABLE IF EXISTS dbo.[Group]; -DROP TABLE IF EXISTS dbo.[Role]; -DROP TABLE IF EXISTS dbo.Permission; -DROP TABLE IF EXISTS dbo.Plugins; -DROP TABLE IF EXISTS dbo.ObjectSource; -DROP TABLE IF EXISTS dbo.AuthenticationUAC; -DROP TABLE IF EXISTS dbo.Vault; +-- DROP TABLE IF EXISTS dbo.Authentication; +-- DROP TABLE IF EXISTS dbo.[Group]; +-- DROP TABLE IF EXISTS dbo.[Role]; +-- DROP TABLE IF EXISTS dbo.Permission; +-- DROP TABLE IF EXISTS dbo.Plugins; +-- DROP TABLE IF EXISTS dbo.ObjectSource; +-- DROP TABLE IF EXISTS dbo.AuthenticationUAC; +-- DROP TABLE IF EXISTS dbo.Vault; GO diff --git a/globalize.js b/globalize.js index 48d85ed..6fb8995 100644 --- a/globalize.js +++ b/globalize.js @@ -16,7 +16,7 @@ module.exports = { startMenuItems: [], }, 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')), configuration: new HotReload(path.join(localPath.source, 'models', 'configuration.json')), stylesheet: new HotReload(path.join(localPath.source, 'models', 'stylesheet.json')), diff --git a/public/views/integrated/serverconfig.hbs b/public/views/integrated/serverconfig.hbs index 63cc25c..1e7c809 100644 --- a/public/views/integrated/serverconfig.hbs +++ b/public/views/integrated/serverconfig.hbs @@ -23,11 +23,12 @@ data: json, expandInitially: true, onSave: json => { + console.log(JSON.stringify(tree.getChanges())); fetch('/config', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(json, null, 2) - }).then(() => writeEventLog(0, 'Serverconfig', tree.getChanges()) ); + body: JSON.stringify(tree.getChanges(), null, 2) + }).then(() => writeEventLog(0, 'Serverconfig', JSON.stringify(tree.getChanges())) ); } }); }); diff --git a/public/views/integrated/styleconfig.hbs b/public/views/integrated/styleconfig.hbs index f46d2e6..9f91a55 100644 --- a/public/views/integrated/styleconfig.hbs +++ b/public/views/integrated/styleconfig.hbs @@ -21,7 +21,7 @@ fetch('/style', { method: 'POST', 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())) ); } }); diff --git a/src/models/integratedStartMenuItems.json b/src/models/integratedStartMenuItems.json index 01eacad..3ab652d 100644 --- a/src/models/integratedStartMenuItems.json +++ b/src/models/integratedStartMenuItems.json @@ -55,8 +55,8 @@ }, "onlyAdministration": false, "defaultSize": { - "width": "900px", - "height": "900px" + "width": "800px", + "height": "600px" } }, { @@ -146,7 +146,11 @@ } ] }, - "onlyAdministration": false + "onlyAdministration": false, + "defaultSize": { + "width": "900px", + "height": "500px" + } }, { "section": "Benutzer", diff --git a/src/models/releasenotes.json b/src/models/releasenotes.json index d26dfb5..9f781f9 100644 --- a/src/models/releasenotes.json +++ b/src/models/releasenotes.json @@ -61,5 +61,12 @@ "datetime": "2026-04-23", "value": "Neues Stylesheet, integratedStartMenuItems JS > JSON, JSONtree Updates, OS-Styles (Mauszeiger, Scrollbalken, Responsive Design, Window-Resize)", "finish": true + }, + { + "sAMAccountName": "manuel.sowada", + "plugin": "System", + "datetime": "2026-04-28", + "value": "Sicherheit durch Auslagern von Configs aus app.locals erhöht", + "finish": true } ] diff --git a/src/routes/adminRoutes.js b/src/routes/adminRoutes.js index 50216ab..b8645bd 100644 --- a/src/routes/adminRoutes.js +++ b/src/routes/adminRoutes.js @@ -1,6 +1,7 @@ const { exec } = require('child_process'); const fs = require('fs'); 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'); @@ -12,31 +13,32 @@ module.exports = { route(app, service) { // JSON configuration abrufen app.post('/api/getConfig', (req, res) => { - fs.readFile(configurationFile, 'utf8', (err, data) => { - if (err) return res.status(500).send(err); - res.status(200).send(JSON.parse(data)); - }); + res.status(200).send(runtimeFile.configuration.live); }); // JSON configuration speichern - app.post('/config', (req, res) => { - fs.writeFile(configurationFile, JSON.stringify(req.body, null, 2), (err) => { - if (err) return res.status(500).send(err); + app.post('/config', (req, res) => { + try { + runtimeFile.configuration.save(req.body); res.status(200).send({ status: 'ok' }); - }); + } catch(err) { + return res.status(500).send(err) + } }); // JSON stylesheet abrufen app.post('/api/getStyles', (req, res) => { - fs.readFile(stylesheetFile, 'utf8', (err, data) => { - if (err) return res.status(500).send(err); - res.status(200).send(JSON.parse(data)); - }); + try { + runtimeFile.stylesheet.save(req.body); + res.status(200).send({ status: 'ok' }); + } catch(err) { + return res.status(500).send(err) + } }); // JSON stylesheet speichern 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); res.status(200).send({ status: 'ok' }); }); @@ -45,15 +47,12 @@ module.exports = { // JSON package.json abrufen app.post('/api/getServerInfo', (req, res) => { - fs.readFile(serverInfoFile, 'utf8', (err, data) => { - if (err) { return res.status(500).send(err); } - res.status(200).send({ package: JSON.parse(data), pid: process.pid, releaseNotes: global.json.releaseNotes.live }); - }); + res.status(200).send({ package: runtimeFile.package.live, pid: process.pid, releaseNotes: runtimeFile.releaseNotes.live }); }); // JSON package.json speichern 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); res.status(200).send({ status: 'ok' }); }); @@ -120,7 +119,7 @@ module.exports = { app.post('/api/plugins/integrated', async (req, res) => { try { - res.status(200).json(global.json.startMenuItems.live); + res.status(200).json(cached.startMenuItems.live); } catch (error) { res.status(500).json({ error: error.message }); } diff --git a/src/routes/indexRoutes.js b/src/routes/indexRoutes.js index 1c39b6b..9352fbf 100644 --- a/src/routes/indexRoutes.js +++ b/src/routes/indexRoutes.js @@ -6,8 +6,6 @@ const { service } = require('@root/server.js'); const { File: HotReload } = require(`@services/hotReload.js`); const { localPath, cache, runtimeFile } = require('@root/globalize.js'); -// let startMenuItemContext = require('@models/integratedStartmenuItems.js') - module.exports = { route: function(app, service) { @@ -35,7 +33,6 @@ module.exports = { app.get('/api/NotifyTray/getTrays', async (req, res) => { const objectGuid = req.cookies.ObjectGUID; - // console.log(await service.get('notifyTray').getOpenNotifications(objectGuid)) res.status(200).json(await service.get('notifyTray').getOpenNotifications(objectGuid)); }) @@ -61,8 +58,6 @@ module.exports = { }); - - app.post('/window/Server/rbac', async (req, res) => { await renderWindow(app, 'rbac.hbs', { }, { }, res) }); diff --git a/src/services/hotReload.js b/src/services/hotReload.js index a5e99e2..090bae8 100644 --- a/src/services/hotReload.js +++ b/src/services/hotReload.js @@ -211,6 +211,25 @@ module.exports = { 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 mergeObjects(target, source, removeExtra = false) { if (Array.isArray(target) && Array.isArray(source)) { diff --git a/utils.js b/utils.js index 0214c86..63b2dc3 100644 --- a/utils.js +++ b/utils.js @@ -4,25 +4,8 @@ const { dirname } = require('path'); const { File: HotReload } = require(`@services/hotReload.js`); const { service } = require(`@root/server.js`); 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) { const debug = runtimeFile.configuration.live.debug.startMenuItems; let logContent = []; @@ -39,9 +22,6 @@ module.exports = startMenuItems = async function (app, objectGuid) { // Load menu sources // ========================= const integratedStartmenuItems = runtimeFile.startMenuItems.live; - // const integratedStartmenuItems = - // service.get('fileSystemManager') - // .loadJSON(global.json.startMenuItems.filePath) || []; const plugins = service .get('pluginManager') @@ -156,70 +136,6 @@ module.exports = startMenuItems = async function (app, objectGuid) { 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