@ccmsg/protocol 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/common/auth.ts +50 -0
- package/src/fixtures/common.ts +9 -3
package/package.json
CHANGED
package/src/common/auth.ts
CHANGED
|
@@ -146,6 +146,43 @@ const ENROLL_CLAIMS_FIELDS = {
|
|
|
146
146
|
* own device is `device_label` on the record, and the two are worth telling
|
|
147
147
|
* apart when a list is read back later. */
|
|
148
148
|
issued_label: Type.Optional(Type.String({ maxLength: 128 })),
|
|
149
|
+
/** What to call the account in the authenticator, as the administrator who
|
|
150
|
+
* made the URL wrote it.
|
|
151
|
+
*
|
|
152
|
+
* It has to travel, because the page has to name the account before anything
|
|
153
|
+
* is created and has no other way to learn it: a passkey manager keeps the
|
|
154
|
+
* name the ceremony was given and shows it wherever the key is listed, so a
|
|
155
|
+
* URL that carried none would put the user handle — sixteen random bytes — in
|
|
156
|
+
* front of the person at every sign-in.
|
|
157
|
+
*
|
|
158
|
+
* Apart from `issued_label`, which is a note about who the URL was handed to
|
|
159
|
+
* and stays on the credential as exactly that. One value answering both would
|
|
160
|
+
* be an administrator's private memo shown to the person as their own name,
|
|
161
|
+
* with no way to correct either without the other.
|
|
162
|
+
*
|
|
163
|
+
* A starting point and not the answer: the registration form shows it and the
|
|
164
|
+
* person may say otherwise, and `auth.register.display_name` is what they
|
|
165
|
+
* settled. For a URL adding a passkey to somebody who exists, it is the name
|
|
166
|
+
* they already read themselves by, so a second key joins the same account. */
|
|
167
|
+
display_name: Type.Optional(Type.String({ maxLength: 128 })),
|
|
168
|
+
/** Every instance this enrolment hands the person, written by whichever one
|
|
169
|
+
* the ceremony lands on once it succeeds.
|
|
170
|
+
*
|
|
171
|
+
* The set is decided at the terminal that made the URL, because that is where
|
|
172
|
+
* "the instances this one knows of" is a question anybody can see the answer
|
|
173
|
+
* to. It has to travel, for the same reason the rest of the claims do: behind
|
|
174
|
+
* a load balancer the ceremony lands wherever it lands, and an instance that
|
|
175
|
+
* wrote the grantings it happened to know of would answer a different
|
|
176
|
+
* question than the one that was asked.
|
|
177
|
+
*
|
|
178
|
+
* Written when the enrolment succeeds and not before. A granting for somebody
|
|
179
|
+
* who never registered would sit in the replicated set naming a person no
|
|
180
|
+
* user record answers for — inert, since nothing could authenticate as them,
|
|
181
|
+
* but there to be read and impossible to tell from one that means something.
|
|
182
|
+
*
|
|
183
|
+
* Absent is the issuer's own instance alone, which is what `instance` already
|
|
184
|
+
* says. Naming it here as well is how a URL hands over more than one. */
|
|
185
|
+
instances: Type.Optional(Type.Array(InstanceId)),
|
|
149
186
|
} as const;
|
|
150
187
|
|
|
151
188
|
/** What an enrolment URL carries, as the instance that issued it reads it back.
|
|
@@ -220,6 +257,19 @@ export const AuthRegisterArgs = Type.Object({
|
|
|
220
257
|
/** What the person calls the device they are registering, for their own use
|
|
221
258
|
* when they later read back a list of several. Nothing is decided by it. */
|
|
222
259
|
device_label: Type.Optional(Type.String({ maxLength: 128 })),
|
|
260
|
+
/** What the person settled on being called, from the form the registration
|
|
261
|
+
* page showed them with the URL's `display_name` already in it.
|
|
262
|
+
*
|
|
263
|
+
* Here rather than left to the claims because the person is the one it is
|
|
264
|
+
* about: an administrator issuing the URL guesses at a name, and the person
|
|
265
|
+
* in front of the browser is who can say. It is what the authenticator was
|
|
266
|
+
* given as the account name, so what they see in their passkey manager and
|
|
267
|
+
* what they read themselves by here are the same string.
|
|
268
|
+
*
|
|
269
|
+
* Unstated leaves the claims' value standing. It authenticates nothing, like
|
|
270
|
+
* every other name here. Adding a passkey to somebody who already exists does
|
|
271
|
+
* not rename them — the account it joins is one they have already named. */
|
|
272
|
+
display_name: Type.Optional(Type.String({ maxLength: 128 })),
|
|
223
273
|
/** The challenge this registration answers, with the instance that can spend
|
|
224
274
|
* it — the same pairing an assertion carries, and for the same reason: the
|
|
225
275
|
* value also sits inside `client_data_json`, but who may consume it does not,
|
package/src/fixtures/common.ts
CHANGED
|
@@ -212,6 +212,7 @@ export const AUTH_REGISTER_REQUEST: Static<typeof AuthRegisterRequest> = {
|
|
|
212
212
|
token: ENROLL_TOKEN,
|
|
213
213
|
code: ENROLL_CODE,
|
|
214
214
|
device_label: "work laptop",
|
|
215
|
+
display_name: "kawaz",
|
|
215
216
|
challenge: CHALLENGE,
|
|
216
217
|
credential: {
|
|
217
218
|
id: "Y3JlZC1pZA",
|
|
@@ -390,9 +391,10 @@ export const AUTH_RESOLVE_REQUEST = {
|
|
|
390
391
|
} satisfies Static<typeof AuthResolveRequest>;
|
|
391
392
|
|
|
392
393
|
/** What the issuer answers about a URL that makes a person. It names the user
|
|
393
|
-
* the credential will be created against,
|
|
394
|
-
*
|
|
395
|
-
* lands on completes it
|
|
394
|
+
* the credential will be created against, posts to the address in front of the
|
|
395
|
+
* instances rather than to the issuer's own — whichever of them the answer
|
|
396
|
+
* lands on completes it — and names both instances the person is to own, which
|
|
397
|
+
* the receiver writes the grantings for. */
|
|
396
398
|
export const AUTH_RESOLVE_RESPONSE = {
|
|
397
399
|
ok: true,
|
|
398
400
|
request_id,
|
|
@@ -407,6 +409,8 @@ export const AUTH_RESOLVE_RESPONSE = {
|
|
|
407
409
|
jti: "01J9Z3W2Q",
|
|
408
410
|
user: USER,
|
|
409
411
|
issued_label: "for kawaz",
|
|
412
|
+
display_name: "kawaz",
|
|
413
|
+
instances: [instance, other_instance],
|
|
410
414
|
},
|
|
411
415
|
} satisfies Static<typeof AuthResolveResponse>;
|
|
412
416
|
|
|
@@ -425,6 +429,8 @@ export const AUTH_RESOLVE_ADD_OWNER_RESPONSE = {
|
|
|
425
429
|
expires_at: FIXTURE_NOW + 600_000,
|
|
426
430
|
jti: "01J9Z3W2R",
|
|
427
431
|
issued_label: "nuc, for kawaz",
|
|
432
|
+
display_name: "kawaz",
|
|
433
|
+
instances: [other_instance],
|
|
428
434
|
},
|
|
429
435
|
} satisfies Static<typeof AuthResolveResponse>;
|
|
430
436
|
|