@camstack/types 1.2.368 → 1.2.370

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-CXlc9YJ5.js");
2
+ const require_sleep = require("./sleep-DnQ5WsMI.js");
3
3
  const require_event_category = require("./event-category-T43rdQWR.js");
4
4
  const require_composition = require("./composition-DCYnv4I6.js");
5
5
  const require_node_color = require("./node-color.js");
@@ -6640,6 +6640,103 @@ function hasUrlScheme(url) {
6640
6640
  return /^[a-z][a-z0-9+.-]*:/i.test(url);
6641
6641
  }
6642
6642
  //#endregion
6643
+ //#region src/auth/app-flow.ts
6644
+ /**
6645
+ * The native-app browser sign-in flows the hub serves itself (D858).
6646
+ *
6647
+ * The viewer app opens the system browser at a hub START route (OIDC
6648
+ * `/addon/auth-oidc/<id>/start`, the passkey page `/auth/app/passkey`) and gets
6649
+ * a one-shot handoff code back at its custom scheme. These helpers are the one
6650
+ * reading of the request every leg shares - the OIDC addon, the finish leg and
6651
+ * the passkey page - so a rule tightened for one is tightened for all:
6652
+ *
6653
+ * - PKCE is mandatory and S256 only (`code_challenge` = base64url of a SHA-256);
6654
+ * - `state` is echoed back exactly;
6655
+ * - the return URL is one of {@link APP_AUTH_CALLBACK_URLS}, never a free URL;
6656
+ * - the purpose is `new-session` or `step-up` (the legacy `renew` has no browser flow).
6657
+ *
6658
+ * Pure and dependency-free (zod only) so an addon, the backend and a spec read
6659
+ * the same code.
6660
+ */
6661
+ /** What the app redeems the code for. `step-up` yields a proof, never a session. */
6662
+ var AppFlowPurposeSchema = zod.z.enum(["new-session", "step-up"]);
6663
+ /** Where the app is sent when the request names no `redirect`. */
6664
+ var APP_FLOW_DEFAULT_REDIRECT = "camstack://auth-callback";
6665
+ /**
6666
+ * A browser OIDC flow started for an app carries this prefix on the IdP
6667
+ * `state` it generates, so a callback whose pending state is gone (expired,
6668
+ * replayed) can still be answered at the app and not on a hub error page. The
6669
+ * destination of that answer is the fixed default callback - the prefix
6670
+ * selects nothing the requester controls.
6671
+ */
6672
+ var APP_FLOW_STATE_PREFIX = "a.";
6673
+ /** S256 challenge: base64url of 32 bytes = 43 characters, no padding. */
6674
+ var CHALLENGE_PATTERN = /^[A-Za-z0-9_-]{43}$/;
6675
+ /** The app's own `state`: URL-safe characters only, bounded. */
6676
+ var STATE_PATTERN = /^[A-Za-z0-9._~-]{1,256}$/;
6677
+ /** Operator-facing words for a refusal (the "clear page", D858). */
6678
+ var APP_FLOW_REFUSAL_MESSAGES = {
6679
+ "bad-challenge": "The sign-in request has no valid PKCE challenge (S256).",
6680
+ "bad-challenge-method": "Only the S256 PKCE method is supported.",
6681
+ "bad-state": "The sign-in request has no valid state.",
6682
+ "bad-purpose": "The sign-in request names an unknown purpose.",
6683
+ "bad-redirect": "The sign-in request names a return address this hub does not accept."
6684
+ };
6685
+ /**
6686
+ * Read the app parameters off a start query: `code_challenge`,
6687
+ * `code_challenge_method`, `state`, `purpose`, `redirect`. Anything missing or
6688
+ * malformed is refused - there is no lenient default for PKCE or state.
6689
+ */
6690
+ function parseAppFlowRequest(query) {
6691
+ const challenge = query["code_challenge"];
6692
+ if (challenge === void 0 || !CHALLENGE_PATTERN.test(challenge)) return {
6693
+ ok: false,
6694
+ reason: "bad-challenge"
6695
+ };
6696
+ if (query["code_challenge_method"] !== "S256") return {
6697
+ ok: false,
6698
+ reason: "bad-challenge-method"
6699
+ };
6700
+ const state = query["state"];
6701
+ if (state === void 0 || !STATE_PATTERN.test(state)) return {
6702
+ ok: false,
6703
+ reason: "bad-state"
6704
+ };
6705
+ const purpose = AppFlowPurposeSchema.safeParse(query["purpose"]);
6706
+ if (!purpose.success) return {
6707
+ ok: false,
6708
+ reason: "bad-purpose"
6709
+ };
6710
+ const redirectParam = query["redirect"];
6711
+ const redirect = redirectParam === void 0 ? APP_FLOW_DEFAULT_REDIRECT : parseAppAuthCallback(redirectParam);
6712
+ if (redirect === null) return {
6713
+ ok: false,
6714
+ reason: "bad-redirect"
6715
+ };
6716
+ return {
6717
+ ok: true,
6718
+ request: {
6719
+ codeChallenge: challenge,
6720
+ state,
6721
+ purpose: purpose.data,
6722
+ redirect
6723
+ }
6724
+ };
6725
+ }
6726
+ /** The app's callback with `code` (success) or `error` (refusal), and the echoed `state` when known. */
6727
+ function appFlowLocation(redirect, result, state) {
6728
+ const params = new URLSearchParams();
6729
+ if ("code" in result) params.set("code", result.code);
6730
+ else params.set("error", result.error);
6731
+ if (state !== void 0) params.set("state", state);
6732
+ return `${redirect}?${params.toString()}`;
6733
+ }
6734
+ /** How a native app starts one login method (D858), as `auth.listLoginMethods` reports it. */
6735
+ var AppLoginPathSchema = zod.z.discriminatedUnion("kind", [zod.z.object({ kind: zod.z.literal("native") }), zod.z.object({
6736
+ kind: zod.z.literal("browser"),
6737
+ startPath: zod.z.string().startsWith("/")
6738
+ })]);
6739
+ //#endregion
6643
6740
  //#region src/auth/sso-state.ts
