@camstack/core 0.1.32 → 0.1.34

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.
Files changed (34) hide show
  1. package/dist/auth/api-key-manager.d.ts +2 -2
  2. package/dist/auth/api-key-manager.d.ts.map +1 -1
  3. package/dist/auth/auth-manager.d.ts +62 -3
  4. package/dist/auth/auth-manager.d.ts.map +1 -1
  5. package/dist/auth/totp-manager.d.ts +53 -0
  6. package/dist/auth/totp-manager.d.ts.map +1 -0
  7. package/dist/auth/user-manager.d.ts +3 -3
  8. package/dist/auth/user-manager.d.ts.map +1 -1
  9. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.d.ts.map +1 -1
  10. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js +29 -9
  11. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js.map +1 -1
  12. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs +29 -9
  13. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs.map +1 -1
  14. package/dist/builtins/local-auth/auth-schema.d.ts +14 -0
  15. package/dist/builtins/local-auth/auth-schema.d.ts.map +1 -1
  16. package/dist/builtins/local-auth/local-auth.addon.d.ts +1 -6
  17. package/dist/builtins/local-auth/local-auth.addon.d.ts.map +1 -1
  18. package/dist/builtins/local-auth/local-auth.addon.js +1015 -53
  19. package/dist/builtins/local-auth/local-auth.addon.js.map +1 -1
  20. package/dist/builtins/local-auth/local-auth.addon.mjs +1026 -64
  21. package/dist/builtins/local-auth/local-auth.addon.mjs.map +1 -1
  22. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +8 -0
  23. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts.map +1 -1
  24. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +27 -21
  25. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js.map +1 -1
  26. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +27 -21
  27. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs.map +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +400 -41
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.mjs +400 -41
  33. package/dist/index.mjs.map +1 -1
  34. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ let node_vm = require("node:vm");
37
37
  node_vm = require_chunk.__toESM(node_vm);
38
38
  let node_os = require("node:os");
39
39
  node_os = require_chunk.__toESM(node_os);
40
- //#region ../types/dist/index-DVKPWMwv.mjs
40
+ //#region ../types/dist/index-BKnvgAep.mjs
41
41
  var MODEL_FORMATS = [
42
42
  "onnx",
43
43
  "coreml",
@@ -2378,7 +2378,8 @@ var CollectionColumnSchema = zod.z.object({
2378
2378
  "TEXT",
2379
2379
  "INTEGER",
2380
2380
  "REAL",
2381
- "JSON"
2381
+ "JSON",
2382
+ "BOOLEAN"
2382
2383
  ]),
2383
2384
  primaryKey: zod.z.boolean().optional(),
2384
2385
  notNull: zod.z.boolean().optional(),
@@ -2451,6 +2452,233 @@ method(LogEntrySchema, zod.z.void(), { kind: "mutation" }), method(zod.z.object(
2451
2452
  tags: zod.z.record(zod.z.string(), zod.z.string()).optional()
2452
2453
  }), zod.z.array(LogEntrySchema).readonly());
2453
2454
  method(zod.z.void(), zod.z.string()), method(zod.z.void(), zod.z.string());
