@robertraaijmakers/pptb-securityplugin 0.1.1 → 0.1.2
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.
- package/dist/app.js +95 -52
- package/dist/app.js.map +2 -2
- package/dist/index.css +11 -1
- package/dist/index.html +9 -1
- package/dist/npm-shrinkwrap.json +2 -2
- package/package.json +15 -5
package/dist/app.js
CHANGED
|
@@ -1050,14 +1050,14 @@ ${logTarget.textContent}`;
|
|
|
1050
1050
|
}
|
|
1051
1051
|
return Array.from(set2);
|
|
1052
1052
|
}
|
|
1053
|
-
var requestAnimFrame = function() {
|
|
1053
|
+
var requestAnimFrame = (function() {
|
|
1054
1054
|
if (typeof window === "undefined") {
|
|
1055
1055
|
return function(callback2) {
|
|
1056
1056
|
return callback2();
|
|
1057
1057
|
};
|
|
1058
1058
|
}
|
|
1059
1059
|
return window.requestAnimationFrame;
|
|
1060
|
-
}();
|
|
1060
|
+
})();
|
|
1061
1061
|
function throttled(fn, thisArg) {
|
|
1062
1062
|
let argsToUse = [];
|
|
1063
1063
|
let ticking = false;
|
|
@@ -1671,6 +1671,7 @@ ${logTarget.textContent}`;
|
|
|
1671
1671
|
}
|
|
1672
1672
|
ctx.beginPath();
|
|
1673
1673
|
switch (style) {
|
|
1674
|
+
// Default includes circle
|
|
1674
1675
|
default:
|
|
1675
1676
|
if (w) {
|
|
1676
1677
|
ctx.ellipse(x, y, w / 2, radius, 0, 0, TAU);
|
|
@@ -1709,6 +1710,7 @@ ${logTarget.textContent}`;
|
|
|
1709
1710
|
break;
|
|
1710
1711
|
}
|
|
1711
1712
|
rad += QUARTER_PI;
|
|
1713
|
+
/* falls through */
|
|
1712
1714
|
case "rectRot":
|
|
1713
1715
|
xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
|
|
1714
1716
|
xOffset = Math.cos(rad) * radius;
|
|
@@ -1722,6 +1724,7 @@ ${logTarget.textContent}`;
|
|
|
1722
1724
|
break;
|
|
1723
1725
|
case "crossRot":
|
|
1724
1726
|
rad += QUARTER_PI;
|
|
1727
|
+
/* falls through */
|
|
1725
1728
|
case "cross":
|
|
1726
1729
|
xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
|
|
1727
1730
|
xOffset = Math.cos(rad) * radius;
|
|
@@ -2611,7 +2614,7 @@ ${logTarget.textContent}`;
|
|
|
2611
2614
|
}
|
|
2612
2615
|
return false;
|
|
2613
2616
|
}
|
|
2614
|
-
var supportsEventListenerOptions = function() {
|
|
2617
|
+
var supportsEventListenerOptions = (function() {
|
|
2615
2618
|
let passiveSupported = false;
|
|
2616
2619
|
try {
|
|
2617
2620
|
const options = {
|
|
@@ -2627,7 +2630,7 @@ ${logTarget.textContent}`;
|
|
|
2627
2630
|
} catch (e) {
|
|
2628
2631
|
}
|
|
2629
2632
|
return passiveSupported;
|
|
2630
|
-
}();
|
|
2633
|
+
})();
|
|
2631
2634
|
function readUsedSize(element, property) {
|
|
2632
2635
|
const value = getStyle(element, property);
|
|
2633
2636
|
const matches = value && value.match(/^(\d+)(\.\d+)?px$/);
|
|
@@ -14545,6 +14548,14 @@ ${logTarget.textContent}`;
|
|
|
14545
14548
|
|
|
14546
14549
|
// src/services/dataverseService.ts
|
|
14547
14550
|
var dataverseAPI = window.dataverseAPI;
|
|
14551
|
+
function buildPrivilegeReference(privilegeId) {
|
|
14552
|
+
const apiEndpoint = dataverseAPI?.apiEndpoint;
|
|
14553
|
+
if (!apiEndpoint) {
|
|
14554
|
+
return `privileges(${privilegeId})`;
|
|
14555
|
+
}
|
|
14556
|
+
const separator = apiEndpoint.endsWith("/") ? "" : "/";
|
|
14557
|
+
return `${apiEndpoint}${separator}privileges(${privilegeId})`;
|
|
14558
|
+
}
|
|
14548
14559
|
async function queryAll(odataQuery) {
|
|
14549
14560
|
const all = [];
|
|
14550
14561
|
let response = await dataverseAPI.queryData(odataQuery);
|
|
@@ -14675,6 +14686,35 @@ ${logTarget.textContent}`;
|
|
|
14675
14686
|
const response = await dataverseAPI.queryData(query);
|
|
14676
14687
|
return response?.RolePrivileges ?? response?.rolePrivileges ?? response?.value ?? [];
|
|
14677
14688
|
}
|
|
14689
|
+
async function addPrivilegesToRole(roleId, privileges) {
|
|
14690
|
+
if (privileges.length === 0) {
|
|
14691
|
+
return;
|
|
14692
|
+
}
|
|
14693
|
+
await dataverseAPI.execute({
|
|
14694
|
+
entityName: "role",
|
|
14695
|
+
entityId: roleId,
|
|
14696
|
+
operationName: "AddPrivilegesRole",
|
|
14697
|
+
operationType: "action",
|
|
14698
|
+
parameters: {
|
|
14699
|
+
Privileges: privileges
|
|
14700
|
+
}
|
|
14701
|
+
});
|
|
14702
|
+
}
|
|
14703
|
+
async function removePrivilegesFromRole(roleId, privilegeId) {
|
|
14704
|
+
if (!privilegeId) {
|
|
14705
|
+
return;
|
|
14706
|
+
}
|
|
14707
|
+
const privilegeReference = buildPrivilegeReference(privilegeId);
|
|
14708
|
+
await dataverseAPI.execute({
|
|
14709
|
+
entityName: "role",
|
|
14710
|
+
entityId: roleId,
|
|
14711
|
+
operationName: "RemovePrivilegeRole",
|
|
14712
|
+
operationType: "action",
|
|
14713
|
+
parameters: {
|
|
14714
|
+
Privilege: privilegeReference
|
|
14715
|
+
}
|
|
14716
|
+
});
|
|
14717
|
+
}
|
|
14678
14718
|
async function associateRoleToUser(userId, roleId) {
|
|
14679
14719
|
await dataverseAPI.associate(
|
|
14680
14720
|
"systemuser",
|
|
@@ -14741,6 +14781,7 @@ ${logTarget.textContent}`;
|
|
|
14741
14781
|
loadingRolesMetadata: "Loading roles and metadata",
|
|
14742
14782
|
loadingRolePrivileges: "Loading role privileges",
|
|
14743
14783
|
loadingRefreshingPrivileges: "Refreshing role privileges",
|
|
14784
|
+
loadingApplyingChanges: "Applying privilege changes",
|
|
14744
14785
|
loadingDashboardData: "Loading dashboard data",
|
|
14745
14786
|
loadingDashboardRolesTeams: "Loading roles and teams",
|
|
14746
14787
|
loadingDashboardPeople: "Loading users, business units, and team memberships",
|
|
@@ -14791,10 +14832,6 @@ ${logTarget.textContent}`;
|
|
|
14791
14832
|
title: "Update failed",
|
|
14792
14833
|
body: "Failed to apply privilege updates. See console for details."
|
|
14793
14834
|
},
|
|
14794
|
-
updated: {
|
|
14795
|
-
title: "Privileges updated",
|
|
14796
|
-
body: "Your changes have been queued for update."
|
|
14797
|
-
},
|
|
14798
14835
|
cacheFailed: {
|
|
14799
14836
|
title: "Cache failed",
|
|
14800
14837
|
body: "Could not cache role privileges. See console for details."
|
|
@@ -14846,9 +14883,6 @@ ${logTarget.textContent}`;
|
|
|
14846
14883
|
function formatMissingPrivilegeId(entityLogicalName, privilege) {
|
|
14847
14884
|
return `Missing privilege ID for ${entityLogicalName}:${privilege}`;
|
|
14848
14885
|
}
|
|
14849
|
-
function formatQueuedPrivilegeChange(privilege, entityLogicalName, level) {
|
|
14850
|
-
return `Queued ${privilege} change for ${entityLogicalName}: ${level}`;
|
|
14851
|
-
}
|
|
14852
14886
|
function formatNoPrivilegesForRole(roleName) {
|
|
14853
14887
|
return `No privileges returned for role ${roleName}.`;
|
|
14854
14888
|
}
|
|
@@ -14944,6 +14978,7 @@ ${logTarget.textContent}`;
|
|
|
14944
14978
|
direction: "asc"
|
|
14945
14979
|
},
|
|
14946
14980
|
assignmentFilter: "",
|
|
14981
|
+
assignmentSearch: "",
|
|
14947
14982
|
sort: {
|
|
14948
14983
|
column: "label",
|
|
14949
14984
|
direction: "asc"
|
|
@@ -15004,6 +15039,7 @@ ${logTarget.textContent}`;
|
|
|
15004
15039
|
document.querySelectorAll("[data-assign-sort]")
|
|
15005
15040
|
),
|
|
15006
15041
|
assignmentFilterAssigned: document.getElementById("assignment-filter-assigned"),
|
|
15042
|
+
assignmentSearch: document.getElementById("assignment-search"),
|
|
15007
15043
|
controlsPrivileges: document.getElementById("controls-privileges"),
|
|
15008
15044
|
controlsAssignments: document.getElementById("controls-assignments"),
|
|
15009
15045
|
controlsDashboard: document.getElementById("controls-dashboard"),
|
|
@@ -15424,6 +15460,17 @@ ${logTarget.textContent}`;
|
|
|
15424
15460
|
if (state.assignmentFilter === "not-assigned") {
|
|
15425
15461
|
return !item.assigned;
|
|
15426
15462
|
}
|
|
15463
|
+
if (state.assignmentSearch) {
|
|
15464
|
+
const rawTerm = state.assignmentSearch.toLowerCase();
|
|
15465
|
+
const term = rawTerm.replace(/\*/g, "").trim();
|
|
15466
|
+
if (term) {
|
|
15467
|
+
const labelMatch = item.label.toLowerCase().includes(term);
|
|
15468
|
+
const subLabelMatch = item.subLabel ? item.subLabel.toLowerCase().includes(term) : false;
|
|
15469
|
+
if (!labelMatch && !subLabelMatch) {
|
|
15470
|
+
return false;
|
|
15471
|
+
}
|
|
15472
|
+
}
|
|
15473
|
+
}
|
|
15427
15474
|
return true;
|
|
15428
15475
|
});
|
|
15429
15476
|
return [...filtered].sort((a, b) => {
|
|
@@ -15768,7 +15815,6 @@ ${logTarget.textContent}`;
|
|
|
15768
15815
|
const level = select.value;
|
|
15769
15816
|
const isPending = updatePendingChange(roleId, row.entityLogicalName, privilege, level);
|
|
15770
15817
|
setPendingClass(select, isPending);
|
|
15771
|
-
logMessage(formatQueuedPrivilegeChange(privilege, row.entityLogicalName, level));
|
|
15772
15818
|
});
|
|
15773
15819
|
select.disabled = !isRoleMode && !row.roleId;
|
|
15774
15820
|
applyLevelClass(select, select.value);
|
|
@@ -15929,18 +15975,18 @@ ${logTarget.textContent}`;
|
|
|
15929
15975
|
}
|
|
15930
15976
|
return "none";
|
|
15931
15977
|
}
|
|
15932
|
-
function
|
|
15978
|
+
function mapPrivilegeDepthLabel(level) {
|
|
15933
15979
|
switch (level) {
|
|
15934
15980
|
case "user":
|
|
15935
|
-
return
|
|
15981
|
+
return "Basic";
|
|
15936
15982
|
case "businessUnit":
|
|
15937
|
-
return
|
|
15983
|
+
return "Local";
|
|
15938
15984
|
case "parentChild":
|
|
15939
|
-
return
|
|
15985
|
+
return "Deep";
|
|
15940
15986
|
case "organization":
|
|
15941
|
-
return
|
|
15987
|
+
return "Global";
|
|
15942
15988
|
default:
|
|
15943
|
-
return
|
|
15989
|
+
return "None";
|
|
15944
15990
|
}
|
|
15945
15991
|
}
|
|
15946
15992
|
function mapOwnershipLabel(raw) {
|
|
@@ -17266,42 +17312,44 @@ ${logTarget.textContent}`;
|
|
|
17266
17312
|
if (currentLevel === change.level) {
|
|
17267
17313
|
continue;
|
|
17268
17314
|
}
|
|
17269
|
-
if (
|
|
17315
|
+
if (change.level === "none") {
|
|
17270
17316
|
if (!removesByRole.has(change.roleId)) {
|
|
17271
17317
|
removesByRole.set(change.roleId, []);
|
|
17272
17318
|
}
|
|
17273
17319
|
removesByRole.get(change.roleId).push(privilegeId);
|
|
17274
|
-
}
|
|
17275
|
-
if (change.level !== "none") {
|
|
17320
|
+
} else {
|
|
17276
17321
|
if (!addsByRole.has(change.roleId)) {
|
|
17277
17322
|
addsByRole.set(change.roleId, []);
|
|
17278
17323
|
}
|
|
17324
|
+
const privilegeInfo = state.privilegeInfoById.get(privilegeId);
|
|
17279
17325
|
addsByRole.get(change.roleId).push({
|
|
17280
17326
|
PrivilegeId: privilegeId,
|
|
17281
|
-
Depth:
|
|
17327
|
+
Depth: mapPrivilegeDepthLabel(change.level),
|
|
17328
|
+
PrivilegeName: privilegeInfo?.name
|
|
17282
17329
|
});
|
|
17283
17330
|
}
|
|
17284
17331
|
}
|
|
17332
|
+
const totalRemoveCalls = Array.from(removesByRole.values()).reduce(
|
|
17333
|
+
(total, privilegeIds) => total + privilegeIds.length,
|
|
17334
|
+
0
|
|
17335
|
+
);
|
|
17336
|
+
const totalAddCalls = addsByRole.size;
|
|
17337
|
+
const totalCalls = totalRemoveCalls + totalAddCalls;
|
|
17338
|
+
let completedCalls = 0;
|
|
17339
|
+
setLoading(true, UI_TEXT.loadingApplyingChanges);
|
|
17340
|
+
updateLoadingProgress(0, totalCalls, UI_TEXT.loadingApplyingChanges);
|
|
17285
17341
|
try {
|
|
17286
17342
|
for (const [roleId, privilegeIds] of removesByRole) {
|
|
17287
|
-
|
|
17288
|
-
|
|
17289
|
-
|
|
17290
|
-
|
|
17291
|
-
|
|
17292
|
-
PrivilegeIds: privilegeIds
|
|
17293
|
-
}
|
|
17294
|
-
});
|
|
17343
|
+
for (const privilegeId of privilegeIds) {
|
|
17344
|
+
await removePrivilegesFromRole(roleId, privilegeId);
|
|
17345
|
+
completedCalls += 1;
|
|
17346
|
+
updateLoadingProgress(completedCalls, totalCalls, UI_TEXT.loadingApplyingChanges);
|
|
17347
|
+
}
|
|
17295
17348
|
}
|
|
17296
17349
|
for (const [roleId, privileges] of addsByRole) {
|
|
17297
|
-
await
|
|
17298
|
-
|
|
17299
|
-
|
|
17300
|
-
parameters: {
|
|
17301
|
-
RoleId: roleId,
|
|
17302
|
-
Privileges: privileges
|
|
17303
|
-
}
|
|
17304
|
-
});
|
|
17350
|
+
await addPrivilegesToRole(roleId, privileges);
|
|
17351
|
+
completedCalls += 1;
|
|
17352
|
+
updateLoadingProgress(completedCalls, totalCalls, UI_TEXT.loadingApplyingChanges);
|
|
17305
17353
|
}
|
|
17306
17354
|
for (const change of state.pendingChanges) {
|
|
17307
17355
|
if (!state.rolePrivileges.has(change.roleId)) {
|
|
@@ -17320,16 +17368,12 @@ ${logTarget.textContent}`;
|
|
|
17320
17368
|
duration: 3500
|
|
17321
17369
|
});
|
|
17322
17370
|
return;
|
|
17371
|
+
} finally {
|
|
17372
|
+
setLoading(false);
|
|
17323
17373
|
}
|
|
17324
17374
|
state.pendingChanges = [];
|
|
17325
|
-
await toolboxAPI2.utils.showNotification({
|
|
17326
|
-
title: NOTIFICATIONS.updated.title,
|
|
17327
|
-
body: NOTIFICATIONS.updated.body,
|
|
17328
|
-
type: "success",
|
|
17329
|
-
duration: 2500
|
|
17330
|
-
});
|
|
17331
17375
|
updatePendingUi();
|
|
17332
|
-
|
|
17376
|
+
await refreshPrivilegeView();
|
|
17333
17377
|
}
|
|
17334
17378
|
async function refreshData() {
|
|
17335
17379
|
if (state.refreshInProgress) {
|
|
@@ -17618,6 +17662,12 @@ ${logTarget.textContent}`;
|
|
|
17618
17662
|
renderAssignmentTable(state.assignmentItems);
|
|
17619
17663
|
});
|
|
17620
17664
|
}
|
|
17665
|
+
if (elements2.assignmentSearch) {
|
|
17666
|
+
elements2.assignmentSearch.addEventListener("input", () => {
|
|
17667
|
+
state.assignmentSearch = elements2.assignmentSearch.value.trim();
|
|
17668
|
+
renderAssignmentTable(state.assignmentItems);
|
|
17669
|
+
});
|
|
17670
|
+
}
|
|
17621
17671
|
for (const button of elements2.sortButtons) {
|
|
17622
17672
|
button.addEventListener("click", () => {
|
|
17623
17673
|
const column = button.dataset.sort || "label";
|
|
@@ -17681,13 +17731,6 @@ ${logTarget.textContent}`;
|
|
|
17681
17731
|
*)
|
|
17682
17732
|
|
|
17683
17733
|
chart.js/dist/chunks/helpers.dataset.js:
|
|
17684
|
-
(*!
|
|
17685
|
-
* Chart.js v4.5.1
|
|
17686
|
-
* https://www.chartjs.org
|
|
17687
|
-
* (c) 2025 Chart.js Contributors
|
|
17688
|
-
* Released under the MIT License
|
|
17689
|
-
*)
|
|
17690
|
-
|
|
17691
17734
|
chart.js/dist/chart.js:
|
|
17692
17735
|
(*!
|
|
17693
17736
|
* Chart.js v4.5.1
|