Skip to content

Commit 2edfe84

Browse files
committed
Page Role Check uses currentbank. Signal Channels Broadcasts and Signal
Channel Stats. Account Directory
1 parent 1c7ace6 commit 2edfe84

File tree

13 files changed

+2519
-3
lines changed

13 files changed

+2519
-3
lines changed

src/lib/components/PageRoleCheck.svelte

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
userEntitlements: any[];
99
required: RoleRequirement[];
1010
optional?: RoleRequirement[];
11+
currentBankId?: string;
1112
children?: Snippet;
1213
}
1314
14-
let { userEntitlements, required, optional, children }: Props = $props();
15+
let { userEntitlements, required, optional, currentBankId, children }: Props =
16+
$props();
1517
1618
// Check required roles (OR logic — need at least one)
1719
let requiredCheck = $derived.by(() => {
18-
return checkRoles(userEntitlements || [], required || []);
20+
return checkRoles(userEntitlements || [], required || [], currentBankId);
1921
});
2022
2123
let firstMissingRequired = $derived(requiredCheck.missingRoles[0] || null);
@@ -24,7 +26,7 @@
2426
// Check optional roles (informational — content still renders)
2527
let optionalCheck = $derived.by(() => {
2628
if (!optional || optional.length === 0) return null;
27-
return checkRoles(userEntitlements || [], optional);
29+
return checkRoles(userEntitlements || [], optional, currentBankId);
2830
});
2931
3032
let missingOptionalRoles = $derived(

src/lib/config/navigation.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
Banknote,
3232
Hash,
3333
Map,
34+
Radio,
3435
} from "@lucide/svelte";
3536
import { env } from "$env/dynamic/public";
3637

@@ -122,6 +123,16 @@ function buildSystemItems(): NavigationItem[] {
122123
label: "Migrations",
123124
iconComponent: GitBranch,
124125
},
126+
{
127+
href: "/system/signal-channels",
128+
label: "Signal Channels",
129+
iconComponent: Radio,
130+
},
131+
{
132+
href: "/system/signal-channels-stats",
133+
label: "Signal Stats",
134+
iconComponent: Radio,
135+
},
125136
{
126137
href: "/system/webui-props",
127138
label: "WebUI Props",
@@ -297,6 +308,11 @@ function buildAccountAccessItems(): NavigationItem[] {
297308
label: "Accounts",
298309
iconComponent: Landmark,
299310
},
311+
{
312+
href: "/account-access/account-directory",
313+
label: "Account Directory",
314+
iconComponent: FolderOpen,
315+
},
300316
];
301317

302318
return items;

src/lib/utils/roleChecker.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const logger = createLogger("RoleChecker");
77
export interface RoleRequirement {
88
role: string;
99
bankId?: string;
10+
/** When true, the user must hold this role for the current bank (bank-level role) */
11+
bankScoped?: boolean;
1012
}
1113

1214
/**
@@ -111,6 +113,12 @@ export const SITE_MAP: Record<string, PageRoleConfig> = {
111113
"/system/webui-props/[id]/delete": {
112114
required: [{ role: "CanDeleteWebUiProps" }],
113115
},
116+
"/system/signal-channels": {
117+
required: [],
118+
},
119+
"/system/signal-channels-stats": {
120+
required: [{ role: "CanGetSignalStats" }],
121+
},
114122
"/system/featured-collections": {
115123
required: [{ role: "CanManageFeaturedApiCollections" }],
116124
},
@@ -179,6 +187,9 @@ export const SITE_MAP: Record<string, PageRoleConfig> = {
179187
"/account-access/custom-views/create": {
180188
required: [{ role: "CanCreateCustomView" }],
181189
},
190+
"/account-access/account-directory": {
191+
required: [{ role: "CanGetAccountDirectoryAtOneBank", bankScoped: true }],
192+
},
182193

183194
// ── Users ─────────────────────────────────────────────
184195
"/users": {
@@ -214,11 +225,13 @@ export function getPageRoles(routeId: string): PageRoleConfig | undefined {
214225
*
215226
* @param userEntitlements - List of entitlements the user has
216227
* @param requiredRoles - List of alternative roles (user needs at least one)
228+
* @param currentBankId - The currently selected bank ID (for bankScoped role checks)
217229
* @returns RoleCheckResult with missing and present roles
218230
*/
219231
export function checkRoles(
220232
userEntitlements: UserEntitlement[],
221233
requiredRoles: RoleRequirement[],
234+
currentBankId?: string,
222235
): RoleCheckResult {
223236
const missingRoles: RoleRequirement[] = [];
224237
const hasRoles: RoleRequirement[] = [];
@@ -229,6 +242,11 @@ export function checkRoles(
229242

230243
if (!roleMatches) return false;
231244

245+
// Bank-scoped roles must match the current bank
246+
if (requirement.bankScoped) {
247+
return currentBankId ? entitlement.bank_id === currentBankId : false;
248+
}
249+
232250
if (requirement.bankId) {
233251
return entitlement.bank_id === requirement.bankId;
234252
}

src/routes/(protected)/+layout.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { page } from "$app/state";
33
import PageRoleCheck from "$lib/components/PageRoleCheck.svelte";
44
import { SITE_MAP } from "$lib/utils/roleChecker";
5+
import { currentBank } from "$lib/stores/currentBank.svelte";
56
67
let { data, children } = $props();
78
@@ -14,6 +15,7 @@
1415
userEntitlements={data.userEntitlements}
1516
required={pageRoles.required}
1617
optional={pageRoles.optional}
18+
currentBankId={currentBank.bankId}
1719
>
1820
{@render children()}
1921
</PageRoleCheck>

0 commit comments

Comments
 (0)