6644
6741
  /**
6645
6742
  * The cookie that binds an SSO sign-in to the browser that started it.
@@ -6902,7 +6999,9 @@ var DeviceCertificateLoginMethodSchema = zod.z.object({
6902
6999
  signature: zod.z.literal(DEVICE_CERT_SIGNATURE),
6903
7000
  messageVersion: zod.z.literal(DEVICE_SIGNATURE_MESSAGE_VERSION),
6904
7001
  /** Which clients can execute it: a native app silently, a browser with a non-extractable WebCrypto key. */
6905
- clients: zod.z.array(zod.z.enum(["native", "web"]))
7002
+ clients: zod.z.array(zod.z.enum(["native", "web"])),
7003
+ /** The app executes it itself, silently (D858). */
7004
+ app: AppLoginPathSchema.nullable()
6906
7005
  });
6907
7006
  //#endregion
6908
7007
  //#region src/auth/request-origin.ts
@@ -14314,6 +14413,16 @@ var nodeCertificatesCapability = {
14314
14413
  kind: "mutation",
14315
14414
  auth: "admin"
14316
14415
  }),
14416
+ /**
14417
+ * The hub unpairs this node (D857): it erases its mesh material, goes back to the
14418
+ * unpaired state and advertises itself again. The call is answered first; the wire
14419
+ * goes down right after, so the hub revokes the node's certificates BEFORE this
14420
+ * connection drops, never after.
14421
+ */
14422
+ forgetHub: require_sleep.method(zod.z.object({}), zod.z.object({ ok: zod.z.literal(true) }), {
14423
+ kind: "mutation",
14424
+ auth: "admin"
14425
+ }),
14317
14426
  /** Install the hub-signed HTTPS leaf and hot-swap the serving context (no restart). */