2455
+ var SsoBridgeClaimsSchema = zod.z.object({
2456
+ userId: zod.z.string(),
2457
+ username: zod.z.string(),
2458
+ isAdmin: zod.z.boolean(),
2459
+ provider: zod.z.string(),
2460
+ email: zod.z.string().optional(),
2461
+ displayName: zod.z.string().optional()
2462
+ });
2463
+ method(zod.z.object({
2464
+ claims: SsoBridgeClaimsSchema,
2465
+ ttlSec: zod.z.number().int().positive().optional()
2466
+ }), zod.z.object({ token: zod.z.string() })), method(zod.z.object({ token: zod.z.string() }), SsoBridgeClaimsSchema.nullable());
2467
+ var PasskeySummarySchema = zod.z.object({
2468
+ credentialId: zod.z.string(),
2469
+ label: zod.z.string(),
2470
+ createdAt: zod.z.number(),
2471
+ lastUsedAt: zod.z.number().nullable(),
2472
+ transports: zod.z.array(zod.z.string()).default([])
2473
+ });
2474
+ method(zod.z.object({
2475
+ userId: zod.z.string(),
2476
+ username: zod.z.string()
2477
+ }), zod.z.object({ optionsJSON: zod.z.record(zod.z.string(), zod.z.unknown()) }), {
2478
+ kind: "mutation",
2479
+ auth: "admin",
2480
+ access: "create"
2481
+ }), method(zod.z.object({
2482
+ userId: zod.z.string(),
2483
+ /** RegistrationResponseJSON from the browser. */
2484
+ response: zod.z.record(zod.z.string(), zod.z.unknown()),
2485
+ /** Operator-visible label (e.g. "MacBook Touch ID"). */
2486
+ label: zod.z.string()
2487
+ }), zod.z.object({
2488
+ success: zod.z.literal(true),
2489
+ credentialId: zod.z.string()
2490
+ }), {
2491
+ kind: "mutation",
2492
+ auth: "admin",
2493
+ access: "create"
2494
+ }), method(zod.z.object({ userId: zod.z.string().optional() }), zod.z.object({ optionsJSON: zod.z.record(zod.z.string(), zod.z.unknown()) }), {
2495
+ kind: "mutation",
2496
+ access: "view"
2497
+ }), method(zod.z.object({
2498
+ /** Required — the user the assertion belongs to (verified). */
2499
+ userId: zod.z.string(),
2500
+ /** AuthenticationResponseJSON from the browser. */
2501
+ response: zod.z.record(zod.z.string(), zod.z.unknown())
2502
+ }), zod.z.object({ verified: zod.z.boolean() }), {
2503
+ kind: "mutation",
2504
+ access: "view"
2505
+ }), method(zod.z.object({ userId: zod.z.string() }), zod.z.array(PasskeySummarySchema), { auth: "admin" }), method(zod.z.object({
2506
+ userId: zod.z.string(),
2507
+ credentialId: zod.z.string()
2508
+ }), zod.z.object({ success: zod.z.literal(true) }), {
2509
+ kind: "mutation",
2510
+ auth: "admin",
2511
+ access: "delete"
2512
+ });
2513
+ var EmailAddressSchema = zod.z.string().email();
2514
+ var SendEmailInputSchema = zod.z.object({
2515
+ to: zod.z.union([EmailAddressSchema, zod.z.array(EmailAddressSchema).min(1)]),
2516
+ cc: zod.z.array(EmailAddressSchema).optional(),
2517
+ bcc: zod.z.array(EmailAddressSchema).optional(),
2518
+ /** RFC 5322 `From` field. Most relays will reject if the domain
2519
+ * isn't authorised — the addon is responsible for substituting a
2520
+ * sane default when omitted. */
2521
+ from: zod.z.string().optional(),
2522
+ /** Optional `Reply-To` override. */
2523
+ replyTo: zod.z.string().optional(),
2524
+ subject: zod.z.string(),
2525
+ /** Plain-text body. Required even when `html` is present (fallback
2526
+ * for clients that strip HTML — including most spam filters). */
2527
+ text: zod.z.string(),
2528
+ /** Optional HTML body. Renders alongside `text` as multi-part. */
2529
+ html: zod.z.string().optional()
2530
+ });
2531
+ var SendEmailResultSchema = zod.z.object({
2532
+ messageId: zod.z.string(),
2533
+ accepted: zod.z.array(EmailAddressSchema).default([]),
2534
+ rejected: zod.z.array(EmailAddressSchema).default([])
2535
+ });
2536
+ var SmtpStatusSchema = zod.z.object({
2537
+ /** True iff the addon has successfully verified the relay. */
2538
+ ready: zod.z.boolean(),
2539
+ /** Operator-visible host string (no credentials). */
2540
+ host: zod.z.string(),
2541
+ /** Last error message reported by the relay, when not ready. */
2542
+ error: zod.z.string().optional(),
2543
+ /** Last successful verify timestamp (unix ms). */
2544
+ lastVerifiedAt: zod.z.number().optional()
2545
+ });
2546
+ method(SendEmailInputSchema, SendEmailResultSchema, {
2547
+ kind: "mutation",
2548
+ auth: "admin",
2549
+ access: "create"
2550
+ }), method(zod.z.void(), SmtpStatusSchema, {
2551
+ kind: "mutation",
2552
+ auth: "admin",
2553
+ access: "view"
2554
+ }), method(zod.z.void(), SmtpStatusSchema, { auth: "admin" });
2555
+ var QosSchema = zod.z.union([
2556
+ zod.z.literal(0),
2557
+ zod.z.literal(1),
2558
+ zod.z.literal(2)
2559
+ ]);
2560
+ var PublishInputSchema = zod.z.object({
2561
+ topic: zod.z.string(),
2562
+ /** UTF-8 payload. Binary payloads must be base64-encoded by the caller. */
2563
+ payload: zod.z.string(),
2564
+ qos: QosSchema.default(0),
2565
+ retain: zod.z.boolean().default(false)
2566
+ });
2567
+ var SubscribeInputSchema = zod.z.object({
2568
+ /** MQTT topic filter (supports `+` single-level and `#` multi-level wildcards). */
2569
+ topic: zod.z.string(),
2570
+ qos: QosSchema.default(0),
2571
+ /**
2572
+ * Caller-supplied owner tag. Useful for debugging + the
2573
+ * `listSubscriptions` admin view ("which consumer owns this?").
2574
+ * When omitted, the addon synthesizes one from the caller's addon id.
2575
+ */
2576
+ owner: zod.z.string().optional()
2577
+ });
2578
+ var SubscribeResultSchema = zod.z.object({
2579
+ success: zod.z.literal(true),
2580
+ /** Server-generated subscription id. Pass to `unsubscribe` to release. */
2581
+ subscriptionId: zod.z.string()
2582
+ });
2583
+ var UnsubscribeInputSchema = zod.z.object({
2584
+ /** Subscription id from `subscribe`. */
2585
+ subscriptionId: zod.z.string() });
2586
+ var MqttStatusSchema = zod.z.object({
2587
+ /** True iff the addon has an active connection to the broker. */
2588
+ connected: zod.z.boolean(),
2589
+ /** Operator-visible host string (e.g. `mqtt://broker.example:1883`). */
2590
+ brokerUrl: zod.z.string(),
2591
+ /** Active subscription count (per-owner, NOT broker-side topic count). */
2592
+ subscriptionCount: zod.z.number().int(),
2593
+ /** Last error reported by the broker. */
2594
+ error: zod.z.string().optional(),
2595
+ /** Last successful connection timestamp (unix ms). */
2596
+ connectedAt: zod.z.number().optional()
2597
+ });
2598
+ var SubscriptionInfoSchema = zod.z.object({
2599
+ subscriptionId: zod.z.string(),
2600
+ topic: zod.z.string(),
2601
+ qos: QosSchema,
2602
+ owner: zod.z.string(),
2603
+ /** When this individual subscription was created. */
2604
+ createdAt: zod.z.number()
2605
+ });
2606
+ method(PublishInputSchema, zod.z.object({ success: zod.z.literal(true) }), {
2607
+ kind: "mutation",
2608
+ auth: "admin",
2609
+ access: "create"
2610
+ }), method(SubscribeInputSchema, SubscribeResultSchema, {
2611
+ kind: "mutation",
2612
+ auth: "admin",
2613
+ access: "create"
2614
+ }), method(UnsubscribeInputSchema, zod.z.object({ success: zod.z.literal(true) }), {
2615
+ kind: "mutation",
2616
+ auth: "admin",
2617
+ access: "delete"
2618
+ }), method(zod.z.void(), zod.z.array(SubscriptionInfoSchema), { auth: "admin" }), method(zod.z.void(), MqttStatusSchema, { auth: "admin" });
2619
+ var HaServiceCallSchema = zod.z.object({
2620
+ /** HA domain (e.g. `light`, `switch`, `notify`). */
2621
+ domain: zod.z.string(),
2622
+ /** HA service (e.g. `turn_on`, `toggle`). */
2623
+ service: zod.z.string(),
2624
+ /** Service-specific data payload (e.g. `{entity_id: 'light.kitchen', brightness: 200}`). */
2625
+ serviceData: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
2626
+ /** Optional target spec (entity_id / device_id / area_id). */
2627
+ target: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
2628
+ });
2629
+ var HaStateSchema = zod.z.object({
2630
+ entity_id: zod.z.string(),
2631
+ state: zod.z.string(),
2632
+ attributes: zod.z.record(zod.z.string(), zod.z.unknown()).default({}),
2633
+ last_changed: zod.z.string().optional(),
2634
+ last_updated: zod.z.string().optional()
2635
+ });
2636
+ var HaStatusSchema = zod.z.object({
2637
+ connected: zod.z.boolean(),
2638
+ host: zod.z.string(),
2639
+ /** Active per-owner subscription count. */
2640
+ subscriptionCount: zod.z.number().int(),
2641
+ /** Last error reported by the WebSocket. */
2642
+ error: zod.z.string().optional(),
2643
+ /** HA version reported during the auth handshake, when reachable. */
2644
+ haVersion: zod.z.string().optional(),
2645
+ connectedAt: zod.z.number().optional()
2646
+ });
2647
+ var HaSubscribeInputSchema = zod.z.object({
2648
+ /**
2649
+ * Specific HA event type to subscribe to (`state_changed`,
2650
+ * `service_called`, etc.). Empty string = all events (firehose —
2651
+ * only for debugging).
2652
+ */
2653
+ eventType: zod.z.string().optional(),
2654
+ /** Caller-supplied tag for listSubscriptions debugging. */
2655
+ owner: zod.z.string().optional()
2656
+ });
2657
+ var HaSubscribeResultSchema = zod.z.object({
2658
+ success: zod.z.literal(true),
2659
+ subscriptionId: zod.z.string()
2660
+ });
2661
+ var HaUnsubscribeInputSchema = zod.z.object({ subscriptionId: zod.z.string() });
2662
+ var HaSubscriptionInfoSchema = zod.z.object({
2663
+ subscriptionId: zod.z.string(),
2664
+ /** Empty string when subscribed to ALL events. */
2665
+ eventType: zod.z.string(),
2666
+ owner: zod.z.string(),
2667
+ createdAt: zod.z.number()
2668
+ });
2669
+ method(HaSubscribeInputSchema, HaSubscribeResultSchema, {
2670
+ kind: "mutation",
2671
+ auth: "admin",
2672
+ access: "create"
2673
+ }), method(HaUnsubscribeInputSchema, zod.z.object({ success: zod.z.literal(true) }), {
2674
+ kind: "mutation",
2675
+ auth: "admin",
2676
+ access: "delete"
2677
+ }), method(HaServiceCallSchema, zod.z.object({ result: zod.z.unknown() }), {
2678
+ kind: "mutation",
2679
+ auth: "admin",
2680
+ access: "create"
2681
+ }), method(zod.z.void(), zod.z.array(HaStateSchema).readonly(), { auth: "admin" }), method(zod.z.object({ entityId: zod.z.string() }), HaStateSchema.nullable(), { auth: "admin" }), method(zod.z.void(), zod.z.array(HaSubscriptionInfoSchema).readonly(), { auth: "admin" }), method(zod.z.void(), HaStatusSchema, { auth: "admin" });
2454
2682
  var AddonPageDeclarationSchema$1 = zod.z.object({
2455
2683
  id: zod.z.string(),
2456
2684
  label: zod.z.string(),
@@ -2554,9 +2782,41 @@ var AddonHttpRouteSchema = zod.z.object({
2554
2782
  "DELETE",
2555
2783
  "PATCH"
2556
2784
  ]),
2557
- path: zod.z.string()
2785
+ path: zod.z.string(),
2786
+ access: zod.z.enum([
2787
+ "public",
2788
+ "authenticated",
2789
+ "admin"
2790
+ ]).optional(),
2791
+ description: zod.z.string().optional()
2558
2792
  });
