@robertraaijmakers/pptb-securityplugin 0.1.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.
@@ -0,0 +1,415 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Advanced Security Roles Explorer</title>
7
+ <link rel="stylesheet" href="index.css" />
8
+ </head>
9
+ <body>
10
+ <div id="app">
11
+ <header class="header">
12
+ <div>
13
+ <h1>Advanced Security Roles Explorer</h1>
14
+ <p class="subtitle">Be fully in control of your security by quickly viewing and managing which security roles give access to which tables. And who is assigned which security role.</p>
15
+ </div>
16
+ <div class="header-actions">
17
+ <div class="header-info">
18
+ <div id="connection-badge" class="badge">Not connected</div>
19
+ <button type="button" id="theme-toggle" class="btn theme-toggle" aria-label="Toggle theme">
20
+ <svg class="theme-icon theme-icon-sun" viewBox="0 0 24 24" aria-hidden="true">
21
+ <circle cx="12" cy="12" r="4"></circle>
22
+ <line x1="12" y1="2" x2="12" y2="5"></line>
23
+ <line x1="12" y1="19" x2="12" y2="22"></line>
24
+ <line x1="2" y1="12" x2="5" y2="12"></line>
25
+ <line x1="19" y1="12" x2="22" y2="12"></line>
26
+ <line x1="4.2" y1="4.2" x2="6.4" y2="6.4"></line>
27
+ <line x1="17.6" y1="17.6" x2="19.8" y2="19.8"></line>
28
+ <line x1="4.2" y1="19.8" x2="6.4" y2="17.6"></line>
29
+ <line x1="17.6" y1="6.4" x2="19.8" y2="4.2"></line>
30
+ </svg>
31
+ <svg class="theme-icon theme-icon-moon" viewBox="0 0 24 24" aria-hidden="true">
32
+ <path d="M21 14.2A8 8 0 0 1 9.8 3a9 9 0 1 0 11.2 11.2z" />
33
+ </svg>
34
+ </button>
35
+ </div>
36
+ <nav class="tabs">
37
+ <button class="tab-button active" data-tab="privileges">Edit security roles</button>
38
+ <button class="tab-button" data-tab="assignments">Assign security roles</button>
39
+ <button class="tab-button" data-tab="dashboard">Security dashboard</button>
40
+ </nav>
41
+ <div class="header-filter">
42
+ <label class="toggle" for="roles-custom-only-global">
43
+ <input type="checkbox" id="roles-custom-only-global" />
44
+ <span class="toggle-track"></span>
45
+ </label>
46
+ <span class="toggle-label">Unmanaged roles only</span>
47
+ </div>
48
+ </div>
49
+ </header>
50
+
51
+ <section class="controls">
52
+ <div id="controls-privileges" class="controls-group">
53
+ <div class="control">
54
+ <label for="filter-mode">Filter mode</label>
55
+ <select id="filter-mode">
56
+ <option value="role">By role</option>
57
+ <option value="entity">By entity</option>
58
+ </select>
59
+ </div>
60
+ <div class="control" id="role-select-control">
61
+ <label for="role-select">Security role</label>
62
+ <select id="role-select"></select>
63
+ </div>
64
+ <div class="control" id="entity-select-control">
65
+ <label for="entity-select">Entity</label>
66
+ <select id="entity-select"></select>
67
+ </div>
68
+ <div class="control" id="rights-filter-control">
69
+ <label for="rights-filter">Rights</label>
70
+ <select id="rights-filter">
71
+ <option value="all">Show all</option>
72
+ <option value="without">Show all without rights</option>
73
+ <option value="with">Show all with rights</option>
74
+ </select>
75
+ </div>
76
+ <div class="control role-filter" id="role-filter-control">
77
+ <label>Role filter</label>
78
+ <div class="multi-select" id="role-filter">
79
+ <button type="button" class="multi-select-button" id="role-filter-button">
80
+ All roles
81
+ </button>
82
+ <div class="multi-select-menu hidden" id="role-filter-menu">
83
+ <div class="multi-select-actions">
84
+ <button type="button" class="link-button" id="role-filter-all">Select all</button>
85
+ <button type="button" class="link-button" id="role-filter-none">Clear</button>
86
+ </div>
87
+ <div class="multi-select-list" id="role-filter-list"></div>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ <div id="controls-assignments" class="controls-group hidden">
93
+ <div class="control">
94
+ <label for="assignment-mode">View</label>
95
+ <select id="assignment-mode">
96
+ <option value="role">Role -> Users</option>
97
+ <option value="user">User -> Roles</option>
98
+ <option value="role-team">Role -> Teams</option>
99
+ <option value="team">Team -> Roles</option>
100
+ </select>
101
+ </div>
102
+ <div class="control" id="assignment-role-control">
103
+ <label for="assignment-role-select">Security role</label>
104
+ <select id="assignment-role-select"></select>
105
+ </div>
106
+ <div class="control" id="assignment-user-control">
107
+ <label for="assignment-user-select">User</label>
108
+ <select id="assignment-user-select"></select>
109
+ </div>
110
+ <div class="control" id="assignment-team-control">
111
+ <label for="assignment-team-select">Team</label>
112
+ <select id="assignment-team-select"></select>
113
+ </div>
114
+ </div>
115
+ <div id="controls-dashboard" class="controls-group hidden">
116
+ <div class="control">
117
+ <label for="dashboard-user-status">User status</label>
118
+ <select id="dashboard-user-status">
119
+ <option value="all">All</option>
120
+ <option value="active">Active only</option>
121
+ <option value="inactive">Inactive only</option>
122
+ </select>
123
+ </div>
124
+ <div class="control">
125
+ <label for="dashboard-user-type">User type</label>
126
+ <select id="dashboard-user-type">
127
+ <option value="all">All</option>
128
+ <option value="human">Human</option>
129
+ <option value="app">Application</option>
130
+ </select>
131
+ </div>
132
+ <div class="control">
133
+ <label for="dashboard-bu-select">Business unit</label>
134
+ <select id="dashboard-bu-select"></select>
135
+ </div>
136
+ <div class="control">
137
+ <label for="dashboard-role-select">Security role</label>
138
+ <select id="dashboard-role-select"></select>
139
+ </div>
140
+ <div class="control">
141
+ <label for="dashboard-team-select">Team</label>
142
+ <select id="dashboard-team-select"></select>
143
+ </div>
144
+ <div class="control">
145
+ <label>&nbsp;</label>
146
+ <button type="button" class="btn" id="dashboard-export">Download data</button>
147
+ </div>
148
+ </div>
149
+ </section>
150
+
151
+ <section id="tab-privileges" class="panel tab-panel">
152
+ <div class="panel-header">
153
+ <h2 id="table-title">Privileges</h2>
154
+ <div class="panel-actions">
155
+ <button id="undo-btn" class="btn">Undo changes</button>
156
+ <button id="apply-btn" class="btn">Apply changes</button>
157
+ <span id="pending-count" class="pending-count hidden">0</span>
158
+ <button id="refresh-btn" class="btn">Refresh</button>
159
+ </div>
160
+ </div>
161
+ <div id="table-loading" class="table-loading hidden">
162
+ <div class="loading-card">
163
+ <div class="loading-title">Loading privileges</div>
164
+ <div class="loading-progress">
165
+ <div id="loading-bar" class="loading-bar"></div>
166
+ </div>
167
+ <div id="loading-text" class="loading-text">Preparing...</div>
168
+ </div>
169
+ </div>
170
+ <div id="table-empty" class="table-empty hidden">
171
+ <div class="table-empty-title">No data loaded</div>
172
+ <div class="table-empty-text">Please click refresh to load data.</div>
173
+ </div>
174
+ <table class="table" id="privileges-table">
175
+ <thead>
176
+ <tr>
177
+ <th>
178
+ <button class="sort-button" data-sort="label">Entity / Role</button>
179
+ </th>
180
+ <th>Ownership</th>
181
+ <th>
182
+ <button class="sort-button" data-sort="create">Create</button>
183
+ </th>
184
+ <th>
185
+ <button class="sort-button" data-sort="read">Read</button>
186
+ </th>
187
+ <th>
188
+ <button class="sort-button" data-sort="write">Write</button>
189
+ </th>
190
+ <th>
191
+ <button class="sort-button" data-sort="delete">Delete</button>
192
+ </th>
193
+ <th>
194
+ <button class="sort-button" data-sort="append">Append</button>
195
+ <span
196
+ class="info-tooltip"
197
+ tabindex="0"
198
+ role="img"
199
+ aria-label="Append permission info"
200
+ data-tooltip="Append allows lookups on this table to reference other tables. Requires Append To on the target table."
201
+ >i</span>
202
+ </th>
203
+ <th>
204
+ <button class="sort-button" data-sort="appendto">Append To</button>
205
+ <span
206
+ class="info-tooltip"
207
+ tabindex="0"
208
+ role="img"
209
+ aria-label="Append To permission info"
210
+ data-tooltip="Append To lets other records do a lookup to this table. Requires Append on the source table."
211
+ >i</span>
212
+ </th>
213
+ <th>
214
+ <button class="sort-button" data-sort="assign">Assign</button>
215
+ </th>
216
+ </tr>
217
+ <tr class="filter-row">
218
+ <th></th>
219
+ <th></th>
220
+ <th>
221
+ <select class="filter-select" data-filter="create"></select>
222
+ </th>
223
+ <th>
224
+ <select class="filter-select" data-filter="read"></select>
225
+ </th>
226
+ <th>
227
+ <select class="filter-select" data-filter="write"></select>
228
+ </th>
229
+ <th>
230
+ <select class="filter-select" data-filter="delete"></select>
231
+ </th>
232
+ <th>
233
+ <select class="filter-select" data-filter="append"></select>
234
+ </th>
235
+ <th>
236
+ <select class="filter-select" data-filter="appendto"></select>
237
+ </th>
238
+ <th>
239
+ <select class="filter-select" data-filter="assign"></select>
240
+ </th>
241
+ </tr>
242
+ </thead>
243
+ <tbody></tbody>
244
+ </table>
245
+ </section>
246
+ <section id="tab-assignments" class="tab-panel hidden">
247
+ <div class="panel">
248
+ <div class="panel-header">
249
+ <div class="panel-header-text">
250
+ <h2 id="assignment-title">User roles</h2>
251
+ <p id="assignment-status" class="subtitle">Select a role or user to view assignments.</p>
252
+ </div>
253
+ <div class="panel-actions">
254
+ <button id="assignment-add" class="btn">Add</button>
255
+ <button id="assignment-remove" class="btn">Remove</button>
256
+ <span id="assignment-count" class="pending-count hidden">0</span>
257
+ </div>
258
+ </div>
259
+ <div class="assignment-list">
260
+ <div class="assignment-toolbar">
261
+ <button type="button" class="link-button" id="assignment-select-all">Select all</button>
262
+ <button type="button" class="link-button" id="assignment-clear">Clear</button>
263
+ </div>
264
+ <div class="assignment-table">
265
+ <table class="table" id="assignment-table">
266
+ <thead>
267
+ <tr>
268
+ <th>
269
+ <button class="sort-button" data-assign-sort="label">User / Role</button>
270
+ </th>
271
+ <th>
272
+ <button class="sort-button" data-assign-sort="assigned">Assigned</button>
273
+ </th>
274
+ <th>Select</th>
275
+ </tr>
276
+ <tr class="filter-row">
277
+ <th></th>
278
+ <th>
279
+ <select id="assignment-filter-assigned" class="filter-select">
280
+ <option value="">All</option>
281
+ <option value="assigned">Assigned</option>
282
+ <option value="not-assigned">Not assigned</option>
283
+ </select>
284
+ </th>
285
+ <th></th>
286
+ </tr>
287
+ </thead>
288
+ <tbody id="assignment-table-body"></tbody>
289
+ </table>
290
+ </div>
291
+ </div>
292
+ </div>
293
+ </section>
294
+ <section id="tab-dashboard" class="tab-panel hidden">
295
+ <div class="panel dashboard-panel">
296
+ <div id="dashboard-loading" class="table-loading hidden">
297
+ <div class="loading-card">
298
+ <div class="loading-title">Loading dashboard</div>
299
+ <div class="loading-progress">
300
+ <div id="dashboard-loading-bar" class="loading-bar"></div>
301
+ </div>
302
+ <div id="dashboard-loading-text" class="loading-text">Preparing...</div>
303
+ </div>
304
+ </div>
305
+ <div class="dashboard-content">
306
+ <div class="dashboard-grid">
307
+ <div class="dashboard-card metric-card">
308
+ <div class="metric-label">Active human users</div>
309
+ <div id="metric-human-active" class="metric-value">0</div>
310
+ </div>
311
+ <div class="dashboard-card metric-card">
312
+ <div class="metric-label">Inactive human users</div>
313
+ <div id="metric-human-inactive" class="metric-value">0</div>
314
+ </div>
315
+ <div class="dashboard-card metric-card">
316
+ <div class="metric-label">Active application users</div>
317
+ <div id="metric-app-active" class="metric-value">0</div>
318
+ </div>
319
+ <div class="dashboard-card metric-card">
320
+ <div class="metric-label">Inactive application users</div>
321
+ <div id="metric-app-inactive" class="metric-value">0</div>
322
+ </div>
323
+ <div class="dashboard-card metric-card">
324
+ <div class="metric-label">Unmanaged roles</div>
325
+ <div id="metric-custom-roles" class="metric-value">0</div>
326
+ </div>
327
+ <div class="dashboard-card metric-card">
328
+ <div class="metric-label">Managed roles</div>
329
+ <div id="metric-managed-roles" class="metric-value">0</div>
330
+ </div>
331
+ <div class="dashboard-card metric-card">
332
+ <div class="metric-label">Roles without users</div>
333
+ <div id="metric-roles-without-users" class="metric-value">0</div>
334
+ </div>
335
+ <div class="dashboard-card metric-card">
336
+ <div class="metric-label">Total teams</div>
337
+ <div id="metric-total-teams" class="metric-value">0</div>
338
+ </div>
339
+ </div>
340
+ <div class="dashboard-charts">
341
+ <div class="dashboard-card chart-card" data-dashboard-chart="usersByRole">
342
+ <div class="chart-header">
343
+ <div class="chart-title-row">
344
+ <h3>Active users per role</h3>
345
+ <button type="button" class="link-button chart-expand" data-dashboard-chart="usersByRole">
346
+ View all
347
+ </button>
348
+ </div>
349
+ <p class="subtitle">Based on active user assignments.</p>
350
+ </div>
351
+ <canvas id="chart-users-by-role"></canvas>
352
+ </div>
353
+ <div class="dashboard-card chart-card" data-dashboard-chart="teamsByRole">
354
+ <div class="chart-header">
355
+ <div class="chart-title-row">
356
+ <h3>Teams per role</h3>
357
+ <button type="button" class="link-button chart-expand" data-dashboard-chart="teamsByRole">
358
+ View all
359
+ </button>
360
+ </div>
361
+ <p class="subtitle">Shows how many teams carry each role.</p>
362
+ </div>
363
+ <canvas id="chart-teams-by-role"></canvas>
364
+ </div>
365
+ <div class="dashboard-card chart-card" data-dashboard-chart="usersByBusinessUnit">
366
+ <div class="chart-header">
367
+ <div class="chart-title-row">
368
+ <h3>Users per business unit</h3>
369
+ <button type="button" class="link-button chart-expand" data-dashboard-chart="usersByBusinessUnit">
370
+ View all
371
+ </button>
372
+ </div>
373
+ <p class="subtitle">Filtered by user status/type and business unit.</p>
374
+ </div>
375
+ <canvas id="chart-users-by-bu"></canvas>
376
+ </div>
377
+ <div class="dashboard-card chart-card" data-dashboard-chart="usersByTeam">
378
+ <div class="chart-header">
379
+ <div class="chart-title-row">
380
+ <h3>Users per team</h3>
381
+ <button type="button" class="link-button chart-expand" data-dashboard-chart="usersByTeam">
382
+ View all
383
+ </button>
384
+ </div>
385
+ <p class="subtitle">Filtered by user status/type and team.</p>
386
+ </div>
387
+ <canvas id="chart-users-by-team"></canvas>
388
+ </div>
389
+ </div>
390
+ </div>
391
+ </div>
392
+ </section>
393
+
394
+ <div id="chart-modal" class="modal hidden" aria-hidden="true">
395
+ <div class="modal-backdrop" data-modal-close="true"></div>
396
+ <div class="modal-content" role="dialog" aria-modal="true" aria-labelledby="chart-modal-title">
397
+ <div class="modal-header">
398
+ <h3 id="chart-modal-title">Chart</h3>
399
+ <button type="button" class="btn" id="chart-modal-close">Close</button>
400
+ </div>
401
+ <div class="modal-body">
402
+ <canvas id="chart-modal-canvas"></canvas>
403
+ </div>
404
+ </div>
405
+ </div>
406
+
407
+ <section class="logs">
408
+ <h2>Activity</h2>
409
+ <pre id="log"></pre>
410
+ </section>
411
+ </div>
412
+
413
+ <script src="app.js"></script>
414
+ </body>
415
+ </html>