@lenne.tech/nest-server 11.16.1 → 11.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/config.env.js +6 -0
  2. package/dist/config.env.js.map +1 -1
  3. package/dist/core/common/interfaces/server-options.interface.d.ts +2 -0
  4. package/dist/core/modules/permissions/core-permissions.controller.d.ts +13 -0
  5. package/dist/core/modules/permissions/core-permissions.controller.js +71 -0
  6. package/dist/core/modules/permissions/core-permissions.controller.js.map +1 -0
  7. package/dist/core/modules/permissions/core-permissions.module.d.ts +5 -0
  8. package/dist/core/modules/permissions/core-permissions.module.js +36 -0
  9. package/dist/core/modules/permissions/core-permissions.module.js.map +1 -0
  10. package/dist/core/modules/permissions/core-permissions.service.d.ts +34 -0
  11. package/dist/core/modules/permissions/core-permissions.service.js +610 -0
  12. package/dist/core/modules/permissions/core-permissions.service.js.map +1 -0
  13. package/dist/core/modules/permissions/interfaces/permissions.interface.d.ts +93 -0
  14. package/dist/core/modules/permissions/interfaces/permissions.interface.js +3 -0
  15. package/dist/core/modules/permissions/interfaces/permissions.interface.js.map +1 -0
  16. package/dist/core/modules/permissions/permissions-scanner.d.ts +25 -0
  17. package/dist/core/modules/permissions/permissions-scanner.js +817 -0
  18. package/dist/core/modules/permissions/permissions-scanner.js.map +1 -0
  19. package/dist/core.module.js +5 -0
  20. package/dist/core.module.js.map +1 -1
  21. package/dist/index.d.ts +5 -0
  22. package/dist/index.js +5 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/tsconfig.build.tsbuildinfo +1 -1
  25. package/package.json +1 -1
  26. package/src/config.env.ts +6 -0
  27. package/src/core/common/interfaces/server-options.interface.ts +26 -0
  28. package/src/core/modules/permissions/INTEGRATION-CHECKLIST.md +56 -0
  29. package/src/core/modules/permissions/README.md +102 -0
  30. package/src/core/modules/permissions/core-permissions.controller.ts +34 -0
  31. package/src/core/modules/permissions/core-permissions.module.ts +36 -0
  32. package/src/core/modules/permissions/core-permissions.service.ts +627 -0
  33. package/src/core/modules/permissions/interfaces/permissions.interface.ts +125 -0
  34. package/src/core/modules/permissions/permissions-scanner.ts +1011 -0
  35. package/src/core.module.ts +7 -0
  36. package/src/index.ts +10 -0
