@camstack/types 1.2.363 → 1.2.365
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/addon.js +2 -1
- package/dist/addon.mjs +2 -1
- package/dist/auth/device-certificate.d.ts +372 -0
- package/dist/auth/request-origin.d.ts +43 -0
- package/dist/capabilities/device-credentials.cap.d.ts +174 -0
- package/dist/capabilities/device-manager.cap.d.ts +9 -93
- package/dist/capabilities/index.d.ts +5 -1
- package/dist/capabilities/node-certificates.cap.d.ts +128 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +20328 -0
- package/dist/client.mjs +20304 -1
- package/dist/device/icon-catalog.d.ts +97 -0
- package/dist/device/icon-catalog.generated.d.ts +266 -0
- package/dist/device/icon-synonyms.d.ts +26 -0
- package/dist/device/index.d.ts +4 -2
- package/dist/device/location-icon.d.ts +17 -128
- package/dist/device/site-zone.d.ts +3 -25
- package/dist/generated/addon-api.d.ts +797 -4
- package/dist/generated/cap-input-defaults.d.ts +1 -1
- package/dist/generated/capability-router-map.d.ts +8 -2
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +2 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +24030 -4823
- package/dist/index.mjs +23970 -4812
- package/dist/interfaces/auth.d.ts +6 -0
- package/dist/interfaces/config-ui.d.ts +7 -8
- package/package.json +1 -1
- package/dist/device/display-icon-vocabulary.d.ts +0 -113
package/dist/addon.js
CHANGED
|
@@ -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:
|
|
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
|
@@ -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:
|
|
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;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type InferProvider } from './capability-definition.js';
|
|
3
|
+
export declare const DeviceCaStatusSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4
|
+
state: z.ZodLiteral<"absent">;
|
|
5
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
6
|
+
state: z.ZodLiteral<"ready">;
|
|
7
|
+
subject: z.ZodString;
|
|
8
|
+
fingerprintSha256: z.ZodString;
|
|
9
|
+
validTo: z.ZodString;
|
|
10
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
11
|
+
state: z.ZodLiteral<"unavailable">;
|
|
12
|
+
reason: z.ZodString;
|
|
13
|
+
}, z.core.$strip>], "state">;
|
|
14
|
+
export type DeviceCaStatus = z.infer<typeof DeviceCaStatusSchema>;
|
|
15
|
+
export declare const DeviceCertificateSettingsSchema: z.ZodObject<{
|
|
16
|
+
selfEnrollment: z.ZodEnum<{
|
|
17
|
+
allowed: "allowed";
|
|
18
|
+
disabled: "disabled";
|
|
19
|
+
}>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
export type DeviceCertificateSettings = z.infer<typeof DeviceCertificateSettingsSchema>;
|
|
22
|
+
/**
|
|
23
|
+
* `device-credentials` — the admin surface of device certificates (D855).
|
|
24
|
+
*
|
|
25
|
+
* Everything a device does ITSELF — completing an enrollment, getting a
|
|
26
|
+
* challenge, signing in, renewing — is a PUBLIC procedure of the hub's `auth`
|
|
27
|
+
* router (`auth.completeEnrollment`, `getDeviceChallenge`,
|
|
28
|
+
* `loginWithDeviceCertificate`, `renewDeviceCertificate`): those legs are
|
|
29
|
+
* proofs of possession, not capability calls, and must not be reachable as
|
|
30
|
+
* cap methods. This cap holds only what an operator does about them.
|
|
31
|
+
*
|
|
32
|
+
* Provider: `local-auth`, which also owns the device CA and the registry.
|
|
33
|
+
* The hub is the only node that persists device credentials.
|
|
34
|
+
*/
|
|
35
|
+
export declare const deviceCredentialsCapability: {
|
|
36
|
+
readonly name: 'device-credentials';
|
|
37
|
+
readonly scope: 'system';
|
|
38
|
+
readonly mode: 'singleton';
|
|
39
|
+
readonly methods: {
|
|
40
|
+
/**
|
|
41
|
+
* Every enrolled device, newest first; `userId` narrows to one user.
|
|
42
|
+
* `status` is derived: revoked wins over expired.
|
|
43
|
+
*/
|
|
44
|
+
readonly listDeviceCredentials: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
45
|
+
userId: z.ZodOptional<z.ZodString>;
|
|
46
|
+
includeRevoked: z.ZodDefault<z.ZodBoolean>;
|
|
47
|
+
}, z.core.$strip>, z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
48
|
+
id: z.ZodString;
|
|
49
|
+
userId: z.ZodString;
|
|
50
|
+
username: z.ZodNullable<z.ZodString>;
|
|
51
|
+
deviceName: z.ZodString;
|
|
52
|
+
platform: z.ZodEnum<{
|
|
53
|
+
android: "android";
|
|
54
|
+
ios: "ios";
|
|
55
|
+
other: "other";
|
|
56
|
+
web: "web";
|
|
57
|
+
}>;
|
|
58
|
+
enrolledVia: z.ZodEnum<{
|
|
59
|
+
qr: "qr";
|
|
60
|
+
self: "self";
|
|
61
|
+
}>;
|
|
62
|
+
fingerprint: z.ZodString;
|
|
63
|
+
issuedAt: z.ZodNumber;
|
|
64
|
+
expiresAt: z.ZodNumber;
|
|
65
|
+
lastUsedAt: z.ZodNullable<z.ZodNumber>;
|
|
66
|
+
lastUsedFrom: z.ZodNullable<z.ZodString>;
|
|
67
|
+
revokedAt: z.ZodNullable<z.ZodNumber>;
|
|
68
|
+
revokedBy: z.ZodNullable<z.ZodString>;
|
|
69
|
+
status: z.ZodEnum<{
|
|
70
|
+
active: "active";
|
|
71
|
+
expired: "expired";
|
|
72
|
+
revoked: "revoked";
|
|
73
|
+
}>;
|
|
74
|
+
}, z.core.$strip>>>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
75
|
+
/**
|
|
76
|
+
* Mint a one-shot enrollment code for `userId` and a device name: 128-bit
|
|
77
|
+
* random, single use, 10 minutes, kept only as a hash. Returns the code
|
|
78
|
+
* once, with the `camstack://enroll?hub=…&code=…` link a QR carries.
|
|
79
|
+
* `caller` (the admin) is recorded in the audit trail.
|
|
80
|
+
*/
|
|
81
|
+
readonly startEnrollment: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
82
|
+
userId: z.ZodString;
|
|
83
|
+
deviceName: z.ZodString;
|
|
84
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
85
|
+
code: z.ZodString;
|
|
86
|
+
expiresAt: z.ZodNumber;
|
|
87
|
+
enrollUrl: z.ZodString;
|
|
88
|
+
hubOrigin: z.ZodNullable<z.ZodString>;
|
|
89
|
+
hubOrigins: z.ZodArray<z.ZodString>;
|
|
90
|
+
}, z.core.$strip>, "mutation"> & {
|
|
91
|
+
readonly caller: 'required';
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Revoke a credential: its certificate stops logging in at once, and every
|
|
95
|
+
* session it opened ends (an open session also dies at its next refresh
|
|
96
|
+
* even if this call raced it). Idempotent.
|
|
97
|
+
*/
|
|
98
|
+
readonly revokeDeviceCredential: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
99
|
+
id: z.ZodString;
|
|
100
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
101
|
+
revoked: z.ZodBoolean;
|
|
102
|
+
sessionsEnded: z.ZodNumber;
|
|
103
|
+
status: z.ZodEnum<{
|
|
104
|
+
active: "active";
|
|
105
|
+
expired: "expired";
|
|
106
|
+
revoked: "revoked";
|
|
107
|
+
}>;
|
|
108
|
+
}, z.core.$strip>, "mutation"> & {
|
|
109
|
+
readonly caller: 'required';
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Hub-wide device-certificate settings. `selfEnrollment`: `allowed`
|
|
113
|
+
* (default) lets a signed-in user enroll their own device after a step-up
|
|
114
|
+
* sign-in; `disabled` makes `auth.enrollSelf` refuse. The admin QR path is
|
|
115
|
+
* unaffected. Hub-wide only (no per-role switch).
|
|
116
|
+
*/
|
|
117
|
+
readonly getDeviceCertificateSettings: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
118
|
+
selfEnrollment: z.ZodEnum<{
|
|
119
|
+
allowed: "allowed";
|
|
120
|
+
disabled: "disabled";
|
|
121
|
+
}>;
|
|
122
|
+
}, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
123
|
+
readonly setDeviceCertificateSettings: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
124
|
+
selfEnrollment: z.ZodEnum<{
|
|
125
|
+
allowed: "allowed";
|
|
126
|
+
disabled: "disabled";
|
|
127
|
+
}>;
|
|
128
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
129
|
+
selfEnrollment: z.ZodEnum<{
|
|
130
|
+
allowed: "allowed";
|
|
131
|
+
disabled: "disabled";
|
|
132
|
+
}>;
|
|
133
|
+
}, z.core.$strip>, "mutation">;
|
|
134
|
+
/**
|
|
135
|
+
* Delete the registry row of a REVOKED credential (clean-up; the audit trail
|
|
136
|
+
* keeps the revocation). Refuses a live credential: revoke it first. After
|
|
137
|
+
* the row is gone the device's next call answers `unknown-credential`.
|
|
138
|
+
*/
|
|
139
|
+
readonly deleteDeviceCredential: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
140
|
+
id: z.ZodString;
|
|
141
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
142
|
+
result: z.ZodEnum<{
|
|
143
|
+
deleted: "deleted";
|
|
144
|
+
live: "live";
|
|
145
|
+
unknown: "unknown";
|
|
146
|
+
}>;
|
|
147
|
+
}, z.core.$strip>, "mutation"> & {
|
|
148
|
+
readonly caller: 'required';
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* The device CA: `absent` until the first enrollment creates it (lazily,
|
|
152
|
+
* never rotated on boot), `unavailable` while the keychain cannot answer.
|
|
153
|
+
*/
|
|
154
|
+
readonly getDeviceCaStatus: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
155
|
+
state: z.ZodLiteral<"absent">;
|
|
156
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
157
|
+
state: z.ZodLiteral<"ready">;
|
|
158
|
+
subject: z.ZodString;
|
|
159
|
+
fingerprintSha256: z.ZodString;
|
|
160
|
+
validTo: z.ZodString;
|
|
161
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
162
|
+
state: z.ZodLiteral<"unavailable">;
|
|
163
|
+
reason: z.ZodString;
|
|
164
|
+
}, z.core.$strip>], "state">, import("./capability-definition.js").CapabilityMethodKind>;
|
|
165
|
+
/** Rename a credential (the label only; the certificate is unchanged). */
|
|
166
|
+
readonly renameDeviceCredential: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
167
|
+
id: z.ZodString;
|
|
168
|
+
deviceName: z.ZodString;
|
|
169
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
170
|
+
renamed: z.ZodBoolean;
|
|
171
|
+
}, z.core.$strip>, "mutation">;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
export type IDeviceCredentialsProvider = InferProvider<typeof deviceCredentialsCapability>;
|