@camstack/types 1.2.364 → 1.2.366

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 (93) hide show
  1. package/dist/addon.js +3 -2
  2. package/dist/addon.mjs +3 -2
  3. package/dist/auth/device-certificate.d.ts +372 -0
  4. package/dist/auth/request-origin.d.ts +43 -0
  5. package/dist/capabilities/air-quality-sensor.cap.d.ts +32 -0
  6. package/dist/capabilities/alarm-panel.cap.d.ts +4 -0
  7. package/dist/capabilities/ambient-light-sensor.cap.d.ts +13 -0
  8. package/dist/capabilities/audio-metrics.cap.d.ts +4 -0
  9. package/dist/capabilities/automation-control.cap.d.ts +4 -0
  10. package/dist/capabilities/battery.cap.d.ts +11 -0
  11. package/dist/capabilities/binary.cap.d.ts +10 -0
  12. package/dist/capabilities/brightness.cap.d.ts +12 -0
  13. package/dist/capabilities/camera-streams.cap.d.ts +4 -0
  14. package/dist/capabilities/capability-definition.d.ts +70 -0
  15. package/dist/capabilities/carbon-monoxide.cap.d.ts +10 -0
  16. package/dist/capabilities/climate-control.cap.d.ts +32 -0
  17. package/dist/capabilities/color.cap.d.ts +4 -0
  18. package/dist/capabilities/connectivity.cap.d.ts +4 -0
  19. package/dist/capabilities/consumables.cap.d.ts +4 -0
  20. package/dist/capabilities/contact.cap.d.ts +10 -0
  21. package/dist/capabilities/control.cap.d.ts +4 -0
  22. package/dist/capabilities/cover.cap.d.ts +12 -0
  23. package/dist/capabilities/day-night.cap.d.ts +4 -0
  24. package/dist/capabilities/device-credentials.cap.d.ts +174 -0
  25. package/dist/capabilities/device-discovery.cap.d.ts +4 -0
  26. package/dist/capabilities/device-status.cap.d.ts +10 -0
  27. package/dist/capabilities/doorbell.cap.d.ts +4 -0
  28. package/dist/capabilities/enum-sensor.cap.d.ts +4 -0
  29. package/dist/capabilities/event-emitter.cap.d.ts +4 -0
  30. package/dist/capabilities/fan-control.cap.d.ts +15 -0
  31. package/dist/capabilities/feature-probe.cap.d.ts +4 -0
  32. package/dist/capabilities/flood.cap.d.ts +10 -0
  33. package/dist/capabilities/gas.cap.d.ts +10 -0
  34. package/dist/capabilities/humidifier.cap.d.ts +15 -0
  35. package/dist/capabilities/humidity-sensor.cap.d.ts +12 -0
  36. package/dist/capabilities/image-settings.cap.d.ts +4 -0
  37. package/dist/capabilities/image.cap.d.ts +4 -0
  38. package/dist/capabilities/index.d.ts +7 -3
  39. package/dist/capabilities/intercom.cap.d.ts +4 -0
  40. package/dist/capabilities/lawn-mower-control.cap.d.ts +12 -0
  41. package/dist/capabilities/lock-control.cap.d.ts +4 -0
  42. package/dist/capabilities/media-player.cap.d.ts +4 -0
  43. package/dist/capabilities/motion-trigger.cap.d.ts +4 -0
  44. package/dist/capabilities/motion-zones.cap.d.ts +4 -0
  45. package/dist/capabilities/motion.cap.d.ts +11 -0
  46. package/dist/capabilities/native-object-detection.cap.d.ts +4 -0
  47. package/dist/capabilities/navigation.cap.d.ts +4 -0
  48. package/dist/capabilities/network-link.cap.d.ts +19 -0
  49. package/dist/capabilities/node-certificates.cap.d.ts +128 -0
  50. package/dist/capabilities/notifier.cap.d.ts +4 -0
  51. package/dist/capabilities/numeric-sensor.cap.d.ts +12 -0
  52. package/dist/capabilities/pet-feeder.cap.d.ts +25 -0
  53. package/dist/capabilities/power-meter.cap.d.ts +43 -0
  54. package/dist/capabilities/presence.cap.d.ts +12 -0
  55. package/dist/capabilities/pressure-sensor.cap.d.ts +12 -0
  56. package/dist/capabilities/privacy-mask.cap.d.ts +4 -0
  57. package/dist/capabilities/ptz-autotrack.cap.d.ts +4 -0
  58. package/dist/capabilities/recording-onboard.cap.d.ts +4 -0
  59. package/dist/capabilities/recording-signal.cap.d.ts +4 -0
  60. package/dist/capabilities/scene-monitor.cap.d.ts +4 -0
  61. package/dist/capabilities/script-runner.cap.d.ts +4 -0
  62. package/dist/capabilities/smoke.cap.d.ts +10 -0
  63. package/dist/capabilities/stream-catalog.cap.d.ts +4 -0
  64. package/dist/capabilities/stream-params.cap.d.ts +4 -0
  65. package/dist/capabilities/stream-signals.cap.d.ts +4 -0
  66. package/dist/capabilities/switch.cap.d.ts +10 -0
  67. package/dist/capabilities/tamper.cap.d.ts +10 -0
  68. package/dist/capabilities/temperature-sensor.cap.d.ts +12 -0
  69. package/dist/capabilities/update.cap.d.ts +4 -0
  70. package/dist/capabilities/vacuum-control.cap.d.ts +32 -0
  71. package/dist/capabilities/valve.cap.d.ts +12 -0
  72. package/dist/capabilities/vibration.cap.d.ts +10 -0
  73. package/dist/capabilities/water-heater.cap.d.ts +17 -0
  74. package/dist/capabilities/weather.cap.d.ts +27 -0
  75. package/dist/capabilities/zone-analytics.cap.d.ts +4 -0
  76. package/dist/capabilities/zone-rules.cap.d.ts +4 -0
  77. package/dist/capabilities/zones.cap.d.ts +4 -0
  78. package/dist/client.d.ts +1 -1
  79. package/dist/client.js +255 -0
  80. package/dist/client.mjs +245 -1
  81. package/dist/generated/addon-api.d.ts +797 -4
  82. package/dist/generated/cap-input-defaults.d.ts +1 -1
  83. package/dist/generated/capability-router-map.d.ts +8 -2
  84. package/dist/generated/history-catalog.d.ts +11 -0
  85. package/dist/generated/method-access-map.d.ts +1 -1
  86. package/dist/generated/system-proxy.d.ts +2 -0
  87. package/dist/index.d.ts +3 -0
  88. package/dist/index.js +1574 -34
  89. package/dist/index.mjs +1522 -35
  90. package/dist/interfaces/auth.d.ts +6 -0
  91. package/dist/{sleep-BBF1iXUi.mjs → sleep-DxJdzHni.mjs} +26 -1
  92. package/dist/{sleep-BBXNq778.js → sleep-NZlEFYGX.js} +37 -0
  93. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-BBXNq778.js");