14318
14427
  installHttpsCertificate: require_sleep.method(zod.z.object({
14319
14428
  certPem: zod.z.string().min(1),
@@ -38410,6 +38519,23 @@ var HUB_MDNS_TXT_KEYS = {
38410
38519
  url: "url"
38411
38520
  };
38412
38521
  var HUB_MDNS_ROLE = "hub";
38522
+ /**
38523
+ * How a hub finds agents to pair (D857): every agent publishes ONE mDNS service for its API
38524
+ * port, paired or not. The TXT record carries only public facts. Finding an agent grants
38525
+ * nothing: pairing still needs the six-digit code confirmed on both screens.
38526
+ */
38527
+ var AGENT_MDNS_SERVICE_TYPE = "camstack-agent";
38528
+ /** The fully-qualified name a hub browses for. */
38529
+ var AGENT_MDNS_QUERY_NAME = "_camstack-agent._tcp.local";
38530
+ /** The TXT keys of the agent advertisement. Every value is public. */
38531
+ var AGENT_MDNS_TXT_KEYS = {
38532
+ nodeId: "nodeId",
38533
+ version: "version",
38534
+ /** `unpaired` | `pending` | `paired`. */
38535
+ state: "state",
38536
+ /** First 16 hex chars of the SHA-256 of the agent's mesh leaf; present once paired. */
38537
+ keyFingerprint: "fp"
38538
+ };
38413
38539
  //#endregion
38414
38540
  //#region src/capabilities/ai-cap-timeouts.ts
38415
38541
  /**
@@ -39497,7 +39623,13 @@ var RedirectLoginMethodSchema = zod.z.object({
39497
39623
  * `beginExternalLink` offer exactly the redirect methods that set this,
39498
39624
  * whatever their id. Absent / false — a login button only.
39499
39625
  */
39500
- linkable: zod.z.boolean().optional()
39626
+ linkable: zod.z.boolean().optional(),
39627
+ /**
39628
+ * How a NATIVE app starts this method (D858): `{ kind: 'browser', startPath }`
39629
+ * when the route understands the app flow query (`app=1&code_challenge=…`),
39630
+ * `null`/absent when there is no app path - the app hides the method.
39631
+ */
39632
+ app: AppLoginPathSchema.nullable().optional()
39501
39633
  });
39502
39634
  /**
39503
39635
  * A Module-Federation widget the login page mounts for an in-page
@@ -39516,7 +39648,9 @@ var WidgetLoginMethodSchema = zod.z.object({
39516
39648
  bundle: zod.z.string(),
39517
39649
  /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
39518
39650
  remote: WidgetRemoteSchema,
39519
- stage: LoginStageEnum
39651
+ stage: LoginStageEnum,
39652
+ /** Widgets are web ceremonies: no native app path (D858). Absent reads as `null`. */
39653
+ app: AppLoginPathSchema.nullable().optional()
39520
39654
  });
39521
39655
  /**
39522
39656
  * A declarative WebAuthn ceremony the shell renders natively (no remote
@@ -39534,7 +39668,9 @@ var PasskeyLoginMethodSchema = zod.z.object({
39534
39668
  /** Effective WebAuthn RP ID (`resolveRpID()`) — the shell gates visibility on it. */
39535
39669
  rpId: zod.z.string(),
39536
39670
  /** Effective expected origin (`resolveOrigin()`), null when unconfigured. */
39537
- origin: zod.z.string().nullable()
39671
+ origin: zod.z.string().nullable(),
39672
+ /** Set by the hub for the primary arm; a second-factor passkey has no app path (D858). */
39673
+ app: AppLoginPathSchema.nullable().optional()
39538
39674
  });
39539
39675
  /** One login-method contribution — redirect button, pre-auth widget, or native passkey ceremony. */