@@ -0,0 +1,610 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var CorePermissionsService_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.CorePermissionsService = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const fs = require("fs");
19
+ const fs_1 = require("fs");
20
+ const path_1 = require("path");
21
+ const permissions_scanner_1 = require("./permissions-scanner");
22
+ let CorePermissionsService = CorePermissionsService_1 = class CorePermissionsService {
23
+ htmlCache = null;
24
+ lastScanTime = 0;
25
+ logger = new common_1.Logger(CorePermissionsService_1.name);
26
+ markdownCache = null;
27
+ basePath;
28
+ report = null;
29
+ scanPromise = null;
30
+ watcher = null;
31
+ SCAN_COOLDOWN_MS = 10_000;
32
+ constructor(basePath) {
33
+ this.basePath = basePath || 'permissions';
34
+ this.setupWatcher();
35
+ }
36
+ generateHtml(authToken) {
37
+ if (!this.htmlCache) {
38
+ if (!this.report)
39
+ return `<p>No report available. Access /${this.basePath} to trigger scan.</p>`;
40
+ this.htmlCache = this.buildHtml(this.report);
41
+ }
42
+ if (authToken) {
43
+ const escaped = authToken.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/</g, '\\u003c');
44
+ return this.htmlCache.replace('</body>', `<script>var AUTH_TOKEN='${escaped}';</script></body>`);
45
+ }
46
+ return this.htmlCache;
47
+ }
48
+ generateMarkdown() {
49
+ if (this.markdownCache)
50
+ return this.markdownCache;
51
+ if (!this.report)
52
+ return `# Permissions Report\n\nNo report available. Access /${this.basePath} to trigger scan.`;
53
+ this.markdownCache = (0, permissions_scanner_1.generateMarkdownReport)(this.report);
54
+ return this.markdownCache;
55
+ }
56
+ getReport() {
57
+ return this.report;
58
+ }
59
+ async getOrScan() {
60
+ if (this.report)
61
+ return this.report;
62
+ if (this.scanPromise)
63
+ return this.scanPromise;
64
+ this.scanPromise = this.scan();
65
+ return this.scanPromise;
66
+ }
67
+ onModuleDestroy() {
68
+ this.watcher?.close();
69
+ }
70
+ async scan() {
71
+ const now = Date.now();
72
+ if (now - this.lastScanTime < this.SCAN_COOLDOWN_MS) {
73
+ if (this.report)
74
+ return this.report;
75
+ }
76
+ try {
77
+ this.lastScanTime = now;
78
+ const projectRoot = (0, permissions_scanner_1.findProjectRoot)();
79
+ if (!projectRoot) {
80
+ throw new Error('Could not find project root (src/server/modules/ not found)');
81
+ }
82
+ this.report = (0, permissions_scanner_1.scanPermissions)(projectRoot, {
83
+ log: (msg) => this.logger.log(msg),
84
+ warn: (msg) => this.logger.warn(msg),
85
+ });
86
+ this.htmlCache = null;
87
+ this.markdownCache = null;
88
+ return this.report;
89
+ }
90
+ catch (error) {
91
+ this.logger.error('Permissions scan failed', error);
92
+ throw error;
93
+ }
94
+ finally {
95
+ this.scanPromise = null;
96
+ }
97
+ }
98
+ collectModuleRoles(mod) {
99
+ const roles = new Set();
100
+ for (const model of mod.models) {
101
+ for (const r of model.classRestriction)
102
+ roles.add(r);
103
+ for (const f of model.fields) {
104
+ const matches = f.roles.match(/`([^`]+)`/g);
105
+ if (matches)
106
+ matches.forEach((m) => roles.add(m.replace(/`/g, '')));
107
+ }
108
+ }
109
+ for (const ctrl of mod.controllers) {
110
+ for (const r of ctrl.classRoles)
111
+ roles.add(r);
112
+ for (const m of ctrl.methods) {
113
+ for (const r of m.roles)
114
+ roles.add(r);
115
+ }
116
+ }
117
+ for (const res of mod.resolvers) {
118
+ for (const r of res.classRoles)
119
+ roles.add(r);
120
+ for (const m of res.methods) {
121
+ for (const r of m.roles)
122
+ roles.add(r);
123
+ }
124
+ }
125
+ return [...roles].sort();
126
+ }
127
+ badge(role) {
128
+ return `<span class="badge ${this.getBadgeClass(role)}">${this.escapeHtml(role)}</span>`;
129
+ }
130
+ badgeList(roles) {
131
+ return roles.length > 0 ? roles.map((r) => this.badge(r)).join(' ') : '<em>(none)</em>';
132
+ }
133
+ escapeHtml(str) {
134
+ return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
135
+ }
136
+ getBadgeClass(role) {
137
+ if (!role)
138
+ return 'badge-custom';
139
+ const r = role.toUpperCase();
140
+ if (r === 'S_EVERYONE')
141
+ return 'badge-everyone';
142
+ if (r === 'S_NO_ONE')
143
+ return 'badge-noone';
144
+ if (r === 'ADMIN')
145
+ return 'badge-admin';
146
+ if (r === 'S_USER')
147
+ return 'badge-user';
148
+ if (r === 'S_SELF')
149
+ return 'badge-self';
150
+ if (r === 'S_CREATOR')
151
+ return 'badge-creator';
152
+ return 'badge-custom';
153
+ }
154
+ buildClientJs(data) {
155
+ const basePath = JSON.stringify('/' + this.basePath);
156
+ return `<script>
157
+ var DATA = ${data};
158
+ var BASE_PATH = ${basePath};
159
+
160
+ (function() {
161
+ var sel = document.getElementById('roleFilter');
162
+ var roles = {};
163
+
164
+ // Collect roles from roleEnums
165
+ DATA.roleEnums.forEach(function(e) { e.values.forEach(function(v) { roles[v.key] = true; }); });
166
+
167
+ // Collect roles from actual scan data
168
+ DATA.modules.forEach(function(mod) {
169
+ mod.models.forEach(function(model) {
170
+ model.classRestriction.forEach(function(r) { roles[r] = true; });
171
+ model.fields.forEach(function(f) {
172
+ var m = f.roles.match(/\x60([^\x60]+)\x60/g);
173
+ if (m) m.forEach(function(r) { roles[r.replace(/\x60/g, '')] = true; });
174
+ });
175
+ });
176
+ mod.controllers.forEach(function(ep) {
177
+ ep.classRoles.forEach(function(r) { roles[r] = true; });
178
+ ep.methods.forEach(function(m) { m.roles.forEach(function(r) { roles[r] = true; }); });
179
+ });
180
+ mod.resolvers.forEach(function(ep) {
181
+ ep.classRoles.forEach(function(r) { roles[r] = true; });
182
+ ep.methods.forEach(function(m) { m.roles.forEach(function(r) { roles[r] = true; }); });
183
+ });
184
+ });
185
+
186
+ Object.keys(roles).sort().forEach(function(r) {
187
+ var o = document.createElement('option');
188
+ o.value = r; o.textContent = r;
189
+ sel.appendChild(o);
190
+ });
191
+ })();
192
+
193
+ function toggle(el) {
194
+ el.classList.toggle('open');
195
+ var content = el.nextElementSibling;
196
+ if (content) content.classList.toggle('open');
197
+ }
198
+
199
+ function filterAll() {
200
+ var q = document.getElementById('search').value.toLowerCase();
201
+ var role = document.getElementById('roleFilter').value;
202
+ var warnOnly = document.getElementById('warnOnly').checked;
203
+
204
+ // Filter module sections
205
+ document.querySelectorAll('.module-section').forEach(function(section) {
206
+ var text = section.textContent.toLowerCase();
207
+ var hasWarnings = section.dataset.hasWarnings === 'true';
208
+ var sectionRoles = (section.dataset.roles || '').split(',');
209
+ var show = true;
210
+ if (q && !text.includes(q)) show = false;
211
+ if (warnOnly && !hasWarnings) show = false;
212
+ if (role && sectionRoles.indexOf(role) === -1) show = false;
213
+ section.style.display = show ? '' : 'none';
214
+ });
215
+
216
+ // Filter warnings table rows
217
+ var warningsSection = document.getElementById('warnings');
218
+ if (warningsSection) {
219
+ var rows = warningsSection.querySelectorAll('tbody tr');
220
+ rows.forEach(function(row) {
221
+ var text = row.textContent.toLowerCase();
222
+ var show = true;
223
+ if (q && !text.includes(q)) show = false;
224
+ row.style.display = show ? '' : 'none';
225
+ });
226
+ }
227
+
228
+ // Filter subobjects section
229
+ var subObjSection = document.getElementById('subobjects');
230
+ if (subObjSection) {
231
+ subObjSection.querySelectorAll('div > h3').forEach(function(h3) {
232
+ var container = h3.parentElement;
233
+ if (!container) return;
234
+ var text = container.textContent.toLowerCase();
235
+ var show = true;
236
+ if (q && !text.includes(q)) show = false;
237
+ container.style.display = show ? '' : 'none';
238
+ });
239
+ }
240
+ }
241
+
242
+ document.querySelectorAll('th').forEach(function(th) {
243
+ th.addEventListener('click', function() {
244
+ var table = this.closest('table');
245
+ var tbody = table.querySelector('tbody');
246
+ if (!tbody) return;
247
+ var idx = Array.from(this.parentNode.children).indexOf(this);
248
+ var rows = Array.from(tbody.querySelectorAll('tr'));
249
+ var asc = this.dataset.sort !== 'asc';
250
+ rows.sort(function(a, b) {
251
+ var at = (a.children[idx] || {}).textContent || '';
252
+ var bt = (b.children[idx] || {}).textContent || '';
253
+ return asc ? at.localeCompare(bt) : bt.localeCompare(at);
254
+ });
255
+ this.dataset.sort = asc ? 'asc' : 'desc';
256
+ rows.forEach(function(r) { tbody.appendChild(r); });
257
+ });
258
+ });
259
+
260
+ function exportAs(fmt) {
261
+ var blob = new Blob([JSON.stringify(DATA, null, 2)], { type: 'application/json' });
262
+ var a = document.createElement('a');
263
+ a.href = URL.createObjectURL(blob);
264
+ a.download = 'permissions.' + fmt;
265
+ a.click();
266
+ }
267
+
268
+ function exportMarkdown() {
269
+ var opts = { credentials: 'same-origin' };
270
+ if (typeof AUTH_TOKEN !== 'undefined' && AUTH_TOKEN) {
271
+ opts.headers = { 'Authorization': AUTH_TOKEN };
272
+ }
273
+ fetch(BASE_PATH + '/markdown', opts)
274
+ .then(function(res) { return res.text(); })
275
+ .then(function(text) {
276
+ var blob = new Blob([text], { type: 'text/plain' });
277
+ var a = document.createElement('a');
278
+ a.href = URL.createObjectURL(blob);
279
+ a.download = 'permissions.md';
280
+ a.click();
281
+ });
282
+ }
283
+
284
+ function rescan(e) {
285
+ var btn = e ? e.target : this;
286
+ btn.disabled = true;
287
+ btn.textContent = 'Scanning...';
288
+ var opts = { method: 'POST', credentials: 'same-origin' };
289
+ if (typeof AUTH_TOKEN !== 'undefined' && AUTH_TOKEN) {
290
+ opts.headers = { 'Authorization': AUTH_TOKEN };
291
+ }
292
+ fetch(BASE_PATH + '/rescan', opts)
293
+ .then(function(res) { if (!res.ok) throw new Error(res.status); window.location.reload(); })
294
+ .catch(function(err) { alert('Rescan failed: ' + err); btn.disabled = false; btn.textContent = 'Rescan'; });
295
+ }
296
+ </script>`;
297
+ }
298
+ buildCss() {
299
+ return `<style>
300
+ :root {
301
+ --bg: #ffffff; --fg: #1a1a2e; --bg-card: #f8f9fa; --border: #dee2e6;
302
+ --primary: #0d6efd; --success: #198754; --warning: #ffc107; --danger: #dc3545;
303
+ --role-everyone: #198754; --role-noone: #dc3545; --role-admin: #0d6efd;
304
+ --role-user: #e6a817; --role-self: #6c757d; --role-custom: #fd7e14;
305
+ --shadow: 0 1px 3px rgba(0,0,0,0.12);
306
+ }
307
+ @media (prefers-color-scheme: dark) {
308
+ :root {
309
+ --bg: #1a1a2e; --fg: #e0e0e0; --bg-card: #16213e; --border: #3a3a5c;
310
+ --shadow: 0 1px 3px rgba(0,0,0,0.4);
311
+ }
312
+ }
313
+ * { margin: 0; padding: 0; box-sizing: border-box; }
314
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: var(--bg); color: var(--fg); line-height: 1.6; }
315
+ .layout { display: flex; min-height: 100vh; }
316
+ .sidebar { width: 260px; position: sticky; top: 0; height: 100vh; overflow-y: auto; background: var(--bg-card); border-right: 1px solid var(--border); padding: 1rem; flex-shrink: 0; }
317
+ .sidebar h3 { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--primary); margin-bottom: 0.5rem; }
318
+ .sidebar a { display: block; padding: 0.25rem 0.5rem; color: var(--fg); text-decoration: none; font-size: 0.85rem; border-radius: 4px; }
319
+ .sidebar a:hover { background: var(--border); }
320
+ .sidebar a.indent { padding-left: 1.5rem; font-size: 0.8rem; opacity: 0.8; }
321
+ .main { flex: 1; padding: 2rem; max-width: 1200px; }
322
+ .dashboard { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
323
+ .stat { background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; text-align: center; box-shadow: var(--shadow); }
324
+ .stat .num { font-size: 2rem; font-weight: 700; color: var(--primary); }
325
+ .stat .label { font-size: 0.8rem; opacity: 0.7; }
326
+ .stat.warn .num { color: var(--warning); }
327
+ .stat.danger .num { color: var(--danger); }
328
+ .controls { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; align-items: center; }
329
+ .controls input, .controls select { padding: 0.4rem 0.8rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg); font-size: 0.9rem; }
330
+ .controls input { flex: 1; min-width: 200px; }
331
+ .controls label { font-size: 0.85rem; display: flex; align-items: center; gap: 0.3rem; }
332
+ .badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 12px; font-size: 0.75rem; font-weight: 600; color: #fff; }
333
+ .badge-everyone { background: var(--role-everyone); }
334
+ .badge-noone { background: var(--role-noone); }
335
+ .badge-admin { background: var(--role-admin); }
336
+ .badge-user { background: var(--role-user); color: #000; }
337
+ .badge-self, .badge-creator { background: var(--role-self); }
338
+ .badge-custom { background: var(--role-custom); }
339
+ .badge-warn { background: var(--warning); color: #000; }
340
+ section { margin-bottom: 2rem; }
341
+ h1 { font-size: 1.8rem; margin-bottom: 0.5rem; }
342
+ h2 { font-size: 1.4rem; margin: 1.5rem 0 0.75rem; padding-bottom: 0.3rem; border-bottom: 2px solid var(--primary); }
343
+ h3 { font-size: 1.1rem; margin: 1rem 0 0.5rem; }
344
+ .meta { font-size: 0.85rem; opacity: 0.7; margin-bottom: 0.25rem; }
345
+ table { width: 100%; border-collapse: collapse; margin: 0.5rem 0 1rem; font-size: 0.85rem; }
346
+ th, td { padding: 0.4rem 0.6rem; text-align: left; border: 1px solid var(--border); }
347
+ th { background: var(--bg-card); cursor: pointer; user-select: none; white-space: nowrap; }
348
+ th:hover { background: var(--border); }
349
+ tr:nth-child(even) { background: var(--bg-card); }
350
+ .collapsible { cursor: pointer; }
351
+ .collapsible::before { content: '\\25B6'; display: inline-block; margin-right: 0.5rem; transition: transform 0.2s; font-size: 0.8rem; }
352
+ .collapsible.open::before { transform: rotate(90deg); }
353
+ .collapse-content { display: none; }
354
+ .collapse-content.open { display: block; }
355
+ .warning-row { background: rgba(255, 193, 7, 0.1) !important; }
356
+ .btn { padding: 0.4rem 0.8rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-card); color: var(--fg); cursor: pointer; font-size: 0.8rem; margin: 0.25rem 0; }
357
+ .btn:hover { background: var(--border); }
358
+ .module-header { position: sticky; top: 0; background: var(--bg); z-index: 10; padding: 0.5rem 0; border-bottom: 1px solid var(--border); }
359
+ @media (max-width: 768px) {
360
+ .sidebar { display: none; }
361
+ .main { padding: 1rem; }
362
+ .dashboard { grid-template-columns: repeat(2, 1fr); }
363
+ }
364
+ </style>`;
365
+ }
366
+ buildHtml(report) {
367
+ const data = JSON.stringify(report).replace(/</g, '\\u003c');
368
+ const s = report.stats;
369
+ const coverageClass = (pct) => (pct >= 90 ? '' : pct >= 70 ? 'warn' : 'danger');
370
+ return `<!DOCTYPE html>
371
+ <html lang="en">
372
+ <head>
373
+ <meta charset="UTF-8">
374
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
375
+ <title>Permissions Report</title>
376
+ ${this.buildCss()}
377
+ </head>
378
+ <body>
379
+ <div class="layout">
380
+ ${this.buildSidebarHtml(report)}
381
+ <div class="main">
382
+ <h1>Permissions Report</h1>
383
+ <p class="meta">Generated: ${this.escapeHtml(report.generated)}</p>
384
+
385
+ <section id="dashboard">
386
+ <div class="dashboard">
387
+ <div class="stat"><div class="num">${s.totalModules}</div><div class="label">Modules</div></div>
388
+ <div class="stat"><div class="num">${s.totalModels}</div><div class="label">Models</div></div>
389
+ <div class="stat"><div class="num">${s.totalEndpoints}</div><div class="label">Endpoints</div></div>
390
+ <div class="stat"><div class="num">${s.totalSubObjects}</div><div class="label">SubObjects</div></div>
391
+ <div class="stat ${s.totalWarnings > 0 ? 'danger' : ''}"><div class="num">${s.totalWarnings}</div><div class="label">Warnings</div></div>
392
+ <div class="stat ${coverageClass(s.endpointCoverage)}"><div class="num">${s.endpointCoverage}%</div><div class="label">Endpoint Coverage</div></div>
393
+ <div class="stat ${coverageClass(s.securityCoverage)}"><div class="num">${s.securityCoverage}%</div><div class="label">Security Coverage</div></div>
394
+ </div>
395
+ </section>
396
+
397
+ <section>
398
+ <div class="controls">
399
+ <input type="text" id="search" placeholder="Search modules, fields, roles..." oninput="filterAll()">
400
+ <select id="roleFilter" onchange="filterAll()">
401
+ <option value="">All Roles</option>
402
+ </select>
403
+ <label><input type="checkbox" id="warnOnly" onchange="filterAll()"> Warnings only</label>
404
+ </div>
405
+ </section>
406
+
407
+ ${this.buildRoleIndexSection(report)}
408
+ ${this.buildWarningsSection(report)}
409
+ ${this.buildModuleSectionsHtml(report)}
410
+ ${this.buildObjectsSectionsHtml(report)}
411
+
412
+ </div>
413
+ </div>
414
+
415
+ ${this.buildClientJs(data)}
416
+ </body>
417
+ </html>`;
418
+ }
419
+ buildModuleSectionsHtml(report) {
420
+ let html = '';
421
+ for (const mod of report.modules) {
422
+ const hasWarnings = report.warnings.some((w) => w.module === mod.name);
423
+ const allRoles = this.collectModuleRoles(mod);
424
+ html += `<section class="module-section" id="mod-${this.escapeHtml(mod.name)}" data-module="${this.escapeHtml(mod.name)}" data-has-warnings="${hasWarnings}" data-roles="${this.escapeHtml(allRoles.join(','))}">\n`;
425
+ html += `<div class="module-header"><h2 class="collapsible open" onclick="toggle(this)">Module: ${this.escapeHtml(mod.name)}</h2></div>\n<div class="collapse-content open">\n`;
426
+ for (const model of mod.models) {
427
+ html += `<div id="model-${this.escapeHtml(mod.name)}-${this.escapeHtml(model.className)}">`;
428
+ html += `<h3>Model: ${this.escapeHtml(model.className)}</h3>`;
429
+ html += `<p class="meta">File: ${this.escapeHtml(model.filePath)}</p>`;
430
+ if (model.extendsClass)
431
+ html += `<p class="meta">Extends: ${this.escapeHtml(model.extendsClass)}</p>`;
432
+ html += `<p class="meta">Class Restriction: ${model.classRestriction.length > 0 ? model.classRestriction.map((r) => this.badge(r)).join(' ') : '<em>(none)</em>'}</p>`;
433
+ html += `<p class="meta">securityCheck: ${model.securityCheck ? this.escapeHtml(model.securityCheck.summary) : '<em>Not present</em>'}</p>`;
434
+ if (model.fields.length > 0) {
435
+ html += '<table><thead><tr><th>Field</th><th>Roles</th><th>Source</th></tr></thead><tbody>';
436
+ for (const f of model.fields) {
437
+ html += `<tr><td>${this.escapeHtml(f.name)}</td><td>${this.escapeHtml(f.roles)}</td><td>${f.inherited ? 'inherited' : 'local'}</td></tr>`;
438
+ }
439
+ html += '</tbody></table>';
440
+ }
441
+ html += '</div>\n';
442
+ }
443
+ for (const input of mod.inputs) {
444
+ html += `<div><h3>Input: ${this.escapeHtml(input.className)}</h3>`;
445
+ html += `<p class="meta">File: ${this.escapeHtml(input.filePath)}</p>`;
446
+ if (input.extendsClass)
447
+ html += `<p class="meta">Extends: ${this.escapeHtml(input.extendsClass)}</p>`;
448
+ if (input.fields.length > 0) {
449
+ html += '<table><thead><tr><th>Field</th><th>Roles</th></tr></thead><tbody>';
450
+ for (const f of input.fields) {
451
+ html += `<tr><td>${this.escapeHtml(f.name)}</td><td>${this.escapeHtml(f.roles)}</td></tr>`;
452
+ }
453
+ html += '</tbody></table>';
454
+ }
455
+ html += '</div>\n';
456
+ }
457
+ for (const ctrl of mod.controllers) {
458
+ html += `<div id="ctrl-${this.escapeHtml(mod.name)}-${this.escapeHtml(ctrl.className)}">`;
459
+ html += `<h3>Controller: ${this.escapeHtml(ctrl.className)}</h3>`;
460
+ html += `<p class="meta">File: ${this.escapeHtml(ctrl.filePath)}</p>`;
461
+ html += `<p class="meta">Class Roles: ${this.badgeList(ctrl.classRoles)}</p>`;
462
+ if (ctrl.methods.length > 0) {
463
+ html +=
464
+ '<table><thead><tr><th>Method</th><th>HTTP</th><th>Route</th><th>Roles</th><th>Effective</th></tr></thead><tbody>';
465
+ for (const m of ctrl.methods) {
466
+ const eff = m.roles.length > 0 ? m.roles : ctrl.classRoles;
467
+ html += `<tr><td>${this.escapeHtml(m.name)}</td><td>${this.escapeHtml(m.httpMethod)}</td><td>${this.escapeHtml(m.route || '/')}</td><td>${this.badgeList(m.roles)}</td><td>${this.badgeList(eff)}${m.roles.length === 0 && ctrl.classRoles.length > 0 ? ' (class)' : ''}</td></tr>`;
468
+ }
469
+ html += '</tbody></table>';
470
+ }
471
+ html += '</div>\n';
472
+ }
473
+ for (const res of mod.resolvers) {
474
+ html += `<div id="res-${this.escapeHtml(mod.name)}-${this.escapeHtml(res.className)}">`;
475
+ html += `<h3>Resolver: ${this.escapeHtml(res.className)}</h3>`;
476
+ html += `<p class="meta">File: ${this.escapeHtml(res.filePath)}</p>`;
477
+ html += `<p class="meta">Class Roles: ${this.badgeList(res.classRoles)}</p>`;
478
+ if (res.methods.length > 0) {
479
+ html += '<table><thead><tr><th>Method</th><th>Type</th><th>Roles</th><th>Effective</th></tr></thead><tbody>';
480
+ for (const m of res.methods) {
481
+ const eff = m.roles.length > 0 ? m.roles : res.classRoles;
482
+ html += `<tr><td>${this.escapeHtml(m.name)}</td><td>${this.escapeHtml(m.httpMethod)}</td><td>${this.badgeList(m.roles)}</td><td>${this.badgeList(eff)}${m.roles.length === 0 && res.classRoles.length > 0 ? ' (class)' : ''}</td></tr>`;
483
+ }
484
+ html += '</tbody></table>';
485
+ }
486
+ html += '</div>\n';
487
+ }
488
+ html += '</div></section>\n';
489
+ }
490
+ return html;
491
+ }
492
+ buildObjectsSectionsHtml(report) {
493
+ if (report.objects.length === 0)
494
+ return '';
495
+ let html = '<section id="subobjects"><h2>SubObjects</h2>\n';
496
+ for (const obj of report.objects) {
497
+ html += `<div><h3>${this.escapeHtml(obj.className)}</h3>`;
498
+ html += `<p class="meta">File: ${this.escapeHtml(obj.filePath)}</p>`;
499
+ if (obj.extendsClass)
500
+ html += `<p class="meta">Extends: ${this.escapeHtml(obj.extendsClass)}</p>`;
501
+ if (obj.fields.length > 0) {
502
+ html += '<table><thead><tr><th>Field</th><th>Roles</th><th>Source</th></tr></thead><tbody>';
503
+ for (const f of obj.fields) {
504
+ html += `<tr><td>${this.escapeHtml(f.name)}</td><td>${this.escapeHtml(f.roles)}</td><td>${f.inherited ? 'inherited' : 'local'}</td></tr>`;
505
+ }
506
+ html += '</tbody></table>';
507
+ }
508
+ html += '</div>\n';
509
+ }
510
+ html += '</section>\n';
511
+ return html;
512
+ }
513
+ buildRoleIndexSection(report) {
514
+ let rows = '';
515
+ if (report.roleEnums.length > 0) {
516
+ for (const e of report.roleEnums) {
517
+ for (const v of e.values) {
518
+ const isSystem = v.key.startsWith('S_');
519
+ rows += `<tr><td>${this.escapeHtml(e.name)}.${this.escapeHtml(v.key)}</td><td>${isSystem ? '(system)' : this.escapeHtml(v.value)}</td><td>${this.badge(isSystem ? 'System' : 'Real')}</td></tr>\n`;
520
+ }
521
+ }
522
+ }
523
+ const content = report.roleEnums.length > 0
524
+ ? `<table><thead><tr><th>Enum</th><th>Value</th><th>Type</th></tr></thead><tbody>${rows}</tbody></table>`
525
+ : '<p><em>No role enums found.</em></p>';
526
+ return `<section id="role-index">
527
+ <h2 class="collapsible open" onclick="toggle(this)">Role Index</h2>
528
+ <div class="collapse-content open">
529
+ ${content}
530
+ </div>
531
+ </section>`;
532
+ }
533
+ buildSidebarHtml(report) {
534
+ let links = '';
535
+ for (const mod of report.modules) {
536
+ links += `<a href="#mod-${this.escapeHtml(mod.name)}">${this.escapeHtml(mod.name)}</a>\n`;
537
+ for (const model of mod.models) {
538
+ links += `<a href="#model-${this.escapeHtml(mod.name)}-${this.escapeHtml(model.className)}" class="indent">Model: ${this.escapeHtml(model.className)}</a>\n`;
539
+ }
540
+ for (const ctrl of mod.controllers) {
541
+ links += `<a href="#ctrl-${this.escapeHtml(mod.name)}-${this.escapeHtml(ctrl.className)}" class="indent">Ctrl: ${this.escapeHtml(ctrl.className)}</a>\n`;
542
+ }
543
+ for (const res of mod.resolvers) {
544
+ links += `<a href="#res-${this.escapeHtml(mod.name)}-${this.escapeHtml(res.className)}" class="indent">Resolver: ${this.escapeHtml(res.className)}</a>\n`;
545
+ }
546
+ }
547
+ return `<nav class="sidebar">
548
+ <h3>Permissions Report</h3>
549
+ <a href="#dashboard">Dashboard</a>
550
+ <a href="#role-index">Role Index</a>
551
+ <a href="#warnings">Warnings (${report.warnings.length})</a>
552
+ <hr style="margin:0.5rem 0;border-color:var(--border)">
553
+ ${links}
554
+ ${report.objects.length > 0 ? '<hr style="margin:0.5rem 0;border-color:var(--border)"><a href="#subobjects">SubObjects</a>' : ''}
555
+ <hr style="margin:0.5rem 0;border-color:var(--border)">
556
+ <button class="btn" onclick="exportAs('json')">Export JSON</button>
557
+ <button class="btn" onclick="exportMarkdown()">Export Markdown</button>
558
+ <button class="btn" onclick="rescan(event)">Rescan</button>
559
+ </nav>`;
560
+ }
561
+ buildWarningsSection(report) {
562
+ let rows = '';
563
+ for (let i = 0; i < report.warnings.length; i++) {
564
+ const w = report.warnings[i];
565
+ const fileName = w.file.split('/').pop() || w.file;
566
+ rows += `<tr class="warning-row"><td>${i + 1}</td><td>${this.escapeHtml(w.module)}</td><td>${this.escapeHtml(fileName)}</td><td><span class="badge badge-warn">${this.escapeHtml(w.type)}</span></td><td>${this.escapeHtml(w.details)}</td></tr>\n`;
567
+ }
568
+ const content = report.warnings.length > 0
569
+ ? `<table><thead><tr><th>#</th><th>Module</th><th>File</th><th>Type</th><th>Details</th></tr></thead><tbody>${rows}</tbody></table>`
570
+ : '<p><em>No warnings found.</em></p>';
571
+ return `<section id="warnings">
572
+ <h2 class="collapsible open" onclick="toggle(this)">Warnings (${report.warnings.length})</h2>
573
+ <div class="collapse-content open">
574
+ ${content}
575
+ </div>
576
+ </section>`;
577
+ }
578
+ setupWatcher() {
579
+ try {
580
+ const root = (0, permissions_scanner_1.findProjectRoot)();
581
+ if (!root)
582
+ return;
583
+ const watchPath = (0, path_1.join)(root, 'src', 'server');
584
+ if (!(0, fs_1.existsSync)(watchPath))
585
+ return;
586
+ this.watcher = fs.watch(watchPath, { recursive: true }, (_eventType, filename) => {
587
+ if (filename?.endsWith('.ts')) {
588
+ this.logger.debug(`File changed: ${filename}, invalidating cache`);
589
+ this.report = null;
590
+ this.htmlCache = null;
591
+ this.markdownCache = null;
592
+ }
593
+ });
594
+ this.watcher.on('error', (err) => {
595
+ this.logger.warn(`File watcher error: ${err.message}, manual rescan needed`);
596
+ });
597
+ }
598
+ catch (err) {
599
+ this.logger.warn(`File watcher setup failed: ${err}, manual rescan needed`);
600
+ }
601
+ }
602
+ };
603
+ exports.CorePermissionsService = CorePermissionsService;
604
+ exports.CorePermissionsService = CorePermissionsService = CorePermissionsService_1 = __decorate([
605
+ (0, common_1.Injectable)(),
606
+ __param(0, (0, common_1.Optional)()),
607
+ __param(0, (0, common_1.Inject)('PERMISSIONS_PATH')),
608
+ __metadata("design:paramtypes", [String])
609
+ ], CorePermissionsService);
610
+ //# sourceMappingURL=core-permissions.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-permissions.service.js","sourceRoot":"","sources":["../../../../src/core/modules/permissions/core-permissions.service.ts"],"names":[],"mappings":"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"}