2
+ const require_sleep = require("./sleep-NZlEFYGX.js");
3
3
  const require_event_category = require("./event-category-T43rdQWR.js");
4
4
  const require_err_msg = require("./err-msg-Dx2Kor0g.js");
5
5
  //#region src/generated/cap-input-defaults.ts
@@ -16,7 +16,7 @@ const require_err_msg = require("./err-msg-Dx2Kor0g.js");
16
16
  * Plain data, zero Zod: a forked runner must not import the schema barrel
17
17
  * (~144MB RSS per runner — D28).
18
18
  *
19
- * Coverage: 25 caps, 66 methods with defaults.
19
+ * Coverage: 26 caps, 67 methods with defaults.
20
20
  */
21
21
  var CAP_INPUT_DEFAULTS = Object.freeze({
22
22
  "addons": { "getLogs": { "limit": 100 } },
@@ -39,6 +39,7 @@ var CAP_INPUT_DEFAULTS = Object.freeze({
39
39
  "page": 1,
40
40
  "pageSize": 50
41
41
  } },
42
+ "device-credentials": { "listDeviceCredentials": { "includeRevoked": false } },
42
43
  "device-manager": { "adoptionListCandidates": {
43
44
  "page": 1,
44
45
  "pageSize": 50
package/dist/addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as ReadinessRegistry, A as viewerUiCapability, At as clearKnownSecrets, C as isZodSecret, Cn as isSecretMarker, Dt as REVALIDATE_AFTER_MS, E as HF_REPO, En as toSecretFieldView, Et as resolveSecretViewsIn, Ft as shortSecretRefHash, Gt as normalizeAddonInitResult, H as expandCapMethods, I as adminUiCapability, It as PEER_BYTES_CHUNK_BYTES, Lt as PEER_BYTES_MAX_OUTSTANDING, Mt as knownSecretCount, Nt as registerKnownSecret, Ot as createSecretsAccess, P as describeCustomActions, Pt as scrubKnownSecrets, Q as MODEL_FORMATS, Rt as PEER_BYTES_STALL_MS, S as collectZodSecretPaths, Sn as isSecretFieldView, Tn as makeSecretMarker, Ut as DisposerChain, Vt as DATAPLANE_SECRET_HEADER, Wt as BaseAddon, X as readNodePin, Y as nodePin, _ as createEventBusSliceSource, an as isSecretRef, bn as classifySecretWrite, c as asString, d as parseJsonUnknown, dn as emitReadiness, en as SECRET_REF_SCHEME, et as ReadinessTimeoutError, f as hfModelUrl, g as createDeviceProxy, h as isDeviceScopedCap, in as globalSecretScope, j as DEVICE_CHILDREN_BATCH_MAX, jt as forgetKnownSecret, k as deviceOpsCapability, kt as MIN_SCRUBBED_LENGTH, m as DEVICE_SCOPED_CAPS, nn as buildSecretRef, o as asJsonObject, on as normalizeSecretOwner, p as BOOT_RECOVERY_BACKOFF_MS, r as maskUrlCredentials, rn as formatSecretScope, rt as scopeKey, sn as parseSecretRef, t as sleep, tn as arrayItemFieldPath, un as createEvent, wn as isSecretMarkerLike, xn as isSecretClear, yn as SECRET_CLEAR, zt as PEER_BYTES_TICKET_TTL_MS } from "./sleep-BBF1iXUi.mjs";
1
+ import { A as viewerUiCapability, At as createSecretsAccess, Bt as PEER_BYTES_STALL_MS, C as isZodSecret, Cn as isSecretClear, Dn as makeSecretMarker, E as HF_REPO, En as isSecretMarkerLike, Ft as registerKnownSecret, Gt as DisposerChain, I as adminUiCapability, It as scrubKnownSecrets, Kt as BaseAddon, Lt as shortSecretRefHash, Mt as clearKnownSecrets, Nt as forgetKnownSecret, On as toSecretFieldView, Ot as resolveSecretViewsIn, P as describeCustomActions, Pt as knownSecretCount, Q as readNodePin, Rt as PEER_BYTES_CHUNK_BYTES, S as collectZodSecretPaths, Sn as classifySecretWrite, Tn as isSecretMarker, Ut as DATAPLANE_SECRET_HEADER, Vt as PEER_BYTES_TICKET_TTL_MS, W as expandCapMethods, Z as nodePin, _ as createEventBusSliceSource, an as formatSecretScope, at as scopeKey, c as asString, cn as normalizeSecretOwner, d as parseJsonUnknown, et as MODEL_FORMATS, f as hfModelUrl, fn as createEvent, g as createDeviceProxy, h as isDeviceScopedCap, in as buildSecretRef, j as DEVICE_CHILDREN_BATCH_MAX, jt as MIN_SCRUBBED_LENGTH, k as deviceOpsCapability, kt as REVALIDATE_AFTER_MS, ln as parseSecretRef, m as DEVICE_SCOPED_CAPS, nn as SECRET_REF_SCHEME, nt as ReadinessTimeoutError, o as asJsonObject, on as globalSecretScope, p as BOOT_RECOVERY_BACKOFF_MS, pn as emitReadiness, qt as normalizeAddonInitResult, r as maskUrlCredentials, rn as arrayItemFieldPath, sn as isSecretRef, t as sleep, tt as ReadinessRegistry, wn as isSecretFieldView, xn as SECRET_CLEAR, zt as PEER_BYTES_MAX_OUTSTANDING } from "./sleep-DxJdzHni.mjs";
2
2
  import { t as EventCategory } from "./event-category-C4hVnRo8.mjs";
3
3
  import { a as DeviceType, t as errMsg } from "./err-msg-DX6i_MY4.mjs";
4
4
  //#region src/generated/cap-input-defaults.ts
@@ -15,7 +15,7 @@ import { a as DeviceType, t as errMsg } from "./err-msg-DX6i_MY4.mjs";
15
15
  * Plain data, zero Zod: a forked runner must not import the schema barrel
16
16
  * (~144MB RSS per runner — D28).
17
17
  *
18
- * Coverage: 25 caps, 66 methods with defaults.
18
+ * Coverage: 26 caps, 67 methods with defaults.
19
19
  */
20
20
  var CAP_INPUT_DEFAULTS = Object.freeze({
21
21
  "addons": { "getLogs": { "limit": 100 } },
@@ -38,6 +38,7 @@ var CAP_INPUT_DEFAULTS = Object.freeze({
38
38
  "page": 1,
39
39
  "pageSize": 50
40
40
  } },
41
+ "device-credentials": { "listDeviceCredentials": { "includeRevoked": false } },
41
42
  "device-manager": { "adoptionListCandidates": {
42
43
  "page": 1,
43
44
  "pageSize": 50
@@ -0,0 +1,372 @@
1
+ /**
2
+ * Device certificates (D855) — the wire contract shared by the hub, the admin
3
+ * UI and the native viewer.
4
+ *
5
+ * A device (a phone) generates its OWN P-256 key pair in hardware (Secure
6
+ * Enclave / Android Keystore / a non-extractable WebCrypto key). The private
7
+ * key never travels. The hub signs the PUBLIC key into an X.509 leaf under a
8
+ * dedicated device CA; the device later proves possession of the key by
9
+ * signing a hub-issued nonce, and the hub answers with the same session a
10
+ * password login opens.
11
+ *
12
+ * Everything on the wire is a small string (a PEM, a base64url signature):
13
+ * D613 is about bulk bytes, and a certificate is ~600 bytes.
14
+ */
15
+ import { z } from 'zod';
16
+ /** Signature algorithm of every device credential: ECDSA, curve P-256, SHA-256. */
17
+ export declare const DEVICE_CERT_SIGNATURE: 'ecdsa-p256-sha256';
18
+ /** First line of every signed message; a change of format bumps the version. */
19
+ export declare const DEVICE_SIGNATURE_MESSAGE_VERSION: 'camstack-device-cert-v1';
20
+ /** What a signature is for. A login signature can never be replayed as a renewal. */
21
+ export declare const DeviceSignaturePurposeSchema: z.ZodEnum<{
22
+ login: "login";
23
+ renew: "renew";
24
+ revoke: "revoke";
25
+ }>;
26
+ export type DeviceSignaturePurpose = z.infer<typeof DeviceSignaturePurposeSchema>;
27
+ /** Leaf lifetime and the window in which the app renews it. */
28
+ export declare const DEVICE_CERT_VALIDITY_DAYS = 365;
29
+ export declare const DEVICE_CERT_RENEW_WINDOW_DAYS = 30;
30
+ /** One-shot enrollment code and login nonce lifetimes. */
31
+ export declare const DEVICE_ENROLLMENT_TTL_MS: number;
32
+ export declare const DEVICE_NONCE_TTL_MS = 60000;
33
+ /** SAN URI prefixes of a device leaf. */
34
+ export declare const DEVICE_SAN_CREDENTIAL_PREFIX: 'camstack:credential:';
35
+ export declare const DEVICE_SAN_USER_PREFIX: 'camstack:user:';
36
+ /**
37
+ * The exact bytes a device signs (UTF-8, `\n` separators, no trailing newline):
38
+ *
39
+ * camstack-device-cert-v1
40
+ * <login|renew>
41
+ * <origin> the hub origin returned by `getDeviceChallenge`
42
+ * <nonce>
43
+ *
44
+ * The origin is part of the message so a signature collected by a look-alike
45
+ * hub is worthless on the real one; the hub additionally binds the nonce to
46
+ * the origin it issued it for and refuses any other.
47
+ */
48
+ export declare function buildDeviceSignatureMessage(input: {
49
+ readonly purpose: DeviceSignaturePurpose;
50
+ readonly origin: string;
51
+ readonly nonce: string;
52
+ }): string;
53
+ /** The deep link a QR carries: `camstack://enroll?hub=<origin>&code=<code>`. */
54
+ export declare function buildDeviceEnrollmentLink(input: {
55
+ readonly hub?: string;
56
+ readonly code: string;
57
+ readonly scheme?: string;
58
+ }): string;
59
+ /** Parse an enrollment deep link; `null` when it is not one. `hub` is absent when the link names none. */
60
+ export declare function parseDeviceEnrollmentLink(raw: string): {
61
+ readonly hub: string | null;
62
+ readonly code: string;
63
+ } | null;
64
+ export declare const DevicePlatformSchema: z.ZodEnum<{
65
+ android: "android";
66
+ ios: "ios";
67
+ other: "other";
68
+ web: "web";
69
+ }>;
70
+ export type DevicePlatform = z.infer<typeof DevicePlatformSchema>;
71
+ /**
72
+ * Why a device-certificate endpoint said no. Distinct from a transport / 5xx
73
+ * failure: those carry no reason and mean "try again", never "the credential is
74
+ * dead". The viewer switches on this exhaustively.
75
+ */
76
+ export declare const DeviceRefusalReasonSchema: z.ZodEnum<{
77
+ "bad-public-key": "bad-public-key";
78
+ "bad-signature": "bad-signature";
79
+ "code-invalid": "code-invalid";
80
+ expired: "expired";
81
+ "invalid-certificate": "invalid-certificate";
82
+ "nonce-invalid": "nonce-invalid";
83
+ "rate-limited": "rate-limited";
84
+ revoked: "revoked";
85
+ "self-enrollment-disabled": "self-enrollment-disabled";
86
+ "step-up-required": "step-up-required";
87
+ superseded: "superseded";
88
+ unavailable: "unavailable";
89
+ "unknown-credential": "unknown-credential";
90
+ "user-gone": "user-gone";
91
+ }>;
92
+ export type DeviceRefusalReason = z.infer<typeof DeviceRefusalReasonSchema>;
93
+ /** The only answers after which the app may count towards deleting its credential. */
94
+ export declare const DEFINITIVE_DEVICE_REFUSALS: readonly DeviceRefusalReason[];
95
+ /** Consecutive DEFINITIVE answers before the app deletes its key and certificate. */
96
+ export declare const DEVICE_DEFINITIVE_REFUSALS_BEFORE_DELETE = 3;
97
+ export declare function isDefinitiveDeviceRefusal(reason: DeviceRefusalReason): boolean;
98
+ export declare const DeviceRefusalSchema: z.ZodObject<{
99
+ ok: z.ZodLiteral<false>;
100
+ reason: z.ZodEnum<{
101
+ "bad-public-key": "bad-public-key";
102
+ "bad-signature": "bad-signature";
103
+ "code-invalid": "code-invalid";
104
+ expired: "expired";
105
+ "invalid-certificate": "invalid-certificate";
106
+ "nonce-invalid": "nonce-invalid";
107
+ "rate-limited": "rate-limited";
108
+ revoked: "revoked";
109
+ "self-enrollment-disabled": "self-enrollment-disabled";
110
+ "step-up-required": "step-up-required";
111
+ superseded: "superseded";
112
+ unavailable: "unavailable";
113
+ "unknown-credential": "unknown-credential";
114
+ "user-gone": "user-gone";
115
+ }>;
116
+ definitive: z.ZodBoolean;
117
+ retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
118
+ }, z.core.$strip>;
119
+ export type DeviceRefusal = z.infer<typeof DeviceRefusalSchema>;
120
+ /**
121
+ * A credential-bound session that can no longer refresh answers
122
+ * `auth.refreshSession` with UNAUTHORIZED whose message is this prefix + the
123
+ * reason; {@link deviceRefusalFromMessage} reads it back.
124
+ */
125
+ export declare const DEVICE_REFRESH_REFUSAL_PREFIX: 'device-credential:';
126
+ export declare function deviceRefusalFromMessage(message: string): DeviceRefusalReason | null;
127
+ export declare const CompleteEnrollmentInputSchema: z.ZodObject<{
128
+ code: z.ZodString;
129
+ publicKeySpki: z.ZodString;
130
+ deviceName: z.ZodOptional<z.ZodString>;
131
+ platform: z.ZodEnum<{
132
+ android: "android";
133
+ ios: "ios";
134
+ other: "other";
135
+ web: "web";
136
+ }>;
137
+ }, z.core.$strip>;
138
+ export type CompleteEnrollmentInput = z.infer<typeof CompleteEnrollmentInputSchema>;
139
+ export declare const CompleteEnrollmentOutputSchema: z.ZodObject<{
140
+ credentialId: z.ZodString;
141
+ certPem: z.ZodString;
142
+ chainPem: z.ZodString;
143
+ notAfter: z.ZodNumber;
144
+ user: z.ZodObject<{
145
+ id: z.ZodString;
146
+ username: z.ZodString;
147
+ }, z.core.$strip>;
148
+ }, z.core.$strip>;
149
+ export type CompleteEnrollmentOutput = z.infer<typeof CompleteEnrollmentOutputSchema>;
150
+ export declare const CompleteEnrollmentResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
151
+ credentialId: z.ZodString;
152
+ certPem: z.ZodString;
153
+ chainPem: z.ZodString;
154
+ notAfter: z.ZodNumber;
155
+ user: z.ZodObject<{
156
+ id: z.ZodString;
157
+ username: z.ZodString;
158
+ }, z.core.$strip>;
159
+ ok: z.ZodLiteral<true>;
160
+ }, z.core.$strip>, z.ZodObject<{
161
+ ok: z.ZodLiteral<false>;
162
+ reason: z.ZodEnum<{
163
+ "bad-public-key": "bad-public-key";
164
+ "bad-signature": "bad-signature";
165
+ "code-invalid": "code-invalid";
166
+ expired: "expired";
167
+ "invalid-certificate": "invalid-certificate";
168
+ "nonce-invalid": "nonce-invalid";
169
+ "rate-limited": "rate-limited";
170
+ revoked: "revoked";
171
+ "self-enrollment-disabled": "self-enrollment-disabled";
172
+ "step-up-required": "step-up-required";
173
+ superseded: "superseded";
174
+ unavailable: "unavailable";
175
+ "unknown-credential": "unknown-credential";
176
+ "user-gone": "user-gone";
177
+ }>;
178
+ definitive: z.ZodBoolean;
179
+ retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
180
+ }, z.core.$strip>], "ok">;
181
+ export type CompleteEnrollmentResult = z.infer<typeof CompleteEnrollmentResultSchema>;
182
+ export declare const EnrollSelfInputSchema: z.ZodObject<{
183
+ proof: z.ZodString;
184
+ publicKeySpki: z.ZodString;
185
+ deviceName: z.ZodString;
186
+ platform: z.ZodEnum<{
187
+ android: "android";
188
+ ios: "ios";
189
+ other: "other";
190
+ web: "web";
191
+ }>;
192
+ }, z.core.$strip>;
193
+ export type EnrollSelfInput = z.infer<typeof EnrollSelfInputSchema>;
194
+ export declare const DeviceEnrollProofSchema: z.ZodObject<{
195
+ proof: z.ZodString;
196
+ expiresAt: z.ZodNumber;
197
+ }, z.core.$strip>;
198
+ export declare const DeviceChallengeSchema: z.ZodObject<{
199
+ nonce: z.ZodString;
200
+ origin: z.ZodString;
201
+ expiresAt: z.ZodNumber;
202
+ signature: z.ZodLiteral<"ecdsa-p256-sha256">;
203
+ }, z.core.$strip>;
204
+ export type DeviceChallenge = z.infer<typeof DeviceChallengeSchema>;
205
+ export declare const DeviceChallengeResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
206
+ nonce: z.ZodString;
207
+ origin: z.ZodString;
208
+ expiresAt: z.ZodNumber;
209
+ signature: z.ZodLiteral<"ecdsa-p256-sha256">;
210
+ ok: z.ZodLiteral<true>;
211
+ }, z.core.$strip>, z.ZodObject<{
212
+ ok: z.ZodLiteral<false>;
213
+ reason: z.ZodEnum<{
214
+ "bad-public-key": "bad-public-key";
215
+ "bad-signature": "bad-signature";
216
+ "code-invalid": "code-invalid";
217
+ expired: "expired";
218
+ "invalid-certificate": "invalid-certificate";
219
+ "nonce-invalid": "nonce-invalid";
220
+ "rate-limited": "rate-limited";
221
+ revoked: "revoked";
222
+ "self-enrollment-disabled": "self-enrollment-disabled";
223
+ "step-up-required": "step-up-required";
224
+ superseded: "superseded";
225
+ unavailable: "unavailable";
226
+ "unknown-credential": "unknown-credential";
227
+ "user-gone": "user-gone";
228
+ }>;
229
+ definitive: z.ZodBoolean;
230
+ retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
231
+ }, z.core.$strip>], "ok">;
232
+ export type DeviceChallengeResult = z.infer<typeof DeviceChallengeResultSchema>;
233
+ export declare const DeviceProofInputSchema: z.ZodObject<{
234
+ certPem: z.ZodString;
235
+ nonce: z.ZodString;
236
+ signature: z.ZodString;
237
+ }, z.core.$strip>;
238
+ export type DeviceProofInput = z.infer<typeof DeviceProofInputSchema>;
239
+ export declare const RenewDeviceCertificateOutputSchema: z.ZodObject<{
240
+ credentialId: z.ZodString;
241
+ certPem: z.ZodString;
242
+ chainPem: z.ZodString;
243
+ notAfter: z.ZodNumber;
244
+ }, z.core.$strip>;
245
+ export type RenewDeviceCertificateOutput = z.infer<typeof RenewDeviceCertificateOutputSchema>;
246
+ export declare const RenewDeviceCertificateResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
247
+ credentialId: z.ZodString;
248
+ certPem: z.ZodString;
249
+ chainPem: z.ZodString;
250
+ notAfter: z.ZodNumber;
251
+ ok: z.ZodLiteral<true>;
252
+ }, z.core.$strip>, z.ZodObject<{
253
+ ok: z.ZodLiteral<false>;
254
+ reason: z.ZodEnum<{
255
+ "bad-public-key": "bad-public-key";
256
+ "bad-signature": "bad-signature";
257
+ "code-invalid": "code-invalid";
258
+ expired: "expired";
259
+ "invalid-certificate": "invalid-certificate";
260
+ "nonce-invalid": "nonce-invalid";
261
+ "rate-limited": "rate-limited";
262
+ revoked: "revoked";
263
+ "self-enrollment-disabled": "self-enrollment-disabled";
264
+ "step-up-required": "step-up-required";
265
+ superseded: "superseded";
266
+ unavailable: "unavailable";
267
+ "unknown-credential": "unknown-credential";
268
+ "user-gone": "user-gone";
269
+ }>;
270
+ definitive: z.ZodBoolean;
271
+ retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
272
+ }, z.core.$strip>], "ok">;
273
+ export type RenewDeviceCertificateResult = z.infer<typeof RenewDeviceCertificateResultSchema>;
274
+ export declare const RevokeOwnDeviceCertificateResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
275
+ ok: z.ZodLiteral<true>;
276
+ credentialId: z.ZodString;
277
+ sessionsEnded: z.ZodNumber;
278
+ }, z.core.$strip>, z.ZodObject<{
279
+ ok: z.ZodLiteral<false>;
280
+ reason: z.ZodEnum<{
281
+ "bad-public-key": "bad-public-key";
282
+ "bad-signature": "bad-signature";
283
+ "code-invalid": "code-invalid";
284
+ expired: "expired";
285
+ "invalid-certificate": "invalid-certificate";
286
+ "nonce-invalid": "nonce-invalid";
287
+ "rate-limited": "rate-limited";
288
+ revoked: "revoked";
289
+ "self-enrollment-disabled": "self-enrollment-disabled";
290
+ "step-up-required": "step-up-required";
291
+ superseded: "superseded";
292
+ unavailable: "unavailable";
293
+ "unknown-credential": "unknown-credential";
294
+ "user-gone": "user-gone";
295
+ }>;
296
+ definitive: z.ZodBoolean;
297
+ retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
298
+ }, z.core.$strip>], "ok">;
299
+ export type RevokeOwnDeviceCertificateResult = z.infer<typeof RevokeOwnDeviceCertificateResultSchema>;
300
+ /** Who revoked a credential, as `revokedBy` records it: `admin:<userId>` | `user:<userId>` | `device`. */
301
+ export type DeviceRevoker = {
302
+ readonly kind: 'admin';
303
+ readonly userId: string;
304
+ } | {
305
+ readonly kind: 'user';
306
+ readonly userId: string;
307
+ } | {
308
+ readonly kind: 'device';
309
+ };
310
+ export declare function formatDeviceRevoker(revoker: DeviceRevoker): string;
311
+ export declare const DeviceCredentialStatusSchema: z.ZodEnum<{
312
+ active: "active";
313
+ expired: "expired";
314
+ revoked: "revoked";
315
+ }>;
316
+ export type DeviceCredentialStatus = z.infer<typeof DeviceCredentialStatusSchema>;
317
+ export declare const DeviceCredentialSchema: z.ZodObject<{
318
+ id: z.ZodString;
319
+ userId: z.ZodString;
320
+ username: z.ZodNullable<z.ZodString>;
321
+ deviceName: z.ZodString;
322
+ platform: z.ZodEnum<{
323
+ android: "android";
324
+ ios: "ios";
325
+ other: "other";
326
+ web: "web";
327
+ }>;
328
+ enrolledVia: z.ZodEnum<{
329
+ qr: "qr";
330
+ self: "self";
331
+ }>;
332
+ fingerprint: z.ZodString;
333
+ issuedAt: z.ZodNumber;
334
+ expiresAt: z.ZodNumber;
335
+ lastUsedAt: z.ZodNullable<z.ZodNumber>;
336
+ lastUsedFrom: z.ZodNullable<z.ZodString>;
337
+ revokedAt: z.ZodNullable<z.ZodNumber>;
338
+ revokedBy: z.ZodNullable<z.ZodString>;
339
+ status: z.ZodEnum<{
340
+ active: "active";
341
+ expired: "expired";
342
+ revoked: "revoked";
343
+ }>;
344
+ }, z.core.$strip>;
345
+ export type DeviceCredential = z.infer<typeof DeviceCredentialSchema>;
346
+ export declare const StartEnrollmentOutputSchema: z.ZodObject<{
347
+ code: z.ZodString;
348
+ expiresAt: z.ZodNumber;
349
+ enrollUrl: z.ZodString;
350
+ hubOrigin: z.ZodNullable<z.ZodString>;
351
+ hubOrigins: z.ZodArray<z.ZodString>;
352
+ }, z.core.$strip>;
353
+ export type StartEnrollmentOutput = z.infer<typeof StartEnrollmentOutputSchema>;
354
+ /** The `device-certificate` arm of `auth.listLoginMethods`. */
355
+ export declare const DeviceCertificateLoginMethodSchema: z.ZodObject<{
356
+ kind: z.ZodLiteral<"device-certificate">;
357
+ id: z.ZodLiteral<"device-certificate">;
358
+ label: z.ZodString;
359
+ stage: z.ZodLiteral<"primary">;
360
+ challengePath: z.ZodLiteral<"auth.getDeviceChallenge">;
361
+ revokePath: z.ZodLiteral<"auth.revokeOwnDeviceCertificate">;
362
+ enrollSelfPath: z.ZodLiteral<"auth.enrollSelf">;
363
+ loginPath: z.ZodLiteral<"auth.loginWithDeviceCertificate">;
364
+ renewPath: z.ZodLiteral<"auth.renewDeviceCertificate">;
365
+ signature: z.ZodLiteral<"ecdsa-p256-sha256">;
366
+ messageVersion: z.ZodLiteral<"camstack-device-cert-v1">;
367
+ clients: z.ZodArray<z.ZodEnum<{
368
+ native: "native";
369
+ web: "web";
370
+ }>>;
371
+ }, z.core.$strip>;
372
+ export type DeviceCertificateLoginMethod = z.infer<typeof DeviceCertificateLoginMethodSchema>;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The hub address an OIDC sign-in STARTED at — so it returns there (D791).
3
+ *
4
+ * The browser must come back to the origin it left from: the session cookie,
5
+ * the admin UI's stored token and a popup's `window.opener` all belong to
6
+ * one origin. Before this the `redirect_uri` was the hub's single browser
7
+ * address (`hubBrowserOrigin`), so a sign-in started on the LAN address
8
+ * (`https://192.168.x.x:4443`) finished on the public tunnel.
9
+ *
10
+ * The origin is read from the `/start` request — `X-Forwarded-Host` /
11
+ * `Host`, `X-Forwarded-Proto` — and is NEVER trusted as such: a forged
12
+ * `Host` would otherwise choose where the IdP sends the authorization code.
13
+ * It is used only when it equals, exactly, an origin the hub advertises
14
+ * itself at (the Network page's addresses: detected, custom, the public
15
+ * endpoint, the app-connection set) or the origin of the operator's
16
+ * configured redirect override. Anything else falls back to the default
17
+ * browser address, exactly as before.
18
+ *
19
+ * The mount prefix (`X-Forwarded-Prefix`, the reverse-proxy relay) is kept on
20
+ * the path when well-formed — it can only move the callback within an
21
+ * allowlisted origin, where the hub serves or 404s it and a strict IdP
22
+ * refuses an unregistered one.
23
+ */
24
+ import type { HubAddressBook } from '../capabilities/local-network.cap.js';
25
+ /** A request's headers as the addon-routes bridge hands them (lower-cased names). */
26
+ export type RequestHeaders = Readonly<Record<string, string | undefined>>;
27
+ /** `scheme://host[:port]` normalised by WHATWG URL, or `null` if it is not an http(s) origin. */
28
+ export declare function normalizeOrigin(value: string): string | null;
29
+ /** The mount prefix the relay named (no trailing slash), or `''`. Invalid = absent. */
30
+ export declare function requestMountPrefix(headers: RequestHeaders): string;
31
+ /**
32
+ * The origins the request CLAIMS, most specific first: the proxy's
33
+ * `X-Forwarded-Host` over `Host`; the named `X-Forwarded-Proto`, or https
34
+ * then http when none is named (the hub terminates TLS itself on 4443).
35
+ */
36
+ export declare function claimedRequestOrigins(headers: RequestHeaders): readonly string[];
37
+ /** Every origin the hub advertises itself at, normalised. Never the app link, never loopback. */
38
+ export declare function advertisedHubOrigins(book: HubAddressBook): ReadonlySet<string>;
39
+ /**
40
+ * The origin to send the browser back to: the first claimed origin that is in
41
+ * `allowed`, or `null` (the caller then uses its default address).
42
+ */
43
+ export declare function pickRequestOrigin(headers: RequestHeaders, allowed: ReadonlySet<string>): string | null;
@@ -58,6 +58,38 @@ export declare const airQualitySensorCapability: {
58
58
  * `scripts/check-runtime-state-durability.ts`.
59
59
  */
60
60
  readonly durability: 'restored';
61
+ /**
62
+ * History (D850): recorded series.
63
+ */
64
+ readonly history: {
65
+ readonly fields: {
66
+ readonly co2Ppm: {
67
+ readonly kind: 'gauge';
68
+ readonly unit: 'ppm';
69
+ readonly deadband: 5;
70
+ };
71
+ readonly vocPpb: {
72
+ readonly kind: 'gauge';
73
+ readonly unit: 'ppb';
74
+ readonly deadband: 5;
75
+ };
76
+ readonly pm25: {
77
+ readonly kind: 'gauge';
78
+ readonly unit: 'ug/m3';
79
+ readonly deadband: 1;
80
+ };
81
+ readonly pm10: {
82
+ readonly kind: 'gauge';
83
+ readonly unit: 'ug/m3';
84
+ readonly deadband: 1;
85
+ };
86
+ readonly aqi: {
87
+ readonly kind: 'gauge';
88
+ readonly unit: 'count';
89
+ readonly deadband: 1;
90
+ };
91
+ };
92
+ };
61
93
  /** Clock fields: written, but excluded from the compare that decides
62
94
  * whether persisting is worth a SQLite commit. */
63
95
  readonly volatileStateFields: readonly ["lastFetchedAt"];
@@ -177,6 +177,10 @@ export declare const alarmPanelCapability: {
177
177
  * `scripts/check-runtime-state-durability.ts`.
178
178
  */
179
179
  readonly durability: 'restored';
180
+ /**
181
+ * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
182
+ */
183
+ readonly history: 'none';
180
184
  /** Clock fields: written, but excluded from the compare that decides
181
185
  * whether persisting is worth a SQLite commit. */
182
186
  readonly volatileStateFields: readonly ["lastChangedAt"];
@@ -41,6 +41,19 @@ export declare const ambientLightSensorCapability: {
41
41
  * `scripts/check-runtime-state-durability.ts`.
42
42
  */
43
43
  readonly durability: 'restored';
44
+ /**
45
+ * History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
46
+ */
47
+ readonly history: {
48
+ readonly fields: {
49
+ readonly lux: {
50
+ readonly kind: 'gauge';
51
+ readonly unit: 'lx';
52
+ readonly deadbandPct: 10;
53
+ readonly minIntervalMs: 60000;
54
+ };
55
+ };
56
+ };
44
57
  /** Clock fields: written, but excluded from the compare that decides
45
58
  * whether persisting is worth a SQLite commit. */
46
59
  readonly volatileStateFields: readonly ["lastFetchedAt"];
@@ -175,6 +175,10 @@ export declare const audioMetricsCapability: {
175
175
  * `scripts/check-runtime-state-durability.ts`.
176
176
  */
177
177
  readonly durability: 'session';
178
+ /**
179
+ * History (D850): none — the level is the addon series `pipeline-analytics/audio-level` (producer `record`); the other numbers move every inference window and duplicate it.
180
+ */
181
+ readonly history: 'none';
178
182
  };
179
183
  export type IAudioMetricsProvider = InferProvider<typeof audioMetricsCapability>;
180
184
  export { AudioMetricsSnapshotSchema, AudioClassSummarySchema, AudioMetricsHistoryPointSchema, AudioMetricsHistorySchema, };
@@ -67,5 +67,9 @@ export declare const automationControlCapability: {
67
67
  * `scripts/check-runtime-state-durability.ts`.
68
68
  */
69
69
  readonly durability: 'session';
70
+ /**
71
+ * History (D850): none — configuration and transient run state.
72
+ */
73
+ readonly history: 'none';
70
74
  };
71
75
  export type IAutomationControlProvider = InferProvider<typeof automationControlCapability>;
@@ -149,6 +149,17 @@ export declare const batteryCapability: {
149
149
  * `scripts/check-runtime-state-durability.ts`.
150
150
  */
151
151
  readonly durability: 'restored';
152
+ /**
153
+ * History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
154
+ */
155
+ readonly history: {
156
+ readonly fields: {
157
+ readonly percentage: {
158
+ readonly kind: 'gauge';
159
+ readonly unit: '%';
160
+ };
161
+ };
162
+ };
152
163
  /** Clock fields: written, but excluded from the compare that decides
153
164
  * whether persisting is worth a SQLite commit. */
154
165
  readonly volatileStateFields: readonly ["lastUpdated"];
@@ -42,6 +42,16 @@ export declare const binaryCapability: {
42
42
  * `scripts/check-runtime-state-durability.ts`.
43
43
  */
44
44
  readonly durability: 'restored';
45
+ /**
46
+ * History (D850): recorded series.
47
+ */
48
+ readonly history: {
49
+ readonly fields: {
50
+ readonly on: {
51
+ readonly kind: 'boolean';
52
+ };
53
+ };
54
+ };
45
55
  /** Clock fields: written, but excluded from the compare that decides
46
56
  * whether persisting is worth a SQLite commit. */
47
57
  readonly volatileStateFields: readonly ["lastChangedAt"];
@@ -67,5 +67,17 @@ export declare const brightnessCapability: {
67
67
  * `scripts/check-runtime-state-durability.ts`.
68
68
  */
69
69
  readonly durability: 'session';
70
+ /**
71
+ * History (D850): recorded series. Actuator tier: level keeps every change.
72
+ */
73
+ readonly history: {
74
+ readonly fields: {
75
+ readonly percentage: {
76
+ readonly kind: 'gauge';
77
+ readonly unit: '%';
78
+ readonly minIntervalMs: 0;
79
+ };
80
+ };
81
+ };
70
82
  };
71
83
  export type IBrightnessProvider = InferProvider<typeof brightnessCapability>;
@@ -403,5 +403,9 @@ export declare const cameraStreamsCapability: {
403
403
  * `scripts/check-runtime-state-durability.ts`.
404
404
  */
405
405
  readonly durability: 'session';
406
+ /**
407
+ * History (D850): none — `online` duplicates device-status.online (one authority); slot data is nested enum/string.
408
+ */
409
+ readonly history: 'none';
406
410
  };
407
411
  export type ICameraStreamsProvider = InferProvider<typeof cameraStreamsCapability>;