@fuzdev/fuz_app 0.39.0 → 0.40.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.
- package/dist/auth/CLAUDE.md +89 -17
- package/dist/auth/account_actions.d.ts +5 -3
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +5 -6
- package/dist/auth/account_routes.d.ts.map +1 -1
- package/dist/auth/account_routes.js +7 -7
- package/dist/auth/admin_action_specs.d.ts +6 -138
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.js +4 -2
- package/dist/auth/admin_actions.d.ts +4 -3
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/admin_actions.js +8 -9
- package/dist/auth/audit_log_queries.d.ts +16 -6
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +7 -8
- package/dist/auth/audit_log_schema.d.ts +24 -74
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +17 -2
- package/dist/auth/bootstrap_routes.d.ts.map +1 -1
- package/dist/auth/bootstrap_routes.js +3 -3
- package/dist/auth/cleanup.d.ts +9 -1
- package/dist/auth/cleanup.d.ts.map +1 -1
- package/dist/auth/cleanup.js +2 -2
- package/dist/auth/deps.d.ts +13 -1
- package/dist/auth/deps.d.ts.map +1 -1
- package/dist/auth/permit_offer_actions.d.ts +16 -2
- package/dist/auth/permit_offer_actions.d.ts.map +1 -1
- package/dist/auth/permit_offer_actions.js +26 -8
- package/dist/auth/self_service_role_actions.d.ts +136 -0
- package/dist/auth/self_service_role_actions.d.ts.map +1 -0
- package/dist/auth/self_service_role_actions.js +198 -0
- package/dist/auth/signup_routes.d.ts.map +1 -1
- package/dist/auth/signup_routes.js +2 -2
- package/dist/auth/standard_rpc_actions.d.ts +1 -1
- package/dist/auth/standard_rpc_actions.js +1 -1
- package/dist/server/app_backend.d.ts +9 -1
- package/dist/server/app_backend.d.ts.map +1 -1
- package/dist/server/app_backend.js +12 -1
- package/dist/ui/ui_format.d.ts +2 -3
- package/dist/ui/ui_format.d.ts.map +1 -1
- package/dist/ui/ui_format.js +1 -1
- package/package.json +1 -1
|
@@ -43,12 +43,11 @@ import { admin_account_list_action_spec, admin_session_list_action_spec, admin_s
|
|
|
43
43
|
/**
|
|
44
44
|
* Create the admin-only RPC actions.
|
|
45
45
|
*
|
|
46
|
-
* @param deps -
|
|
46
|
+
* @param deps - `AdminActionDeps` slice of `AppDeps` (`log`, `on_audit_event`, optional `audit_log_config`)
|
|
47
47
|
* @param options - role schema for `grantable_roles` derivation
|
|
48
48
|
* @returns the `RpcAction` array to spread into a `create_rpc_endpoint` call
|
|
49
49
|
*/
|
|
50
50
|
export const create_admin_actions = (deps, options = {}) => {
|
|
51
|
-
const { log, on_audit_event } = deps;
|
|
52
51
|
const role_options = options.roles?.role_options ?? BUILTIN_ROLE_OPTIONS;
|
|
53
52
|
const grantable_roles = [];
|
|
54
53
|
for (const [name, rc] of role_options) {
|
|
@@ -81,7 +80,7 @@ export const create_admin_actions = (deps, options = {}) => {
|
|
|
81
80
|
reason: ERROR_ACCOUNT_NOT_FOUND,
|
|
82
81
|
attempted_account_id: input.account_id,
|
|
83
82
|
},
|
|
84
|
-
},
|
|
83
|
+
}, deps);
|
|
85
84
|
throw jsonrpc_errors.not_found('account', { reason: ERROR_ACCOUNT_NOT_FOUND });
|
|
86
85
|
}
|
|
87
86
|
const count = await query_session_revoke_all_for_account(ctx, input.account_id);
|
|
@@ -92,7 +91,7 @@ export const create_admin_actions = (deps, options = {}) => {
|
|
|
92
91
|
target_account_id: input.account_id,
|
|
93
92
|
ip: ctx.client_ip,
|
|
94
93
|
metadata: { count },
|
|
95
|
-
},
|
|
94
|
+
}, deps);
|
|
96
95
|
return { ok: true, count };
|
|
97
96
|
};
|
|
98
97
|
const token_revoke_all_handler = async (input, ctx) => {
|
|
@@ -112,7 +111,7 @@ export const create_admin_actions = (deps, options = {}) => {
|
|
|
112
111
|
reason: ERROR_ACCOUNT_NOT_FOUND,
|
|
113
112
|
attempted_account_id: input.account_id,
|
|
114
113
|
},
|
|
115
|
-
},
|
|
114
|
+
}, deps);
|
|
116
115
|
throw jsonrpc_errors.not_found('account', { reason: ERROR_ACCOUNT_NOT_FOUND });
|
|
117
116
|
}
|
|
118
117
|
const count = await query_revoke_all_api_tokens_for_account(ctx, input.account_id);
|
|
@@ -123,7 +122,7 @@ export const create_admin_actions = (deps, options = {}) => {
|
|
|
123
122
|
target_account_id: input.account_id,
|
|
124
123
|
ip: ctx.client_ip,
|
|
125
124
|
metadata: { count },
|
|
126
|
-
},
|
|
125
|
+
}, deps);
|
|
127
126
|
return { ok: true, count };
|
|
128
127
|
};
|
|
129
128
|
const audit_log_list_handler = async (input, ctx) => {
|
|
@@ -188,7 +187,7 @@ export const create_admin_actions = (deps, options = {}) => {
|
|
|
188
187
|
account_id: auth.account.id,
|
|
189
188
|
ip: ctx.client_ip,
|
|
190
189
|
metadata: { invite_id: invite.id, email, username },
|
|
191
|
-
},
|
|
190
|
+
}, deps);
|
|
192
191
|
return { ok: true, invite };
|
|
193
192
|
};
|
|
194
193
|
const invite_list_handler = async (_input, ctx) => {
|
|
@@ -207,7 +206,7 @@ export const create_admin_actions = (deps, options = {}) => {
|
|
|
207
206
|
account_id: auth.account.id,
|
|
208
207
|
ip: ctx.client_ip,
|
|
209
208
|
metadata: { invite_id: input.invite_id },
|
|
210
|
-
},
|
|
209
|
+
}, deps);
|
|
211
210
|
return { ok: true };
|
|
212
211
|
};
|
|
213
212
|
const actions = [
|
|
@@ -246,7 +245,7 @@ export const create_admin_actions = (deps, options = {}) => {
|
|
|
246
245
|
old_value,
|
|
247
246
|
new_value: input.open_signup,
|
|
248
247
|
},
|
|
249
|
-
},
|
|
248
|
+
}, deps);
|
|
250
249
|
const settings = await query_app_settings_load_with_username(ctx);
|
|
251
250
|
return { ok: true, settings };
|
|
252
251
|
};
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
|
-
import type { Logger } from '@fuzdev/fuz_util/log.js';
|
|
15
14
|
import type { QueryDeps } from '../db/query_deps.js';
|
|
16
15
|
import type { RouteContext } from '../http/route_spec.js';
|
|
16
|
+
import type { AppDeps } from './deps.js';
|
|
17
17
|
import { type AuditLogConfig, type AuditLogEvent, type AuditLogInput, type AuditLogListOptions, type AuditLogEventWithUsernamesJson, type PermitHistoryEventJson } from './audit_log_schema.js';
|
|
18
18
|
/** Default limit for audit log listings. */
|
|
19
19
|
export declare const AUDIT_LOG_DEFAULT_LIMIT = 50;
|
|
@@ -81,19 +81,29 @@ export declare const query_audit_log_list_permit_history: (deps: QueryDeps, limi
|
|
|
81
81
|
* @returns the number of entries deleted
|
|
82
82
|
*/
|
|
83
83
|
export declare const query_audit_log_cleanup_before: (deps: QueryDeps, before: Date) => Promise<number>;
|
|
84
|
+
/**
|
|
85
|
+
* Capabilities required by `audit_log_fire_and_forget`.
|
|
86
|
+
*
|
|
87
|
+
* Defined as a slice of `AppDeps` so call sites can pass the surrounding deps
|
|
88
|
+
* bundle directly without a structural-compatibility coincidence. The bundled
|
|
89
|
+
* shape replaces the prior `(log, on_audit_event, config?)` positional args
|
|
90
|
+
* — consumers that forgot the trailing `config` would silently fall back to
|
|
91
|
+
* `BUILTIN_AUDIT_LOG_CONFIG` and skip metadata validation for their own
|
|
92
|
+
* event types. `audit_log_config` is optional on `AppDeps` and defaults to
|
|
93
|
+
* `BUILTIN_AUDIT_LOG_CONFIG` inside `audit_log_fire_and_forget` when absent.
|
|
94
|
+
*/
|
|
95
|
+
export type AuditLogFireAndForgetDeps = Pick<AppDeps, 'log' | 'on_audit_event' | 'audit_log_config'>;
|
|
84
96
|
/**
|
|
85
97
|
* Log an audit event without blocking the caller.
|
|
86
98
|
*
|
|
87
99
|
* Errors are logged — audit logging never breaks auth flows. Uses
|
|
88
100
|
* `background_db` so entries persist even when the request transaction
|
|
89
|
-
* rolls back. Write and `
|
|
101
|
+
* rolls back. Write and `on_audit_event` callback failures are logged separately.
|
|
90
102
|
*
|
|
91
103
|
* @param route - `background_db` and `pending_effects` from the route context
|
|
92
104
|
* @param input - the audit event to record
|
|
93
|
-
* @param
|
|
94
|
-
* @param on_event - callback invoked with the inserted row after a successful write
|
|
95
|
-
* @param config - audit-log config. Defaults to `BUILTIN_AUDIT_LOG_CONFIG`.
|
|
105
|
+
* @param deps - logger, `on_audit_event` callback, and optional `audit_log_config`
|
|
96
106
|
* @returns the settled promise (callers may ignore it)
|
|
97
107
|
*/
|
|
98
|
-
export declare const audit_log_fire_and_forget: <T extends string>(route: Pick<RouteContext, "background_db" | "pending_effects">, input: AuditLogInput<T>,
|
|
108
|
+
export declare const audit_log_fire_and_forget: <T extends string>(route: Pick<RouteContext, "background_db" | "pending_effects">, input: AuditLogInput<T>, deps: AuditLogFireAndForgetDeps) => Promise<void>;
|
|
99
109
|
//# sourceMappingURL=audit_log_queries.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit_log_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"audit_log_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAEnD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AACvC,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,EAC3B,MAAM,uBAAuB,CAAC;AAE/B,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAa1C,iFAAiF;AACjF,eAAO,MAAM,sCAAsC,QAAO,MACvB,CAAC;AAEpC,0CAA0C;AAC1C,eAAO,MAAM,wCAAwC,QAAO,IAE3D,CAAC;AAYF,gFAAgF;AAChF,eAAO,MAAM,qCAAqC,QAAO,MACvB,CAAC;AAEnC,0CAA0C;AAC1C,eAAO,MAAM,uCAAuC,QAAO,IAE1D,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,GAAU,CAAC,SAAS,MAAM,EACrD,MAAM,SAAS,EACf,OAAO,aAAa,CAAC,CAAC,CAAC,EACvB,SAAQ,cAAyC,KAC/C,OAAO,CAAC,aAAa,CAmCvB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,UAAU,mBAAmB,KAC3B,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAwC9B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,GAC/C,MAAM,SAAS,EACf,UAAU,mBAAmB,KAC3B,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CA8C/C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,YAAY,MAAM,EAClB,cAA+B,KAC7B,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAO9B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mCAAmC,GAC/C,MAAM,SAAS,EACf,cAA+B,EAC/B,eAAU,KACR,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAYvC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,SAAS,EACf,QAAQ,IAAI,KACV,OAAO,CAAC,MAAM,CAMhB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC3C,OAAO,EACP,KAAK,GAAG,gBAAgB,GAAG,kBAAkB,CAC7C,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,MAAM,EACzD,OAAO,IAAI,CAAC,YAAY,EAAE,eAAe,GAAG,iBAAiB,CAAC,EAC9D,OAAO,aAAa,CAAC,CAAC,CAAC,EACvB,MAAM,yBAAyB,KAC7B,OAAO,CAAC,IAAI,CAed,CAAC"}
|
|
@@ -216,23 +216,22 @@ export const query_audit_log_cleanup_before = async (deps, before) => {
|
|
|
216
216
|
*
|
|
217
217
|
* Errors are logged — audit logging never breaks auth flows. Uses
|
|
218
218
|
* `background_db` so entries persist even when the request transaction
|
|
219
|
-
* rolls back. Write and `
|
|
219
|
+
* rolls back. Write and `on_audit_event` callback failures are logged separately.
|
|
220
220
|
*
|
|
221
221
|
* @param route - `background_db` and `pending_effects` from the route context
|
|
222
222
|
* @param input - the audit event to record
|
|
223
|
-
* @param
|
|
224
|
-
* @param on_event - callback invoked with the inserted row after a successful write
|
|
225
|
-
* @param config - audit-log config. Defaults to `BUILTIN_AUDIT_LOG_CONFIG`.
|
|
223
|
+
* @param deps - logger, `on_audit_event` callback, and optional `audit_log_config`
|
|
226
224
|
* @returns the settled promise (callers may ignore it)
|
|
227
225
|
*/
|
|
228
|
-
export const audit_log_fire_and_forget = (route, input,
|
|
229
|
-
const
|
|
226
|
+
export const audit_log_fire_and_forget = (route, input, deps) => {
|
|
227
|
+
const { log, on_audit_event, audit_log_config = BUILTIN_AUDIT_LOG_CONFIG } = deps;
|
|
228
|
+
const p = query_audit_log({ db: route.background_db }, input, audit_log_config)
|
|
230
229
|
.then((event) => {
|
|
231
230
|
try {
|
|
232
|
-
|
|
231
|
+
on_audit_event(event);
|
|
233
232
|
}
|
|
234
233
|
catch (callback_err) {
|
|
235
|
-
log.error('Audit log
|
|
234
|
+
log.error('Audit log on_audit_event callback failed:', callback_err);
|
|
236
235
|
}
|
|
237
236
|
})
|
|
238
237
|
.catch((err) => {
|
|
@@ -103,12 +103,14 @@ export declare const AUDIT_METADATA_SCHEMAS: Readonly<{
|
|
|
103
103
|
permit_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
104
104
|
scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
|
|
105
105
|
source_offer_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
106
|
+
self_service: z.ZodOptional<z.ZodBoolean>;
|
|
106
107
|
}, z.core.$loose>;
|
|
107
108
|
permit_revoke: z.ZodObject<{
|
|
108
109
|
role: z.ZodString;
|
|
109
110
|
permit_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
110
111
|
scope_id: z.ZodOptional<z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>>;
|
|
111
112
|
reason: z.ZodOptional<z.ZodString>;
|
|
113
|
+
self_service: z.ZodOptional<z.ZodBoolean>;
|
|
112
114
|
}, z.core.$loose>;
|
|
113
115
|
permit_offer_create: z.ZodObject<{
|
|
114
116
|
offer_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
@@ -166,11 +168,11 @@ export declare const AUDIT_METADATA_SCHEMAS: Readonly<{
|
|
|
166
168
|
export type AuditMetadataMap = {
|
|
167
169
|
[K in AuditEventType]: z.infer<(typeof AUDIT_METADATA_SCHEMAS)[K]>;
|
|
168
170
|
};
|
|
169
|
-
/** Audit log row from the database. */
|
|
171
|
+
/** Audit log row from the database. See `AuditLogEventJson` for `event_type` widening rationale. */
|
|
170
172
|
export interface AuditLogEvent {
|
|
171
173
|
id: Uuid;
|
|
172
174
|
seq: number;
|
|
173
|
-
event_type:
|
|
175
|
+
event_type: AuditEventTypeName;
|
|
174
176
|
outcome: AuditOutcome;
|
|
175
177
|
actor_id: Uuid | null;
|
|
176
178
|
account_id: Uuid | null;
|
|
@@ -258,40 +260,32 @@ export declare const create_audit_log_config: (options?: CreateAuditLogConfigOpt
|
|
|
258
260
|
export interface AuditLogListOptions {
|
|
259
261
|
limit?: number;
|
|
260
262
|
offset?: number;
|
|
261
|
-
|
|
262
|
-
|
|
263
|
+
/**
|
|
264
|
+
* Event-type filter. Accepts any string — builtins or consumer-registered
|
|
265
|
+
* via `create_audit_log_config({extra_events})`. The DB column is
|
|
266
|
+
* `TEXT NOT NULL` with no CHECK, so unknown strings simply match nothing.
|
|
267
|
+
*/
|
|
268
|
+
event_type?: string;
|
|
269
|
+
event_type_in?: Array<string>;
|
|
263
270
|
account_id?: Uuid;
|
|
264
271
|
outcome?: AuditOutcome;
|
|
265
272
|
/** When set, only return events with `seq` greater than this value. Enables SSE reconnection gap fill. */
|
|
266
273
|
since_seq?: number;
|
|
267
274
|
}
|
|
268
|
-
/**
|
|
275
|
+
/**
|
|
276
|
+
* Zod schema for client-safe audit log event.
|
|
277
|
+
*
|
|
278
|
+
* `event_type` is `AuditEventTypeName` (regex-validated string) — matches
|
|
279
|
+
* the `AuditLogEvent` row and the DB's `TEXT NOT NULL` column. Consumer
|
|
280
|
+
* types registered via `create_audit_log_config({extra_events})` round-trip
|
|
281
|
+
* through queries, `on_audit_event` callbacks, and JSON-RPC responses
|
|
282
|
+
* identically to builtins. `AuditLogInput<T>` stays parameterized on the
|
|
283
|
+
* write side so `AuditMetadataMap` narrowing via `get_audit_metadata` works.
|
|
284
|
+
*/
|
|
269
285
|
export declare const AuditLogEventJson: z.ZodObject<{
|
|
270
286
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
271
287
|
seq: z.ZodNumber;
|
|
272
|
-
event_type: z.
|
|
273
|
-
login: "login";
|
|
274
|
-
logout: "logout";
|
|
275
|
-
bootstrap: "bootstrap";
|
|
276
|
-
signup: "signup";
|
|
277
|
-
password_change: "password_change";
|
|
278
|
-
session_revoke: "session_revoke";
|
|
279
|
-
session_revoke_all: "session_revoke_all";
|
|
280
|
-
token_create: "token_create";
|
|
281
|
-
token_revoke: "token_revoke";
|
|
282
|
-
token_revoke_all: "token_revoke_all";
|
|
283
|
-
permit_grant: "permit_grant";
|
|
284
|
-
permit_revoke: "permit_revoke";
|
|
285
|
-
permit_offer_create: "permit_offer_create";
|
|
286
|
-
permit_offer_accept: "permit_offer_accept";
|
|
287
|
-
permit_offer_decline: "permit_offer_decline";
|
|
288
|
-
permit_offer_retract: "permit_offer_retract";
|
|
289
|
-
permit_offer_expire: "permit_offer_expire";
|
|
290
|
-
permit_offer_supersede: "permit_offer_supersede";
|
|
291
|
-
invite_create: "invite_create";
|
|
292
|
-
invite_delete: "invite_delete";
|
|
293
|
-
app_settings_update: "app_settings_update";
|
|
294
|
-
}>;
|
|
288
|
+
event_type: z.ZodString;
|
|
295
289
|
outcome: z.ZodEnum<{
|
|
296
290
|
success: "success";
|
|
297
291
|
failure: "failure";
|
|
@@ -308,29 +302,7 @@ export type AuditLogEventJson = z.infer<typeof AuditLogEventJson>;
|
|
|
308
302
|
export declare const AuditLogEventWithUsernamesJson: z.ZodObject<{
|
|
309
303
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
310
304
|
seq: z.ZodNumber;
|
|
311
|
-
event_type: z.
|
|
312
|
-
login: "login";
|
|
313
|
-
logout: "logout";
|
|
314
|
-
bootstrap: "bootstrap";
|
|
315
|
-
signup: "signup";
|
|
316
|
-
password_change: "password_change";
|
|
317
|
-
session_revoke: "session_revoke";
|
|
318
|
-
session_revoke_all: "session_revoke_all";
|
|
319
|
-
token_create: "token_create";
|
|
320
|
-
token_revoke: "token_revoke";
|
|
321
|
-
token_revoke_all: "token_revoke_all";
|
|
322
|
-
permit_grant: "permit_grant";
|
|
323
|
-
permit_revoke: "permit_revoke";
|
|
324
|
-
permit_offer_create: "permit_offer_create";
|
|
325
|
-
permit_offer_accept: "permit_offer_accept";
|
|
326
|
-
permit_offer_decline: "permit_offer_decline";
|
|
327
|
-
permit_offer_retract: "permit_offer_retract";
|
|
328
|
-
permit_offer_expire: "permit_offer_expire";
|
|
329
|
-
permit_offer_supersede: "permit_offer_supersede";
|
|
330
|
-
invite_create: "invite_create";
|
|
331
|
-
invite_delete: "invite_delete";
|
|
332
|
-
app_settings_update: "app_settings_update";
|
|
333
|
-
}>;
|
|
305
|
+
event_type: z.ZodString;
|
|
334
306
|
outcome: z.ZodEnum<{
|
|
335
307
|
success: "success";
|
|
336
308
|
failure: "failure";
|
|
@@ -349,29 +321,7 @@ export type AuditLogEventWithUsernamesJson = z.infer<typeof AuditLogEventWithUse
|
|
|
349
321
|
export declare const PermitHistoryEventJson: z.ZodObject<{
|
|
350
322
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
351
323
|
seq: z.ZodNumber;
|
|
352
|
-
event_type: z.
|
|
353
|
-
login: "login";
|
|
354
|
-
logout: "logout";
|
|
355
|
-
bootstrap: "bootstrap";
|
|
356
|
-
signup: "signup";
|
|
357
|
-
password_change: "password_change";
|
|
358
|
-
session_revoke: "session_revoke";
|
|
359
|
-
session_revoke_all: "session_revoke_all";
|
|
360
|
-
token_create: "token_create";
|
|
361
|
-
token_revoke: "token_revoke";
|
|
362
|
-
token_revoke_all: "token_revoke_all";
|
|
363
|
-
permit_grant: "permit_grant";
|
|
364
|
-
permit_revoke: "permit_revoke";
|
|
365
|
-
permit_offer_create: "permit_offer_create";
|
|
366
|
-
permit_offer_accept: "permit_offer_accept";
|
|
367
|
-
permit_offer_decline: "permit_offer_decline";
|
|
368
|
-
permit_offer_retract: "permit_offer_retract";
|
|
369
|
-
permit_offer_expire: "permit_offer_expire";
|
|
370
|
-
permit_offer_supersede: "permit_offer_supersede";
|
|
371
|
-
invite_create: "invite_create";
|
|
372
|
-
invite_delete: "invite_delete";
|
|
373
|
-
app_settings_update: "app_settings_update";
|
|
374
|
-
}>;
|
|
324
|
+
event_type: z.ZodString;
|
|
375
325
|
outcome: z.ZodEnum<{
|
|
376
326
|
success: "success";
|
|
377
327
|
failure: "failure";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit_log_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAC;AAGhC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,6YAsBnB,CAAC;AAEZ,wCAAwC;AACxC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;EAA4B,CAAC;AACxD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,QAA+B,CAAC;AAExE,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB,aAE7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,2CAA2C;AAC3C,eAAO,MAAM,YAAY;;;EAAiC,CAAC;AAC3D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"audit_log_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -89,17 +89,23 @@ export const AUDIT_METADATA_SCHEMAS = Object.freeze({
|
|
|
89
89
|
}),
|
|
90
90
|
// `permit_id` is optional on `permit_grant` because failed grants
|
|
91
91
|
// (e.g. `web_grantable` denied) never produce a permit row.
|
|
92
|
+
// `self_service: true` is set by the self-service role toggle in
|
|
93
|
+
// `self_service_role_actions.ts` — declared explicitly rather than
|
|
94
|
+
// riding on `z.looseObject` permissiveness so the field is part of
|
|
95
|
+
// the documented schema surface.
|
|
92
96
|
permit_grant: z.looseObject({
|
|
93
97
|
role: z.string(),
|
|
94
98
|
permit_id: Uuid.optional(),
|
|
95
99
|
scope_id: Uuid.nullish(),
|
|
96
100
|
source_offer_id: Uuid.optional(),
|
|
101
|
+
self_service: z.boolean().optional(),
|
|
97
102
|
}),
|
|
98
103
|
permit_revoke: z.looseObject({
|
|
99
104
|
role: z.string(),
|
|
100
105
|
permit_id: Uuid,
|
|
101
106
|
scope_id: Uuid.nullish(),
|
|
102
107
|
reason: z.string().optional(),
|
|
108
|
+
self_service: z.boolean().optional(),
|
|
103
109
|
}),
|
|
104
110
|
// `offer_id` is optional because failed creates (e.g. `web_grantable`
|
|
105
111
|
// denied, `authorize` callback denied) never produce an offer row.
|
|
@@ -205,11 +211,20 @@ export const create_audit_log_config = (options) => {
|
|
|
205
211
|
metadata_schemas: Object.freeze(metadata_schemas),
|
|
206
212
|
});
|
|
207
213
|
};
|
|
208
|
-
/**
|
|
214
|
+
/**
|
|
215
|
+
* Zod schema for client-safe audit log event.
|
|
216
|
+
*
|
|
217
|
+
* `event_type` is `AuditEventTypeName` (regex-validated string) — matches
|
|
218
|
+
* the `AuditLogEvent` row and the DB's `TEXT NOT NULL` column. Consumer
|
|
219
|
+
* types registered via `create_audit_log_config({extra_events})` round-trip
|
|
220
|
+
* through queries, `on_audit_event` callbacks, and JSON-RPC responses
|
|
221
|
+
* identically to builtins. `AuditLogInput<T>` stays parameterized on the
|
|
222
|
+
* write side so `AuditMetadataMap` narrowing via `get_audit_metadata` works.
|
|
223
|
+
*/
|
|
209
224
|
export const AuditLogEventJson = z.strictObject({
|
|
210
225
|
id: Uuid,
|
|
211
226
|
seq: z.number().int(),
|
|
212
|
-
event_type:
|
|
227
|
+
event_type: AuditEventTypeName,
|
|
213
228
|
outcome: AuditOutcome,
|
|
214
229
|
actor_id: Uuid.nullable(),
|
|
215
230
|
account_id: Uuid.nullable(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAoB,KAAK,uBAAuB,EAAC,MAAM,wBAAwB,CAAC;AAGvF,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAkB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAA+B,KAAK,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAanD,gFAAgF;AAChF,eAAO,MAAM,cAAc;;;;kBAIzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,iFAAiF;AACjF,eAAO,MAAM,eAAe;;;kBAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,8EAA8E;IAC9E,gBAAgB,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,EAAE,EAAE,EAAE,CAAC;IACP,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,wBAAwB,EAC9B,SAAS;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,KAClC,OAAO,CAAC,eAAe,CAwBzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,gBAAgB,EACtB,SAAS,qBAAqB,KAC5B,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"bootstrap_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAoB,KAAK,uBAAuB,EAAC,MAAM,wBAAwB,CAAC;AAGvF,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAkB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAA+B,KAAK,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAanD,gFAAgF;AAChF,eAAO,MAAM,cAAc;;;;kBAIzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,iFAAiF;AACjF,eAAO,MAAM,eAAe;;;kBAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,8EAA8E;IAC9E,gBAAgB,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,EAAE,EAAE,EAAE,CAAC;IACP,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,wBAAwB,EAC9B,SAAS;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,KAClC,OAAO,CAAC,eAAe,CAwBzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,gBAAgB,EACtB,SAAS,qBAAqB,KAC5B,KAAK,CAAC,SAAS,CAuHjB,CAAC"}
|
|
@@ -67,7 +67,7 @@ export const check_bootstrap_status = async (deps, options) => {
|
|
|
67
67
|
* @returns route specs (not yet applied to Hono)
|
|
68
68
|
*/
|
|
69
69
|
export const create_bootstrap_route_specs = (deps, options) => {
|
|
70
|
-
const { keyring
|
|
70
|
+
const { keyring } = deps;
|
|
71
71
|
const { session_options, bootstrap_status, on_bootstrap, ip_rate_limiter } = options;
|
|
72
72
|
const { token_path } = bootstrap_status;
|
|
73
73
|
return [
|
|
@@ -123,7 +123,7 @@ export const create_bootstrap_route_specs = (deps, options) => {
|
|
|
123
123
|
outcome: 'failure',
|
|
124
124
|
ip: get_client_ip(c),
|
|
125
125
|
metadata: { error: result.error },
|
|
126
|
-
}, deps
|
|
126
|
+
}, deps);
|
|
127
127
|
return c.json({ error: result.error }, result.status);
|
|
128
128
|
}
|
|
129
129
|
// Successful bootstrap — update state immediately
|
|
@@ -150,7 +150,7 @@ export const create_bootstrap_route_specs = (deps, options) => {
|
|
|
150
150
|
actor_id: result.actor.id,
|
|
151
151
|
account_id: result.account.id,
|
|
152
152
|
ip: get_client_ip(c),
|
|
153
|
-
}, deps
|
|
153
|
+
}, deps);
|
|
154
154
|
// CRITICAL: If token file deletion failed, throw to force operator attention.
|
|
155
155
|
// All success work (session, on_bootstrap, audit) has completed above.
|
|
156
156
|
// The error response alerts the operator to delete the token file manually.
|
package/dist/auth/cleanup.d.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import type { Logger } from '@fuzdev/fuz_util/log.js';
|
|
22
22
|
import type { QueryDeps } from '../db/query_deps.js';
|
|
23
|
-
import type { AuditLogEvent } from './audit_log_schema.js';
|
|
23
|
+
import type { AuditLogConfig, AuditLogEvent } from './audit_log_schema.js';
|
|
24
24
|
/** Dependencies for the cleanup helpers. */
|
|
25
25
|
export interface AuthCleanupDeps extends QueryDeps {
|
|
26
26
|
log: Logger;
|
|
@@ -30,6 +30,14 @@ export interface AuthCleanupDeps extends QueryDeps {
|
|
|
30
30
|
* to skip broadcast — the audit rows still land in the DB.
|
|
31
31
|
*/
|
|
32
32
|
on_audit_event?: ((event: AuditLogEvent) => void) | null;
|
|
33
|
+
/**
|
|
34
|
+
* Audit-log config. Only the builtin `permit_offer_expire` event type is
|
|
35
|
+
* emitted here, so omitting this is safe — the field exists so consumers
|
|
36
|
+
* threading the same `AppDeps` bundle to scheduled cleanup keep using
|
|
37
|
+
* their registered config (and consumer extensions to the
|
|
38
|
+
* `permit_offer_expire` metadata schema get validated).
|
|
39
|
+
*/
|
|
40
|
+
audit_log_config?: AuditLogConfig;
|
|
33
41
|
}
|
|
34
42
|
/** Result of `run_auth_cleanup`. */
|
|
35
43
|
export interface AuthCleanupResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanup.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAInD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"cleanup.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAInD,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEzE,4CAA4C;AAC5C,MAAM,WAAW,eAAgB,SAAQ,SAAS;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAC;CAClC;AAED,oCAAoC;AACpC,MAAM,WAAW,iBAAiB;IACjC,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,GAAU,MAAM,eAAe,KAAG,OAAO,CAAC,MAAM,CAiCzF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAU,MAAM,eAAe,KAAG,OAAO,CAAC,iBAAiB,CAIvF,CAAC"}
|
package/dist/auth/cleanup.js
CHANGED
|
@@ -33,7 +33,7 @@ import { query_audit_log } from './audit_log_queries.js';
|
|
|
33
33
|
*/
|
|
34
34
|
export const cleanup_expired_permit_offers = async (deps) => {
|
|
35
35
|
const expired = await query_permit_offer_sweep_expired(deps);
|
|
36
|
-
const { on_audit_event } = deps;
|
|
36
|
+
const { on_audit_event, audit_log_config } = deps;
|
|
37
37
|
for (const offer of expired) {
|
|
38
38
|
try {
|
|
39
39
|
const event = await query_audit_log(deps, {
|
|
@@ -46,7 +46,7 @@ export const cleanup_expired_permit_offers = async (deps) => {
|
|
|
46
46
|
role: offer.role,
|
|
47
47
|
scope_id: offer.scope_id,
|
|
48
48
|
},
|
|
49
|
-
});
|
|
49
|
+
}, audit_log_config);
|
|
50
50
|
if (on_audit_event) {
|
|
51
51
|
try {
|
|
52
52
|
on_audit_event(event);
|
package/dist/auth/deps.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { Keyring } from './keyring.js';
|
|
|
12
12
|
import type { PasswordHashDeps } from './password.js';
|
|
13
13
|
import type { Db } from '../db/db.js';
|
|
14
14
|
import type { StatResult } from '../runtime/deps.js';
|
|
15
|
-
import type { AuditLogEvent } from './audit_log_schema.js';
|
|
15
|
+
import type { AuditLogConfig, AuditLogEvent } from './audit_log_schema.js';
|
|
16
16
|
/**
|
|
17
17
|
* Stateless capabilities bundle for fuz_app backends.
|
|
18
18
|
*
|
|
@@ -41,6 +41,18 @@ export interface AppDeps {
|
|
|
41
41
|
* Defaults to a noop when not wired to SSE.
|
|
42
42
|
*/
|
|
43
43
|
on_audit_event: (event: AuditLogEvent) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Audit-log config for `audit_log_fire_and_forget` and `query_audit_log`.
|
|
46
|
+
* Built once at startup via `create_audit_log_config({extra_events})` to
|
|
47
|
+
* register consumer event types. Optional — defaults to
|
|
48
|
+
* `BUILTIN_AUDIT_LOG_CONFIG` when absent.
|
|
49
|
+
*
|
|
50
|
+
* Threaded through `AppDeps` (instead of a per-call positional arg) so
|
|
51
|
+
* consumer handlers cannot silently fall back to the builtin config by
|
|
52
|
+
* forgetting to pass theirs — the deps bundle carries it everywhere
|
|
53
|
+
* fuz_app emits an audit event.
|
|
54
|
+
*/
|
|
55
|
+
audit_log_config?: AuditLogConfig;
|
|
44
56
|
}
|
|
45
57
|
/**
|
|
46
58
|
* Capabilities for route spec factories.
|
package/dist/auth/deps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"deps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACvB,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,2BAA2B;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,yBAAyB;IACzB,EAAE,EAAE,EAAE,CAAC;IACP,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC"}
|
|
@@ -72,6 +72,20 @@ export interface PermitOfferActionOptions {
|
|
|
72
72
|
*/
|
|
73
73
|
authorize?: PermitOfferCreateAuthorize;
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Authorization callback that admits any admin and otherwise falls back to
|
|
77
|
+
* the symmetric default (caller must hold the offered role globally).
|
|
78
|
+
*
|
|
79
|
+
* The `web_grantable` filter in `create_handler` runs **before** the
|
|
80
|
+
* `authorize` callback, so this never sees non-web-grantable roles. Drop
|
|
81
|
+
* into `create_permit_offer_actions({authorize: authorize_admin_or_holder})`
|
|
82
|
+
* (or any factory that forwards `authorize`, e.g. `create_standard_rpc_actions`)
|
|
83
|
+
* for the common "admins offer anything; users offer what they hold"
|
|
84
|
+
* pattern. Scope-aware policies (e.g. classroom_teacher offering
|
|
85
|
+
* classroom_student in their own scope) wrap this and short-circuit `true`
|
|
86
|
+
* before delegating.
|
|
87
|
+
*/
|
|
88
|
+
export declare const authorize_admin_or_holder: PermitOfferCreateAuthorize;
|
|
75
89
|
/**
|
|
76
90
|
* Dependencies for `create_permit_offer_actions`.
|
|
77
91
|
*
|
|
@@ -80,7 +94,7 @@ export interface PermitOfferActionOptions {
|
|
|
80
94
|
* directly (the transport's `send_to_account` signature accepts the broader
|
|
81
95
|
* `JsonrpcMessageFromServerToClient`, which is contravariantly compatible).
|
|
82
96
|
*/
|
|
83
|
-
export interface PermitOfferActionDeps extends Pick<RouteFactoryDeps, 'log' | 'on_audit_event'> {
|
|
97
|
+
export interface PermitOfferActionDeps extends Pick<RouteFactoryDeps, 'log' | 'on_audit_event' | 'audit_log_config'> {
|
|
84
98
|
/** Optional WS fan-out primitive. `null` or absent → notifications skipped. */
|
|
85
99
|
notification_sender?: NotificationSender | null;
|
|
86
100
|
}
|
|
@@ -88,7 +102,7 @@ export interface PermitOfferActionDeps extends Pick<RouteFactoryDeps, 'log' | 'o
|
|
|
88
102
|
* Create the seven permit-offer RPC actions (six offer-lifecycle methods
|
|
89
103
|
* plus `permit_revoke`).
|
|
90
104
|
*
|
|
91
|
-
* @param deps -
|
|
105
|
+
* @param deps - `PermitOfferActionDeps` — `log`, `on_audit_event`, optional `audit_log_config` (slice of `AppDeps`); optional `notification_sender` for WS fan-out
|
|
92
106
|
* @param options - role schema, default TTL, authorization override
|
|
93
107
|
* @returns the `RpcAction` array to spread into a `create_rpc_endpoint` call
|
|
94
108
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permit_offer_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/permit_offer_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAa,KAAK,aAAa,EAAE,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAGxF,OAAO,EAAmC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAsBzF,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,EAON,KAAK,kBAAkB,EACvB,MAAM,iCAAiC,CAAC;AAmCzC;;;;;;;;GAQG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACxC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,EACrE,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,EACnC,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,iDAAiD;AACjD,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,sFAAsF;IACtF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACvC;
|
|
1
|
+
{"version":3,"file":"permit_offer_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/permit_offer_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAa,KAAK,aAAa,EAAE,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAGxF,OAAO,EAAmC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAsBzF,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,EAON,KAAK,kBAAkB,EACvB,MAAM,iCAAiC,CAAC;AAmCzC;;;;;;;;GAQG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACxC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,EACrE,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,EACnC,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,iDAAiD;AACjD,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,sFAAsF;IACtF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACvC;AAyBD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,EAAE,0BAQvC,CAAC;AAcF;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAClD,gBAAgB,EAChB,KAAK,GAAG,gBAAgB,GAAG,kBAAkB,CAC7C;IACA,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAChD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GACvC,MAAM,qBAAqB,EAC3B,UAAS,wBAA6B,KACpC,KAAK,CAAC,SAAS,CAudjB,CAAC"}
|