39540
39676
  var LoginMethodContributionSchema = zod.z.discriminatedUnion("kind", [
@@ -54188,7 +54324,20 @@ var SsoBridgeClaimsSchema = zod.z.object({
54188
54324
  * request to present the matching cookie — a login bridge is useless in
54189
54325
  * any other browser.
54190
54326
  */
54191
- browserBinding: zod.z.string().optional()
54327
+ browserBinding: zod.z.string().optional(),
54328
+ /**
54329
+ * The native app that started this sign-in (D858): its PKCE challenge,
54330
+ * `state`, purpose and allow-listed return URL, copied from the server-side
54331
+ * pending OIDC state. A bridge carrying it is finished ONLY at
54332
+ * `/api/auth/sso/finish-app` (which mints a handoff code, never a web
54333
+ * session); `/api/auth/sso/finish` refuses it.
54334
+ */
54335
+ app: zod.z.object({
54336
+ codeChallenge: zod.z.string(),
54337
+ state: zod.z.string(),
54338
+ purpose: zod.z.enum(["new-session", "step-up"]),
54339
+ redirect: zod.z.string()
54340
+ }).optional()
54192
54341
  });
54193
54342
  var ssoBridgeCapability = {
54194
54343
  name: "sso-bridge",
@@ -79826,6 +79975,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
79826
79975
  addonId: null,
79827
79976
  access: "create"
79828
79977
  },
79978
+ "nodeCertificates.forgetHub": {
79979
+ capName: "node-certificates",
79980
+ capScope: "system",
79981
+ addonId: null,
79982
+ access: "delete"
79983
+ },
79829
79984
  "nodeCertificates.getCertificates": {
79830
79985
  capName: "node-certificates",
79831
79986
  capScope: "system",
@@ -100355,6 +100510,9 @@ function enumerateInferenceDevices(hw) {
100355
100510
  //#endregion
100356
100511
  exports.ACCESSORY_LABEL = ACCESSORY_LABEL;
100357
100512
  exports.ACCESS_ROLES = ACCESS_ROLES;
100513
+ exports.AGENT_MDNS_QUERY_NAME = AGENT_MDNS_QUERY_NAME;
100514
+ exports.AGENT_MDNS_SERVICE_TYPE = AGENT_MDNS_SERVICE_TYPE;
100515
+ exports.AGENT_MDNS_TXT_KEYS = AGENT_MDNS_TXT_KEYS;
100358
100516
  exports.ALEXA_EGRESS_PROFILE = ALEXA_EGRESS_PROFILE;
100359
100517
  exports.ALL_CAPABILITY_DEFINITIONS = ALL_CAPABILITY_DEFINITIONS;
100360
100518
  exports.APPEARANCE_BIN_COUNT = APPEARANCE_BIN_COUNT;
@@ -100364,6 +100522,9 @@ exports.APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT = APPEARANCE_RESOLVES_AMBIGUITY_DE
100364
100522
  exports.APPLE_SA_TO_MACRO = APPLE_SA_TO_MACRO;
100365
100523
  exports.APP_AUTH_CALLBACK_MAX_LENGTH = APP_AUTH_CALLBACK_MAX_LENGTH;
100366
100524
  exports.APP_AUTH_CALLBACK_URLS = APP_AUTH_CALLBACK_URLS;
100525
+ exports.APP_FLOW_DEFAULT_REDIRECT = APP_FLOW_DEFAULT_REDIRECT;
100526
+ exports.APP_FLOW_REFUSAL_MESSAGES = APP_FLOW_REFUSAL_MESSAGES;
100527
+ exports.APP_FLOW_STATE_PREFIX = APP_FLOW_STATE_PREFIX;
100367
100528
  exports.ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT = ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT;
100368
100529
  exports.AUDIO_ANALYSIS_CAP_NAME = AUDIO_ANALYSIS_CAP_NAME;
100369
100530
  exports.AUDIO_BACKEND_CHOICES = AUDIO_BACKEND_CHOICES;
@@ -100411,6 +100572,8 @@ exports.AmbientLightSensorStatusSchema = AmbientLightSensorStatusSchema;
100411
100572
  exports.AnalyticsLtsSeriesSchema = AnalyticsLtsSeriesSchema;
100412
100573
  exports.ApiKeyRecordSchema = ApiKeyRecordSchema;
100413
100574
  exports.ApiKeySummarySchema = ApiKeySummarySchema;
100575
+ exports.AppFlowPurposeSchema = AppFlowPurposeSchema;
100576
+ exports.AppLoginPathSchema = AppLoginPathSchema;
100414
100577
  exports.AppleFmAvailabilitySchema = AppleFmAvailabilitySchema;
100415
100578
  exports.AppleFmUnavailableReasonSchema = AppleFmUnavailableReasonSchema;
100416
100579
  exports.ArchiveEntrySchema = ArchiveEntrySchema;
@@ -102143,6 +102306,7 @@ exports.alertsCapability = alertsCapability;
102143
102306
  exports.allDoActions = allDoActions;
102144
102307
  exports.allowedSuppliedEffect = allowedSuppliedEffect;
102145
102308
  exports.ambientLightSensorCapability = ambientLightSensorCapability;
102309
+ exports.appFlowLocation = appFlowLocation;
102146
102310
  exports.applyBlockingEdit = applyBlockingEdit;
102147
102311
  exports.applyModeDelaysEdits = applyModeDelaysEdits;
102148
102312
  exports.applyModeDeviceListEdit = applyModeDeviceListEdit;
@@ -102643,6 +102807,7 @@ exports.overlayClusterStepSettings = overlayClusterStepSettings;
102643
102807
  exports.packagePickerItems = packagePickerItems;
102644
102808
  exports.parseAdminBase = parseAdminBase;
102645
102809
  exports.parseAppAuthCallback = parseAppAuthCallback;
102810
+ exports.parseAppFlowRequest = parseAppFlowRequest;
102646
102811
  exports.parseCameraStreamConfig = parseCameraStreamConfig;
102647
102812
  exports.parseDeviceEnrollmentLink = parseDeviceEnrollmentLink;
102648
102813
  exports.parseExpression = require_composition.parseExpression;