@geoly-ai/social-hub-authz 0.0.1

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,116 @@
1
+ export type Role = "internal" | "senior" | "supervisor" | "manager" | "client" | "admin";
2
+ export type Resource = "brand" | "campaign" | "socialAccount" | "task" | "publishingPlan" | "contentDraft" | "report" | "dashboardSummary" | "opReport" | "postSnapshot" | "postSnapshotStats" | "postSnapshotRefresh" | "postSnapshotImport" | "apiKey" | "cliAuthorization" | "cliTokenDuration" | "auditLog" | "compliance" | "subredditIntelligence" | "member" | "systemMember" | "systemBrand" | "systemCampaign" | "invite" | "systemSetting" | "permissionMatrix" | "agentTeam" | "notificationChannel" | "browserEnvironment" | "brandMember" | "campaignAccount";
3
+ export type Action = "list" | "read" | "create" | "update" | "delete" | "retry" | "cancel" | "export";
4
+ export type PermissionMatrix = Record<Role, Record<Resource, Record<Action, boolean>>>;
5
+ export declare const ROLE_VALUES: Role[];
6
+ export declare const RESOURCE_VALUES: Resource[];
7
+ export declare const ACTION_VALUES: Action[];
8
+ export type FieldMaskMode = "omit" | "null" | "redact" | "aggregateOnly";
9
+ export type FieldPolicy = {
10
+ resource: "postSnapshot" | "socialAccount" | "opReport";
11
+ field: string;
12
+ readable: boolean;
13
+ editable: boolean;
14
+ mask?: FieldMaskMode;
15
+ };
16
+ export type ResolvedAccessContext = {
17
+ role: Role;
18
+ teamIds: string[];
19
+ brandIds: string[];
20
+ campaignIds: string[];
21
+ accountIds: string[];
22
+ hasAllCampaignAccess: boolean;
23
+ };
24
+ /**
25
+ * ApiKey 绑定的 team 必须与 URL 路径中的 :teamId 一致(主规格多租户)。
26
+ */
27
+ export declare function assertTeamAccess(apiKeyTeamId: string, pathTeamId: string): void;
28
+ export declare function assertAnyTeamAccess(input: {
29
+ role?: Role;
30
+ primaryTeamId: string;
31
+ visibleTeamIds?: string[];
32
+ pathTeamId: string;
33
+ }): void;
34
+ /** Session: path :teamId must match primary team or any visibleTeamIds. API key: path must match bound team only. */
35
+ export declare function assertTeamPathForContext(ctx: {
36
+ kind: "api_key" | "session" | "cli_token";
37
+ teamId: string;
38
+ role?: Role;
39
+ visibleTeamIds?: string[];
40
+ }, pathTeamId: string): void;
41
+ export declare function assertCanPerformAction(input: {
42
+ role: Role;
43
+ resource: Resource;
44
+ action: Action;
45
+ }): void;
46
+ export declare function canPerformResolvedAction(input: {
47
+ matrix: PermissionMatrix;
48
+ role: Role;
49
+ resource: Resource;
50
+ action: Action;
51
+ }): boolean;
52
+ export declare function assertResolvedAction(input: {
53
+ matrix: PermissionMatrix;
54
+ role: Role;
55
+ resource: Resource;
56
+ action: Action;
57
+ }): void;
58
+ export declare function filterCampaignsByVisibility<T extends {
59
+ id: string;
60
+ }>(campaigns: T[], visibleCampaignIds: string[] | null | undefined): T[];
61
+ export declare function canPerformAction(input: {
62
+ role: Role;
63
+ resource: Resource;
64
+ action: Action;
65
+ }): boolean;
66
+ export declare function hasScope(scopes: string[], required: string): boolean;
67
+ export declare function buildPermissionMatrix(input?: {
68
+ roles?: Role[];
69
+ }): PermissionMatrix;
70
+ /** Canonical `campaign_accounts.visibility` for client-facing joins (matches DB default). */
71
+ export declare const CLIENT_VISIBLE_CAMPAIGN_ACCOUNT: "client_visible";
72
+ /**
73
+ * Canonical section registry shared by navigation derivation logic.
74
+ */
75
+ export type NavSectionRegistryEntry = {
76
+ id: string;
77
+ roles?: Role[];
78
+ selfService?: boolean;
79
+ gate?: {
80
+ resource: Resource;
81
+ action: Action;
82
+ };
83
+ };
84
+ export declare const NAV_SECTION_REGISTRY: readonly NavSectionRegistryEntry[];
85
+ /**
86
+ * Base navigation list by role. UI can further trim entries using
87
+ * `navigationAllowanceFromMatrix`, and should always keep self-service pages.
88
+ */
89
+ export declare const NAV_BASE_SECTIONS_BY_ROLE: Record<Role, string[]>;
90
+ export declare const NAV_SELF_SERVICE_SECTIONS: string[];
91
+ /**
92
+ * Sidebar section → resolved matrix gate. Sections omitted here stay visible unless the base role list excludes them.
93
+ */
94
+ export declare const NAV_SECTION_MATRIX_GATES: Partial<Record<string, {
95
+ resource: Resource;
96
+ action: Action;
97
+ }>>;
98
+ /** Keyed by sidebar section id; used to hide nav entries when runtime matrix denies the gate. */
99
+ export declare function navigationAllowanceFromMatrix(matrix: PermissionMatrix, role: Role): Record<string, boolean>;
100
+ export declare function permissionKey(resource: Resource, action: Action): string;
101
+ /** Flat `resource.action` flags for fine-grained UI gates (brands page, intelligence account ops). */
102
+ export declare function permissionAllowanceFromMatrix(matrix: PermissionMatrix, role: Role): Record<string, boolean>;
103
+ export declare function resolveAccessContext(input: {
104
+ role: Role;
105
+ primaryTeamId: string;
106
+ visibleTeamIds?: string[];
107
+ visibleBrandIds?: string[];
108
+ visibleCampaignIds?: string[] | null;
109
+ visibleAccountIds?: string[];
110
+ }): ResolvedAccessContext;
111
+ export declare function getFieldPolicy(input: {
112
+ role: Role;
113
+ resource: FieldPolicy["resource"];
114
+ field: string;
115
+ }): FieldPolicy | null;
116
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,466 @@
1
+ import { forbidden } from "@geoly-ai/social-hub-core";
2
+ export const ROLE_VALUES = [
3
+ "internal",
4
+ "senior",
5
+ "supervisor",
6
+ "manager",
7
+ "client",
8
+ "admin",
9
+ ];
10
+ export const RESOURCE_VALUES = [
11
+ "brand",
12
+ "campaign",
13
+ "socialAccount",
14
+ "task",
15
+ "publishingPlan",
16
+ "contentDraft",
17
+ "report",
18
+ "dashboardSummary",
19
+ "opReport",
20
+ "postSnapshot",
21
+ "postSnapshotStats",
22
+ "postSnapshotRefresh",
23
+ "postSnapshotImport",
24
+ "apiKey",
25
+ "cliAuthorization",
26
+ "cliTokenDuration",
27
+ "auditLog",
28
+ "compliance",
29
+ "subredditIntelligence",
30
+ "member",
31
+ "systemMember",
32
+ "systemBrand",
33
+ "systemCampaign",
34
+ "invite",
35
+ "systemSetting",
36
+ "permissionMatrix",
37
+ "agentTeam",
38
+ "notificationChannel",
39
+ "browserEnvironment",
40
+ "brandMember",
41
+ "campaignAccount",
42
+ ];
43
+ export const ACTION_VALUES = [
44
+ "list",
45
+ "read",
46
+ "create",
47
+ "update",
48
+ "delete",
49
+ "retry",
50
+ "cancel",
51
+ "export",
52
+ ];
53
+ const readActions = new Set(["list", "read"]);
54
+ const operationalWriteActions = new Set([
55
+ "create",
56
+ "update",
57
+ "retry",
58
+ "cancel",
59
+ "export",
60
+ ]);
61
+ const clientReadableResources = new Set([
62
+ "brand",
63
+ "campaign",
64
+ "socialAccount",
65
+ "report",
66
+ "dashboardSummary",
67
+ "opReport",
68
+ "postSnapshot",
69
+ "postSnapshotStats",
70
+ ]);
71
+ const POST_SNAPSHOT_ACCOUNT_TYPE_POLICY_BY_ROLE = {
72
+ admin: {
73
+ resource: "postSnapshot",
74
+ field: "accountType",
75
+ readable: true,
76
+ editable: true,
77
+ },
78
+ manager: {
79
+ resource: "postSnapshot",
80
+ field: "accountType",
81
+ readable: true,
82
+ editable: true,
83
+ },
84
+ supervisor: {
85
+ resource: "postSnapshot",
86
+ field: "accountType",
87
+ readable: true,
88
+ editable: true,
89
+ },
90
+ senior: {
91
+ resource: "postSnapshot",
92
+ field: "accountType",
93
+ readable: true,
94
+ editable: true,
95
+ },
96
+ internal: {
97
+ resource: "postSnapshot",
98
+ field: "accountType",
99
+ readable: true,
100
+ editable: true,
101
+ },
102
+ client: {
103
+ resource: "postSnapshot",
104
+ field: "accountType",
105
+ readable: false,
106
+ editable: false,
107
+ mask: "omit",
108
+ },
109
+ };
110
+ /**
111
+ * ApiKey 绑定的 team 必须与 URL 路径中的 :teamId 一致(主规格多租户)。
112
+ */
113
+ export function assertTeamAccess(apiKeyTeamId, pathTeamId) {
114
+ if (apiKeyTeamId !== pathTeamId) {
115
+ throw forbidden("Team scope mismatch");
116
+ }
117
+ }
118
+ export function assertAnyTeamAccess(input) {
119
+ if (input.role === "admin")
120
+ return;
121
+ if (input.primaryTeamId === input.pathTeamId)
122
+ return;
123
+ if (input.visibleTeamIds?.includes(input.pathTeamId))
124
+ return;
125
+ throw forbidden("Team scope mismatch");
126
+ }
127
+ /** Session: path :teamId must match primary team or any visibleTeamIds. API key: path must match bound team only. */
128
+ export function assertTeamPathForContext(ctx, pathTeamId) {
129
+ if (ctx.kind === "api_key") {
130
+ assertTeamAccess(ctx.teamId, pathTeamId);
131
+ return;
132
+ }
133
+ assertAnyTeamAccess({
134
+ role: ctx.role,
135
+ primaryTeamId: ctx.teamId,
136
+ visibleTeamIds: ctx.visibleTeamIds,
137
+ pathTeamId,
138
+ });
139
+ }
140
+ export function assertCanPerformAction(input) {
141
+ if (!canPerformAction(input)) {
142
+ throw forbidden(`Role ${input.role} cannot ${input.action} ${input.resource}`);
143
+ }
144
+ }
145
+ export function canPerformResolvedAction(input) {
146
+ return input.matrix[input.role]?.[input.resource]?.[input.action] === true;
147
+ }
148
+ export function assertResolvedAction(input) {
149
+ if (!canPerformResolvedAction(input)) {
150
+ throw forbidden(`Role ${input.role} cannot ${input.action} ${input.resource}`);
151
+ }
152
+ }
153
+ export function filterCampaignsByVisibility(campaigns, visibleCampaignIds) {
154
+ // null/undefined means no visibility filter; empty array means no access.
155
+ if (visibleCampaignIds == null) {
156
+ return campaigns;
157
+ }
158
+ if (visibleCampaignIds.length === 0)
159
+ return [];
160
+ const allowed = new Set(visibleCampaignIds);
161
+ return campaigns.filter((campaign) => allowed.has(campaign.id));
162
+ }
163
+ export function canPerformAction(input) {
164
+ if (input.role === "admin")
165
+ return true;
166
+ if (input.resource === "dashboardSummary") {
167
+ return canPerformAction({
168
+ role: input.role,
169
+ resource: "report",
170
+ action: "list",
171
+ });
172
+ }
173
+ if (input.resource === "opReport") {
174
+ return canPerformAction({
175
+ role: input.role,
176
+ resource: "report",
177
+ action: input.action,
178
+ });
179
+ }
180
+ if (input.resource === "postSnapshot") {
181
+ return canPerformAction({
182
+ role: input.role,
183
+ resource: "report",
184
+ action: input.action,
185
+ });
186
+ }
187
+ if (input.resource === "postSnapshotStats") {
188
+ return canPerformAction({
189
+ role: input.role,
190
+ resource: "report",
191
+ action: "read",
192
+ });
193
+ }
194
+ if (input.resource === "postSnapshotRefresh") {
195
+ return canPerformAction({
196
+ role: input.role,
197
+ resource: "report",
198
+ action: "create",
199
+ });
200
+ }
201
+ if (input.resource === "postSnapshotImport") {
202
+ return canPerformAction({
203
+ role: input.role,
204
+ resource: "report",
205
+ action: "create",
206
+ });
207
+ }
208
+ if (input.resource === "systemMember") {
209
+ return canPerformAction({
210
+ role: input.role,
211
+ resource: "member",
212
+ action: input.action,
213
+ });
214
+ }
215
+ if (input.resource === "systemBrand") {
216
+ return canPerformAction({
217
+ role: input.role,
218
+ resource: "brand",
219
+ action: input.action,
220
+ });
221
+ }
222
+ if (input.resource === "systemCampaign") {
223
+ return canPerformAction({
224
+ role: input.role,
225
+ resource: "campaign",
226
+ action: input.action,
227
+ });
228
+ }
229
+ if (input.resource === "systemSetting") {
230
+ if (input.role === "manager") {
231
+ return input.action === "list" || input.action === "read";
232
+ }
233
+ return false;
234
+ }
235
+ if (input.resource === "permissionMatrix") {
236
+ if (input.role === "manager") {
237
+ return readActions.has(input.action);
238
+ }
239
+ return false;
240
+ }
241
+ if (input.resource === "agentTeam") {
242
+ if (input.role === "manager") {
243
+ return readActions.has(input.action);
244
+ }
245
+ return false;
246
+ }
247
+ if (input.resource === "notificationChannel") {
248
+ return canPerformAction({
249
+ role: input.role,
250
+ resource: "task",
251
+ action: input.action,
252
+ });
253
+ }
254
+ if (input.resource === "browserEnvironment") {
255
+ return canPerformAction({
256
+ role: input.role,
257
+ resource: "compliance",
258
+ action: input.action,
259
+ });
260
+ }
261
+ if (input.resource === "brandMember") {
262
+ return canPerformAction({
263
+ role: input.role,
264
+ resource: "brand",
265
+ action: input.action,
266
+ });
267
+ }
268
+ if (input.resource === "campaignAccount") {
269
+ return canPerformAction({
270
+ role: input.role,
271
+ resource: "systemCampaign",
272
+ action: input.action,
273
+ });
274
+ }
275
+ if (input.resource === "compliance") {
276
+ if (input.role === "client")
277
+ return false;
278
+ if (input.role === "manager")
279
+ return true;
280
+ if (input.role === "supervisor") {
281
+ return (readActions.has(input.action) ||
282
+ input.action === "create" ||
283
+ input.action === "update");
284
+ }
285
+ if (input.role === "senior")
286
+ return readActions.has(input.action);
287
+ return readActions.has(input.action);
288
+ }
289
+ if (input.role === "client") {
290
+ return (readActions.has(input.action) &&
291
+ clientReadableResources.has(input.resource));
292
+ }
293
+ if (input.resource === "auditLog")
294
+ return false;
295
+ if (input.resource === "apiKey") {
296
+ if (input.role === "manager")
297
+ return true;
298
+ return false;
299
+ }
300
+ if (input.resource === "cliAuthorization") {
301
+ if (input.role === "manager") {
302
+ return (input.action === "create" ||
303
+ input.action === "read" ||
304
+ input.action === "delete");
305
+ }
306
+ return false;
307
+ }
308
+ if (input.resource === "cliTokenDuration") {
309
+ return false;
310
+ }
311
+ if (input.role === "manager")
312
+ return true;
313
+ // member: supervisor=list|read|update; senior/internal=list|read; client=none (above)
314
+ if (input.resource === "member") {
315
+ if (input.role === "supervisor") {
316
+ return (input.action === "list" ||
317
+ input.action === "read" ||
318
+ input.action === "update");
319
+ }
320
+ return input.action === "list" || input.action === "read";
321
+ }
322
+ // invite: supervisor=list|create; others=none
323
+ if (input.resource === "invite") {
324
+ if (input.role === "supervisor") {
325
+ return input.action === "list" || input.action === "create";
326
+ }
327
+ return false;
328
+ }
329
+ if (input.role === "supervisor") {
330
+ return (readActions.has(input.action) || operationalWriteActions.has(input.action));
331
+ }
332
+ if (input.role === "senior") {
333
+ return (readActions.has(input.action) ||
334
+ (input.resource === "task" &&
335
+ operationalWriteActions.has(input.action)) ||
336
+ (input.resource === "contentDraft" && input.action === "update"));
337
+ }
338
+ return (readActions.has(input.action) ||
339
+ (input.resource === "task" && ["update", "retry"].includes(input.action)));
340
+ }
341
+ export function hasScope(scopes, required) {
342
+ if (scopes.includes(required) || scopes.includes("*"))
343
+ return true;
344
+ const [namespace] = required.split(":");
345
+ return scopes.includes(`${namespace}:*`);
346
+ }
347
+ export function buildPermissionMatrix(input) {
348
+ const roles = input?.roles ?? ROLE_VALUES;
349
+ const matrix = {};
350
+ for (const role of roles) {
351
+ matrix[role] = {};
352
+ for (const resource of RESOURCE_VALUES) {
353
+ matrix[role][resource] = {};
354
+ for (const action of ACTION_VALUES) {
355
+ matrix[role][resource][action] = canPerformAction({
356
+ role,
357
+ resource,
358
+ action,
359
+ });
360
+ }
361
+ }
362
+ }
363
+ return matrix;
364
+ }
365
+ /** Canonical `campaign_accounts.visibility` for client-facing joins (matches DB default). */
366
+ export const CLIENT_VISIBLE_CAMPAIGN_ACCOUNT = "client_visible";
367
+ export const NAV_SECTION_REGISTRY = [
368
+ { id: "dashboard", gate: { resource: "dashboardSummary", action: "list" } },
369
+ { id: "today", gate: { resource: "publishingPlan", action: "list" } },
370
+ { id: "accounts", gate: { resource: "socialAccount", action: "list" } },
371
+ { id: "graph", gate: { resource: "socialAccount", action: "list" } },
372
+ { id: "brands", gate: { resource: "systemBrand", action: "list" } },
373
+ { id: "calendar", gate: { resource: "publishingPlan", action: "list" } },
374
+ { id: "drafts", gate: { resource: "contentDraft", action: "list" } },
375
+ { id: "plans", gate: { resource: "publishingPlan", action: "list" } },
376
+ { id: "tasks", gate: { resource: "task", action: "list" } },
377
+ { id: "intelligence", gate: { resource: "subredditIntelligence", action: "read" } },
378
+ { id: "intelligenceTasks", gate: { resource: "subredditIntelligence", action: "read" } },
379
+ { id: "events", gate: { resource: "task", action: "list" } },
380
+ { id: "reports", gate: { resource: "opReport", action: "list" } },
381
+ { id: "postPerformance", gate: { resource: "postSnapshot", action: "list" } },
382
+ { id: "riskCenter", gate: { resource: "compliance", action: "list" } },
383
+ { id: "apiKeys", gate: { resource: "apiKey", action: "list" } },
384
+ { id: "users", gate: { resource: "systemMember", action: "list" } },
385
+ { id: "auditLogs", gate: { resource: "auditLog", action: "list" } },
386
+ { id: "permissions", gate: { resource: "permissionMatrix", action: "read" } },
387
+ { id: "systemSettings", gate: { resource: "systemSetting", action: "list" } },
388
+ { id: "agentTeams", gate: { resource: "agentTeam", action: "list" } },
389
+ { id: "members", gate: { resource: "systemMember", action: "list" } },
390
+ { id: "profile", selfService: true },
391
+ ];
392
+ /**
393
+ * Base navigation list by role. UI can further trim entries using
394
+ * `navigationAllowanceFromMatrix`, and should always keep self-service pages.
395
+ */
396
+ export const NAV_BASE_SECTIONS_BY_ROLE = ROLE_VALUES.reduce((acc, role) => {
397
+ acc[role] = NAV_SECTION_REGISTRY.filter((entry) => entry.selfService === true ||
398
+ entry.roles === undefined ||
399
+ entry.roles.includes(role)).map((entry) => entry.id);
400
+ return acc;
401
+ }, {});
402
+ export const NAV_SELF_SERVICE_SECTIONS = NAV_SECTION_REGISTRY.filter((entry) => entry.selfService).map((entry) => entry.id);
403
+ /**
404
+ * Sidebar section → resolved matrix gate. Sections omitted here stay visible unless the base role list excludes them.
405
+ */
406
+ export const NAV_SECTION_MATRIX_GATES = Object.fromEntries(NAV_SECTION_REGISTRY.filter((entry) => entry.gate).map((entry) => [
407
+ entry.id,
408
+ entry.gate,
409
+ ]));
410
+ /** Keyed by sidebar section id; used to hide nav entries when runtime matrix denies the gate. */
411
+ export function navigationAllowanceFromMatrix(matrix, role) {
412
+ const out = {};
413
+ for (const [section, gate] of Object.entries(NAV_SECTION_MATRIX_GATES)) {
414
+ if (!gate)
415
+ continue;
416
+ out[section] = canPerformResolvedAction({
417
+ matrix,
418
+ role,
419
+ resource: gate.resource,
420
+ action: gate.action,
421
+ });
422
+ }
423
+ return out;
424
+ }
425
+ export function permissionKey(resource, action) {
426
+ return `${resource}.${action}`;
427
+ }
428
+ /** Flat `resource.action` flags for fine-grained UI gates (brands page, intelligence account ops). */
429
+ export function permissionAllowanceFromMatrix(matrix, role) {
430
+ const out = {};
431
+ for (const resource of RESOURCE_VALUES) {
432
+ for (const action of ACTION_VALUES) {
433
+ out[permissionKey(resource, action)] = canPerformResolvedAction({
434
+ matrix,
435
+ role,
436
+ resource,
437
+ action,
438
+ });
439
+ }
440
+ }
441
+ return out;
442
+ }
443
+ export function resolveAccessContext(input) {
444
+ const teamIds = Array.from(new Set([input.primaryTeamId, ...(input.visibleTeamIds ?? [])]));
445
+ const brandIds = Array.from(new Set(input.visibleBrandIds ?? []));
446
+ const accountIds = Array.from(new Set(input.visibleAccountIds ?? []));
447
+ const campaignIds = input.visibleCampaignIds && input.visibleCampaignIds.length > 0
448
+ ? Array.from(new Set(input.visibleCampaignIds))
449
+ : [];
450
+ const hasAllCampaignAccess = input.role !== "client" && input.visibleCampaignIds == null;
451
+ return {
452
+ role: input.role,
453
+ teamIds,
454
+ brandIds,
455
+ campaignIds,
456
+ accountIds,
457
+ hasAllCampaignAccess,
458
+ };
459
+ }
460
+ export function getFieldPolicy(input) {
461
+ if (input.resource === "postSnapshot" && input.field === "accountType") {
462
+ return POST_SNAPSHOT_ACCOUNT_TYPE_POLICY_BY_ROLE[input.role];
463
+ }
464
+ return null;
465
+ }
466
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,300 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { ACTION_VALUES, NAV_SECTION_MATRIX_GATES, NAV_SECTION_REGISTRY, NAV_SELF_SERVICE_SECTIONS, RESOURCE_VALUES, ROLE_VALUES, assertCanPerformAction, assertResolvedAction, assertTeamAccess, assertTeamPathForContext, buildPermissionMatrix, canPerformAction, canPerformResolvedAction, filterCampaignsByVisibility, getFieldPolicy, hasScope, navigationAllowanceFromMatrix, permissionAllowanceFromMatrix, permissionKey, resolveAccessContext, } from "./index.js";
3
+ describe("assertTeamAccess", () => {
4
+ it("allows same team", () => {
5
+ expect(() => assertTeamAccess("t1", "t1")).not.toThrow();
6
+ });
7
+ it("rejects cross-team", () => {
8
+ expect(() => assertTeamAccess("t1", "t2")).toThrow();
9
+ });
10
+ });
11
+ describe("canPerformAction", () => {
12
+ it("allows admin to read audit logs", () => {
13
+ expect(canPerformAction({ role: "admin", resource: "auditLog", action: "read" })).toBe(true);
14
+ });
15
+ it("allows manager to manage API keys", () => {
16
+ expect(canPerformAction({
17
+ role: "manager",
18
+ resource: "apiKey",
19
+ action: "create",
20
+ })).toBe(true);
21
+ });
22
+ it("allows admin and manager to approve CLI device auth", () => {
23
+ expect(canPerformAction({
24
+ role: "admin",
25
+ resource: "cliAuthorization",
26
+ action: "create",
27
+ })).toBe(true);
28
+ expect(canPerformAction({
29
+ role: "manager",
30
+ resource: "cliAuthorization",
31
+ action: "create",
32
+ })).toBe(true);
33
+ expect(canPerformAction({
34
+ role: "supervisor",
35
+ resource: "cliAuthorization",
36
+ action: "create",
37
+ })).toBe(false);
38
+ });
39
+ it("allows only admin to choose non-short CLI token duration", () => {
40
+ expect(canPerformAction({
41
+ role: "admin",
42
+ resource: "cliTokenDuration",
43
+ action: "update",
44
+ })).toBe(true);
45
+ expect(canPerformAction({
46
+ role: "manager",
47
+ resource: "cliTokenDuration",
48
+ action: "update",
49
+ })).toBe(false);
50
+ });
51
+ it("rejects client writes to publishing plans", () => {
52
+ expect(canPerformAction({
53
+ role: "client",
54
+ resource: "publishingPlan",
55
+ action: "update",
56
+ })).toBe(false);
57
+ });
58
+ it("rejects client compliance reads", () => {
59
+ expect(canPerformAction({
60
+ role: "client",
61
+ resource: "compliance",
62
+ action: "list",
63
+ })).toBe(false);
64
+ });
65
+ it("rejects client reads for internal operations resources", () => {
66
+ expect(canPerformAction({ role: "client", resource: "task", action: "list" })).toBe(false);
67
+ expect(canPerformAction({
68
+ role: "client",
69
+ resource: "contentDraft",
70
+ action: "list",
71
+ })).toBe(false);
72
+ expect(canPerformAction({
73
+ role: "client",
74
+ resource: "publishingPlan",
75
+ action: "list",
76
+ })).toBe(false);
77
+ });
78
+ it("allows supervisor compliance create", () => {
79
+ expect(canPerformAction({
80
+ role: "supervisor",
81
+ resource: "compliance",
82
+ action: "create",
83
+ })).toBe(true);
84
+ });
85
+ });
86
+ describe("assertCanPerformAction", () => {
87
+ it("throws for disallowed action", () => {
88
+ expect(() => assertCanPerformAction({
89
+ role: "client",
90
+ resource: "campaign",
91
+ action: "create",
92
+ })).toThrow();
93
+ });
94
+ });
95
+ describe("canPerformResolvedAction", () => {
96
+ it("uses resolved matrix values instead of default role rules", () => {
97
+ const matrix = buildPermissionMatrix();
98
+ matrix.manager.apiKey.list = false;
99
+ expect(canPerformAction({ role: "manager", resource: "apiKey", action: "list" })).toBe(true);
100
+ expect(canPerformResolvedAction({
101
+ matrix,
102
+ role: "manager",
103
+ resource: "apiKey",
104
+ action: "list",
105
+ })).toBe(false);
106
+ });
107
+ it("throws when resolved matrix denies an action", () => {
108
+ const matrix = buildPermissionMatrix();
109
+ matrix.manager.report.create = false;
110
+ expect(() => assertResolvedAction({
111
+ matrix,
112
+ role: "manager",
113
+ resource: "report",
114
+ action: "create",
115
+ })).toThrow();
116
+ });
117
+ });
118
+ describe("filterCampaignsByVisibility", () => {
119
+ it("filters campaigns by provided ids", () => {
120
+ const rows = [
121
+ { id: "c1", name: "A" },
122
+ { id: "c2", name: "B" },
123
+ ];
124
+ expect(filterCampaignsByVisibility(rows, ["c2"])).toEqual([
125
+ { id: "c2", name: "B" },
126
+ ]);
127
+ });
128
+ it("returns all campaigns when visibility is null/undefined", () => {
129
+ const rows = [
130
+ { id: "c1", name: "A" },
131
+ { id: "c2", name: "B" },
132
+ ];
133
+ expect(filterCampaignsByVisibility(rows, null)).toEqual(rows);
134
+ expect(filterCampaignsByVisibility(rows, undefined)).toEqual(rows);
135
+ });
136
+ it("returns empty list when visible ids is empty array", () => {
137
+ const rows = [
138
+ { id: "c1", name: "A" },
139
+ { id: "c2", name: "B" },
140
+ ];
141
+ expect(filterCampaignsByVisibility(rows, [])).toEqual([]);
142
+ });
143
+ });
144
+ describe("hasScope", () => {
145
+ it("accepts exact scopes", () => {
146
+ expect(hasScope(["events:write"], "events:write")).toBe(true);
147
+ });
148
+ it("accepts wildcard scopes", () => {
149
+ expect(hasScope(["events:*"], "events:write")).toBe(true);
150
+ });
151
+ it("rejects missing scopes", () => {
152
+ expect(hasScope(["events:read"], "events:write")).toBe(false);
153
+ });
154
+ });
155
+ describe("assertTeamPathForContext", () => {
156
+ it("allows session primary team", () => {
157
+ expect(() => assertTeamPathForContext({
158
+ kind: "session",
159
+ teamId: "t1",
160
+ role: "manager",
161
+ visibleTeamIds: ["t2"],
162
+ }, "t1")).not.toThrow();
163
+ });
164
+ it("allows session when path team is in visibleTeamIds", () => {
165
+ expect(() => assertTeamPathForContext({
166
+ kind: "session",
167
+ teamId: "t1",
168
+ role: "senior",
169
+ visibleTeamIds: ["t1", "t2"],
170
+ }, "t2")).not.toThrow();
171
+ });
172
+ it("rejects session path outside visible teams", () => {
173
+ expect(() => assertTeamPathForContext({
174
+ kind: "session",
175
+ teamId: "t1",
176
+ role: "senior",
177
+ visibleTeamIds: ["t1"],
178
+ }, "t2")).toThrow();
179
+ });
180
+ it("requires api key team to match path", () => {
181
+ expect(() => assertTeamPathForContext({ kind: "api_key", teamId: "t1" }, "t1")).not.toThrow();
182
+ expect(() => assertTeamPathForContext({ kind: "api_key", teamId: "t1" }, "t2")).toThrow();
183
+ });
184
+ it("does not allow admin api key to cross teams", () => {
185
+ expect(() => assertTeamPathForContext({ kind: "api_key", teamId: "t1", role: "admin" }, "t2")).toThrow();
186
+ });
187
+ });
188
+ describe("navigationAllowanceFromMatrix", () => {
189
+ it("derives section flags from resolved matrix", () => {
190
+ const matrix = buildPermissionMatrix();
191
+ matrix.manager.opReport.list = false;
192
+ const nav = navigationAllowanceFromMatrix(matrix, "manager");
193
+ expect(nav.reports).toBe(false);
194
+ expect(nav.brands).toBe(true);
195
+ });
196
+ it("gates brands nav with systemBrand:list", () => {
197
+ const matrix = buildPermissionMatrix();
198
+ matrix.manager.systemBrand.list = false;
199
+ matrix.manager.brand.list = true;
200
+ const nav = navigationAllowanceFromMatrix(matrix, "manager");
201
+ expect(nav.brands).toBe(false);
202
+ });
203
+ it("uses resolved read gate for intelligence visibility", () => {
204
+ const matrix = buildPermissionMatrix();
205
+ matrix.client.subredditIntelligence.read = true;
206
+ matrix.client.subredditIntelligence.list = false;
207
+ const allowed = navigationAllowanceFromMatrix(matrix, "client");
208
+ expect(allowed.intelligence).toBe(true);
209
+ matrix.client.subredditIntelligence.read = false;
210
+ const denied = navigationAllowanceFromMatrix(matrix, "client");
211
+ expect(denied.intelligence).toBe(false);
212
+ });
213
+ });
214
+ describe("permissionAllowanceFromMatrix", () => {
215
+ it("exposes flat resource.action keys", () => {
216
+ const matrix = buildPermissionMatrix();
217
+ matrix.manager.socialAccount.list = false;
218
+ const allowance = permissionAllowanceFromMatrix(matrix, "manager");
219
+ expect(allowance[permissionKey("socialAccount", "list")]).toBe(false);
220
+ expect(allowance[permissionKey("subredditIntelligence", "read")]).toBe(true);
221
+ });
222
+ });
223
+ describe("navigation registry invariants", () => {
224
+ it("keeps non self-service sections gated or role-restricted", () => {
225
+ const weaklyDefined = NAV_SECTION_REGISTRY.filter((entry) => entry.selfService !== true && !entry.gate && !entry.roles);
226
+ expect(weaklyDefined).toEqual([]);
227
+ });
228
+ it("ensures each gated section exists in matrix gates", () => {
229
+ const gatedIds = NAV_SECTION_REGISTRY.filter((entry) => entry.gate).map((entry) => entry.id);
230
+ for (const id of gatedIds) {
231
+ expect(NAV_SECTION_MATRIX_GATES[id]).toBeDefined();
232
+ }
233
+ });
234
+ it("allows manager to read systemSetting for refresh schedule", () => {
235
+ const matrix = buildPermissionMatrix();
236
+ expect(matrix.manager.systemSetting?.read).toBe(true);
237
+ expect(matrix.manager.systemSetting?.update).toBe(false);
238
+ });
239
+ it("gates systemSettings via systemSetting.list in matrix", () => {
240
+ expect(NAV_SECTION_MATRIX_GATES.systemSettings).toEqual({
241
+ resource: "systemSetting",
242
+ action: "list",
243
+ });
244
+ const matrix = buildPermissionMatrix();
245
+ expect(canPerformResolvedAction({
246
+ matrix,
247
+ role: "admin",
248
+ resource: "systemSetting",
249
+ action: "list",
250
+ })).toBe(true);
251
+ expect(canPerformResolvedAction({
252
+ matrix,
253
+ role: "client",
254
+ resource: "systemSetting",
255
+ action: "list",
256
+ })).toBe(false);
257
+ });
258
+ it("keeps self-service section list stable", () => {
259
+ expect(NAV_SELF_SERVICE_SECTIONS).toEqual(["profile"]);
260
+ });
261
+ });
262
+ describe("buildPermissionMatrix", () => {
263
+ it("builds matrix for all roles/resources/actions", () => {
264
+ const matrix = buildPermissionMatrix();
265
+ expect(Object.keys(matrix)).toHaveLength(ROLE_VALUES.length);
266
+ expect(Object.keys(matrix.admin)).toHaveLength(RESOURCE_VALUES.length);
267
+ expect(Object.keys(matrix.admin.brand)).toHaveLength(ACTION_VALUES.length);
268
+ expect(matrix.admin.auditLog.read).toBe(true);
269
+ expect(matrix.client.apiKey.list).toBe(false);
270
+ expect(matrix.client.compliance.list).toBe(false);
271
+ expect(matrix.manager.compliance.update).toBe(true);
272
+ expect(matrix.admin.cliAuthorization.create).toBe(true);
273
+ expect(matrix.manager.cliAuthorization.create).toBe(true);
274
+ expect(matrix.admin.cliTokenDuration.update).toBe(true);
275
+ expect(matrix.manager.cliTokenDuration.update).toBe(false);
276
+ });
277
+ });
278
+ describe("field policy", () => {
279
+ it("denies client accountType read on post snapshots", () => {
280
+ const policy = getFieldPolicy({
281
+ role: "client",
282
+ resource: "postSnapshot",
283
+ field: "accountType",
284
+ });
285
+ expect(policy?.readable).toBe(false);
286
+ expect(policy?.mask).toBe("omit");
287
+ });
288
+ });
289
+ describe("resolveAccessContext", () => {
290
+ it("treats client empty campaign list as restricted", () => {
291
+ const resolved = resolveAccessContext({
292
+ role: "client",
293
+ primaryTeamId: "t1",
294
+ visibleCampaignIds: null,
295
+ });
296
+ expect(resolved.campaignIds).toEqual([]);
297
+ expect(resolved.hasAllCampaignAccess).toBe(false);
298
+ });
299
+ });
300
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,aAAa,EAEb,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,eAAe,EACf,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,EACxB,2BAA2B,EAC3B,cAAc,EACd,QAAQ,EACR,6BAA6B,EAC7B,6BAA6B,EAC7B,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CACJ,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAC1E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,gBAAgB;YAC1B,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,YAAY;YACtB,MAAM,EAAE,MAAM;SACf,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CACJ,gBAAgB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CACvE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,cAAc;YACxB,MAAM,EAAE,MAAM;SACf,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,gBAAgB;YAC1B,MAAM,EAAE,MAAM;SACf,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CACJ,gBAAgB,CAAC;YACf,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,YAAY;YACtB,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,GAAG,EAAE,CACV,sBAAsB,CAAC;YACrB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,UAAU;YACpB,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,OAAO,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;QAEnC,MAAM,CACJ,gBAAgB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAC1E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,CACJ,wBAAwB,CAAC;YACvB,MAAM;YACN,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,MAAM;SACf,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;QAErC,MAAM,CAAC,GAAG,EAAE,CACV,oBAAoB,CAAC;YACnB,MAAM;YACN,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC,OAAO,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YACvB,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;SACxB,CAAC;QACF,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACxD,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;SACxB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YACvB,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;SACxB,CAAC;QACF,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9D,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YACvB,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;SACxB,CAAC;QACF,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,GAAG,EAAE,CACV,wBAAwB,CACtB;YACE,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,SAAS;YACf,cAAc,EAAE,CAAC,IAAI,CAAC;SACvB,EACD,IAAI,CACL,CACF,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,EAAE,CACV,wBAAwB,CACtB;YACE,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,QAAQ;YACd,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;SAC7B,EACD,IAAI,CACL,CACF,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,GAAG,EAAE,CACV,wBAAwB,CACtB;YACE,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,QAAQ;YACd,cAAc,EAAE,CAAC,IAAI,CAAC;SACvB,EACD,IAAI,CACL,CACF,CAAC,OAAO,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,GAAG,EAAE,CACV,wBAAwB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,CAClE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,EAAE,CACV,wBAAwB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,CAClE,CAAC,OAAO,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,GAAG,EAAE,CACV,wBAAwB,CACtB,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAChD,IAAI,CACL,CACF,CAAC,OAAO,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC;QACrC,MAAM,GAAG,GAAG,6BAA6B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,GAAG,KAAK,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;QACjC,MAAM,GAAG,GAAG,6BAA6B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,GAAG,IAAI,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,GAAG,KAAK,CAAC;QACjD,MAAM,OAAO,GAAG,6BAA6B,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAChE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAExC,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,GAAG,KAAK,CAAC;QACjD,MAAM,MAAM,GAAG,6BAA6B,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/D,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,KAAK,CAAC;QAC1C,MAAM,SAAS,GAAG,6BAA6B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACnE,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtE,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,aAAa,GAAG,oBAAoB,CAAC,MAAM,CAC/C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CACrE,CAAC;QACF,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CACrE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CACpB,CAAC;QACF,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;YACtD,QAAQ,EAAE,eAAe;YACzB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,wBAAwB,CAAC;YAC9B,MAAM;YACN,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,eAAe;YACzB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,MAAM,CAAC,wBAAwB,CAAC;YAC9B,MAAM;YACN,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,eAAe;YACzB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC3E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,cAAc,CAAC;YAC5B,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,cAAc;YACxB,KAAK,EAAE,aAAa;SACrB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,QAAQ,GAAG,oBAAoB,CAAC;YACpC,IAAI,EAAE,QAAQ;YACd,aAAa,EAAE,IAAI;YACnB,kBAAkB,EAAE,IAAI;SACzB,CAAC,CAAC;QACH,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@geoly-ai/social-hub-authz",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "description": "Runtime permission checks for Social Ops Hub",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/geoly-ai/geoly-reddit.git",
9
+ "directory": "packages/authz"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "main": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ }
24
+ },
25
+ "dependencies": {
26
+ "@geoly-ai/social-hub-core": "0.0.1"
27
+ },
28
+ "devDependencies": {
29
+ "typescript": "^5.7.2",
30
+ "vitest": "^2.1.8"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "typecheck": "tsc --noEmit",
35
+ "test": "vitest run"
36
+ }
37
+ }