2559
- method(zod.z.void(), zod.z.array(AddonHttpRouteSchema));
2793
+ var InvokeRequestSchema = zod.z.object({
2794
+ method: zod.z.string(),
2795
+ path: zod.z.string(),
2796
+ params: zod.z.record(zod.z.string(), zod.z.string()),
2797
+ query: zod.z.record(zod.z.string(), zod.z.string()),
2798
+ body: zod.z.unknown(),
2799
+ headers: zod.z.record(zod.z.string(), zod.z.string()),
2800
+ user: zod.z.object({
2801
+ id: zod.z.string(),
2802
+ username: zod.z.string(),
2803
+ isAdmin: zod.z.boolean()
2804
+ }).optional(),
2805
+ scopedToken: zod.z.unknown().optional()
2806
+ });
2807
+ var InvokeReplyEnvelopeSchema = zod.z.object({
2808
+ status: zod.z.number().int(),
2809
+ headers: zod.z.record(zod.z.string(), zod.z.string()),
2810
+ /** When set, the hub MUST `reply.redirect(redirectUrl)` instead of
2811
+ * sending `body`. Status defaults to 302 when this is set unless
2812
+ * the handler called `reply.code(...)` explicitly. */
2813
+ redirectUrl: zod.z.string().nullable(),
2814
+ /** JSON-serializable body. `undefined` is treated as "no body". */
2815
+ body: zod.z.unknown().optional(),
2816
+ /** Set when the handler called `reply.type(mime)`. */
2817
+ contentType: zod.z.string().optional()
2818
+ });
2819
+ method(zod.z.void(), zod.z.array(AddonHttpRouteSchema)), method(InvokeRequestSchema, InvokeReplyEnvelopeSchema, { kind: "mutation" });
2560
2820
  method(zod.z.object({ codec: zod.z.string() }), zod.z.boolean()), method(zod.z.void(), zod.z.object({
2561
2821
  id: zod.z.string(),
2562
2822
  name: zod.z.string(),
@@ -3298,7 +3558,14 @@ var AuthResultSchema = zod.z.object({
3298
3558
  username: zod.z.string(),
3299
3559
  email: zod.z.string().optional(),
3300
3560
  displayName: zod.z.string().optional(),
3301
- roles: zod.z.array(zod.z.string()).optional()
3561
+ /**
3562
+ * Whether the authenticating user is an admin. The auth-provider
3563
+ * surface returns this so the server's login flow can mint a JWT
3564
+ * with the correct bypass flag. Non-admin users authenticated via
3565
+ * an external IdP still need their scopes assigned by an admin via
3566
+ * `setUserScopes` — the SSO flow doesn't carry permissions.
3567
+ */
3568
+ isAdmin: zod.z.boolean().default(false)
3302
3569
  });
3303
3570
  method(zod.z.object({
3304
3571
  username: zod.z.string(),
@@ -3307,6 +3574,14 @@ method(zod.z.object({
3307
3574
  var AuthProviderInfoSchema = zod.z.object({
3308
3575
  /** Stable id matching the addon id (used for `getLoginUrl({addonId,…})`). */
3309
3576
  addonId: zod.z.string(),
3577
+ /**
3578
+ * Per-instance id when one addon registers multiple "logical"
3579
+ * providers (e.g. OIDC with Google + Microsoft + custom). The login
3580
+ * URL becomes `/addon/${addonId}/${instanceId}/start` — handler reads
3581
+ * `:instanceId` from the route. Empty/unset means the addon is a
3582
+ * single-instance provider; the URL is `/addon/${addonId}/start`.
3583
+ */
3584
+ instanceId: zod.z.string().optional(),
3310
3585
  /** Display label shown on the login button + admin row. */
3311
3586
  displayName: zod.z.string(),
3312
3587
  /** Optional iconography hint (lucide-react icon name OR emoji). */
@@ -3317,6 +3592,8 @@ var AuthProviderInfoSchema = zod.z.object({
3317
3592
  /** When true, the provider exposes a credential-form login flow
3318
3593
  * (`validateCredentials` accepts username + password). */
3319
3594
  hasCredentialFlow: zod.z.boolean(),
3595
+ /** Provider kind, drives admin-UI hint dispatch (oidc / saml / totp / …). */
3596
+ kind: zod.z.string().optional(),
3320
3597
  /** Operator-facing status string (e.g. "Connected to https://login.acme.com"). */
3321
3598
  status: zod.z.string().optional(),
3322
3599
  /** When false, the provider is registered but disabled by config; the
@@ -4467,7 +4744,20 @@ method(zod.z.void(), MeshStatusSchema), method(zod.z.object({
4467
4744
  authKey: zod.z.string().min(8),
4468
4745
  /** Optional hostname override the host should advertise. */
4469
4746
  hostname: zod.z.string().optional()
4470
- }), zod.z.object({ joined: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.void(), zod.z.object({ left: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.void(), zod.z.object({ peers: zod.z.array(MeshPeerSchema).readonly() })), method(PublicIngressConfigSchema, zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }), method(MeshIngressConfigSchema, zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" });
4747
+ }), zod.z.object({ joined: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.void(), zod.z.object({ left: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.void(), zod.z.object({ peers: zod.z.array(MeshPeerSchema).readonly() })), method(PublicIngressConfigSchema, zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }), method(MeshIngressConfigSchema, zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({
4748
+ /** Optional auth key — when provided, probes the key validity
4749
+ * against the provider's API. Omit when already joined to
4750
+ * just ping the daemon. */
4751
+ authKey: zod.z.string().optional() }), zod.z.object({
4752
+ ok: zod.z.boolean(),
4753
+ /** Provider-side identifier resolved by the probe (tailnet
4754
+ * name for Tailscale, network id for ZeroTier, etc.). */
4755
+ tenant: zod.z.string().optional(),
4756
+ /** Daemon binary version, when reachable. */
4757
+ daemonVersion: zod.z.string().optional(),
4758
+ /** Human-readable error when `ok: false`. */
4759
+ error: zod.z.string().optional()
4760
+ }), { kind: "mutation" });
4471
4761
  var MeshEndpointSchema = zod.z.object({
4472
4762
  id: zod.z.string(),
4473
4763
  label: zod.z.string(),
@@ -4500,35 +4790,58 @@ method(zod.z.void(), zod.z.array(MeshProviderInfoSchema).readonly()), method(zod
4500
4790
  authKey: zod.z.string().min(8),
4501
4791
  hostname: zod.z.string().optional()
4502
4792
  }), zod.z.object({ joined: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({ addonId: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" });
4503
- var UserRoleSchema = zod.z.enum([
4504
- "admin",
4505
- "viewer",
4506
- "agent",
4507
- "scoped"
4508
- ]);
4509
- var AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
4510
- var AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
4511
4793
  var MethodAccessSchema = zod.z.enum([
4512
4794
  "view",
4513
4795
  "create",
4514
4796
  "delete"
4515
4797
  ]);
4516
- var TokenScopeSchema = zod.z.object({
4517
- type: zod.z.enum(["addon", "capability"]),
4518
- target: zod.z.string(),
4519
- access: zod.z.array(MethodAccessSchema).min(1)
4520
- });
4798
+ var AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
4799
+ var AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
4800
+ var CapScopeSchema = zod.z.enum(["device", "system"]);
4801
+ var TokenScopeSchema = zod.z.discriminatedUnion("type", [
4802
+ zod.z.object({
4803
+ type: zod.z.literal("category"),
4804
+ target: CapScopeSchema,
4805
+ access: zod.z.array(MethodAccessSchema).min(1)
4806
+ }),
4807
+ zod.z.object({
4808
+ type: zod.z.literal("capability"),
4809
+ target: zod.z.string(),
4810
+ access: zod.z.array(MethodAccessSchema).min(1)
4811
+ }),
4812
+ zod.z.object({
4813
+ type: zod.z.literal("addon"),
4814
+ target: zod.z.string(),
4815
+ access: zod.z.array(MethodAccessSchema).min(1)
4816
+ }),
4817
+ zod.z.object({
4818
+ type: zod.z.literal("device"),
4819
+ /**
4820
+ * One or more deviceIds (serialised as strings for wire-format
4821
+ * consistency with the rest of the union). Matcher accepts if
4822
+ * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
4823
+ * of one scope-per-device when granting access to a set of cameras.
4824
+ */
4825
+ targets: zod.z.array(zod.z.string()).min(1),
4826
+ access: zod.z.array(MethodAccessSchema).min(1)
4827
+ })
4828
+ ]);
4521
4829
  zod.z.object({
4522
4830
  id: zod.z.string(),
4523
4831
  username: zod.z.string(),
4524
4832
  passwordHash: zod.z.string(),
4525
- role: UserRoleSchema,
4833
+ /**
4834
+ * Admin bypass. When true, the middleware skips the scope-access
4835
+ * check entirely. There is no other axis of privilege; the legacy
4836
+ * role enum collapsed onto this boolean in v2.
4837
+ */
4838
+ isAdmin: zod.z.boolean().default(false),
4526
4839
  allowedProviders: AllowedProviderSchema,
4527
4840
  allowedDevices: AllowedDevicesSchema,
4528
4841
  /**
4529
- * Scopes granted to this user. Admins bypass; their `scopes` is ignored.
4530
- * Non-admins (`viewer`, `agent`, `scoped`) without scopes are locked out
4531
- * of every protected call.
4842
+ * Scopes granted to this user. Admins bypass; their `scopes` is
4843
+ * ignored. Non-admins without scopes are locked out of every
4844
+ * protected call.
4532
4845
  */
4533
4846
  scopes: zod.z.array(TokenScopeSchema).default([]),
4534
4847
  createdAt: zod.z.number(),
@@ -4537,7 +4850,7 @@ zod.z.object({
4537
4850
  zod.z.object({
4538
4851
  id: zod.z.string(),
4539
4852
  label: zod.z.string(),
4540
- role: UserRoleSchema,
4853
+ isAdmin: zod.z.boolean().default(false),
4541
4854
  allowedProviders: AllowedProviderSchema,
4542
4855
  allowedDevices: AllowedDevicesSchema,
4543
4856
  tokenHash: zod.z.string(),
@@ -4559,7 +4872,7 @@ zod.z.object({
4559
4872
  var UserSummarySchema = zod.z.object({
4560
4873
  id: zod.z.string(),
4561
4874
  username: zod.z.string(),
4562
- role: UserRoleSchema,
4875
+ isAdmin: zod.z.boolean().default(false),
4563
4876
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]),
4564
4877
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])),
4565
4878
  scopes: zod.z.array(TokenScopeSchema).default([]),
@@ -4569,14 +4882,14 @@ var UserSummarySchema = zod.z.object({
4569
4882
  var CreateUserInputSchema = zod.z.object({
4570
4883
  username: zod.z.string(),
4571
4884
  password: zod.z.string().min(6),
4572
- role: UserRoleSchema,
4885
+ isAdmin: zod.z.boolean().default(false),
4573
4886
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
4574
4887
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
4575
4888
  scopes: zod.z.array(TokenScopeSchema).optional()
4576
4889
  });
4577
4890
  var UpdateUserInputSchema = zod.z.object({
4578
4891
  id: zod.z.string(),
4579
- role: UserRoleSchema.optional(),
4892
+ isAdmin: zod.z.boolean().optional(),
4580
4893
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
4581
4894
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
4582
4895
  scopes: zod.z.array(TokenScopeSchema).optional()
@@ -4584,7 +4897,7 @@ var UpdateUserInputSchema = zod.z.object({
4584
4897
  var ApiKeySummarySchema = zod.z.object({
4585
4898
  id: zod.z.string(),
4586
4899
  label: zod.z.string(),
4587
- role: UserRoleSchema,
4900
+ isAdmin: zod.z.boolean().default(false),
4588
4901
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
4589
4902
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
4590
4903
  tokenPrefix: zod.z.string(),
@@ -4593,7 +4906,7 @@ var ApiKeySummarySchema = zod.z.object({
4593
4906
  });
4594
4907
  var CreateApiKeyInputSchema = zod.z.object({
4595
4908
  label: zod.z.string(),
4596
- role: UserRoleSchema,
4909
+ isAdmin: zod.z.boolean().default(false),
4597
4910
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
4598
4911
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional()
4599
4912
  });
@@ -4621,43 +4934,89 @@ var CreateScopedTokenResultSchema = zod.z.object({
4621
4934
  token: zod.z.string(),
4622
4935
  record: ScopedTokenSummarySchema
4623
4936
  });
4937
+ var TotpSetupResultSchema = zod.z.object({
4938
+ secret: zod.z.string(),
4939
+ otpauthUrl: zod.z.string()
4940
+ });
4941
+ var TotpStatusSchema = zod.z.object({
4942
+ /** True iff `confirmedAt != null` — a pending half-enrollment is reported as `enabled: false`. */
4943
+ enabled: zod.z.boolean(),
4944
+ /** Null when no row exists OR the row is still pending confirmation. */
4945
+ confirmedAt: zod.z.number().nullable()
4946
+ });
4624
4947
  method(zod.z.void(), zod.z.array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
4625
4948
  kind: "mutation",
4626
- auth: "admin"
4949
+ auth: "admin",
4950
+ access: "create"
4627
4951
  }), method(UpdateUserInputSchema, zod.z.object({ success: zod.z.literal(true) }), {
4628
4952
  kind: "mutation",
4629
- auth: "admin"
4953
+ auth: "admin",
4954
+ access: "create"
4630
4955
  }), method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
4631
4956
  kind: "mutation",
4632
- auth: "admin"
4957
+ auth: "admin",
4958
+ access: "delete"
4633
4959
  }), method(zod.z.object({
4634
4960
  id: zod.z.string(),
4635
4961
  newPassword: zod.z.string().min(6)
4636
4962
  }), zod.z.object({ success: zod.z.literal(true) }), {
4637
4963
  kind: "mutation",
4638
- auth: "admin"
4964
+ auth: "admin",
4965
+ access: "create"
4639
4966
  }), method(zod.z.object({
4640
4967
  userId: zod.z.string(),
4641
4968
  scopes: zod.z.array(TokenScopeSchema)
4642
4969
  }), zod.z.object({ success: zod.z.literal(true) }), {
4643
4970
  kind: "mutation",
4644
- auth: "admin"
4971
+ auth: "admin",
4972
+ access: "create"
4645
4973
  }), method(zod.z.object({
4646
4974
  username: zod.z.string(),
4647
4975
  password: zod.z.string()
4648
- }), UserSummarySchema.extend({ passwordHash: zod.z.string() }).nullable(), { kind: "mutation" }), method(zod.z.void(), zod.z.array(ApiKeySummarySchema), { auth: "admin" }), method(CreateApiKeyInputSchema, CreateApiKeyResultSchema, {
4976
+ }), UserSummarySchema.extend({ passwordHash: zod.z.string() }).nullable(), {
4649
4977
  kind: "mutation",
4650
- auth: "admin"
4978
+ access: "view"
4979
+ }), method(zod.z.void(), zod.z.array(ApiKeySummarySchema), { auth: "admin" }), method(CreateApiKeyInputSchema, CreateApiKeyResultSchema, {
4980
+ kind: "mutation",
4981
+ auth: "admin",
4982
+ access: "create"
4651
4983
  }), method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
4652
4984
  kind: "mutation",
4653
- auth: "admin"
4654
- }), method(zod.z.object({ token: zod.z.string() }), ApiKeySummarySchema.nullable(), { kind: "mutation" }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
4985
+ auth: "admin",
4986
+ access: "delete"
4987
+ }), method(zod.z.object({ token: zod.z.string() }), ApiKeySummarySchema.nullable(), {
4655
4988
  kind: "mutation",
4656
- auth: "admin"
4989
+ access: "view"
4990
+ }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
4991
+ kind: "mutation",
4992
+ auth: "admin",
4993
+ access: "create"
4657
4994
  }), method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
4658
4995
  kind: "mutation",
4659
- auth: "admin"
4660
- }), method(zod.z.object({ token: zod.z.string() }), ScopedTokenSummarySchema.nullable()), method(zod.z.object({ userId: zod.z.string() }), zod.z.array(ScopedTokenSummarySchema), { auth: "admin" });
4996
+ auth: "admin",
4997
+ access: "delete"
4998
+ }), method(zod.z.object({ token: zod.z.string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(zod.z.object({ userId: zod.z.string() }), zod.z.array(ScopedTokenSummarySchema), { auth: "admin" }), method(zod.z.object({ userId: zod.z.string() }), TotpSetupResultSchema, {
4999
+ kind: "mutation",
5000
+ auth: "admin",
5001
+ access: "create"
5002
+ }), method(zod.z.object({
5003
+ userId: zod.z.string(),
5004
+ code: zod.z.string()
5005
+ }), zod.z.object({ success: zod.z.literal(true) }), {
5006
+ kind: "mutation",
5007
+ auth: "admin",
5008
+ access: "create"
5009
+ }), method(zod.z.object({ userId: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
5010
+ kind: "mutation",
5011
+ auth: "admin",
5012
+ access: "delete"
5013
+ }), method(zod.z.object({ userId: zod.z.string() }), TotpStatusSchema, { auth: "admin" }), method(zod.z.object({
5014
+ userId: zod.z.string(),
5015
+ code: zod.z.string()
5016
+ }), zod.z.object({ valid: zod.z.boolean() }), {
5017
+ kind: "mutation",
5018
+ access: "view"
5019
+ });
4661
5020
  var FeatureManifestSchema = zod.z.object({
4662
5021
  streaming: zod.z.boolean(),
4663
5022
  notifications: zod.z.boolean(),