@passlock/server 2.1.0 → 2.3.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.
Files changed (45) hide show
  1. package/dist/effect.d.ts +8 -0
  2. package/dist/effect.d.ts.map +1 -1
  3. package/dist/effect.js +8 -0
  4. package/dist/effect.js.map +1 -1
  5. package/dist/errors.d.ts +65 -0
  6. package/dist/errors.d.ts.map +1 -1
  7. package/dist/errors.js +36 -5
  8. package/dist/errors.js.map +1 -1
  9. package/dist/index.d.ts +63 -21
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +60 -18
  12. package/dist/index.js.map +1 -1
  13. package/dist/network.d.ts +3 -3
  14. package/dist/passkey/passkey.d.ts +267 -10
  15. package/dist/passkey/passkey.d.ts.map +1 -1
  16. package/dist/passkey/passkey.js +161 -5
  17. package/dist/passkey/passkey.js.map +1 -1
  18. package/dist/principal/principal.d.ts +45 -1
  19. package/dist/principal/principal.d.ts.map +1 -1
  20. package/dist/principal/principal.js +27 -0
  21. package/dist/principal/principal.js.map +1 -1
  22. package/dist/safe-result.d.ts +33 -0
  23. package/dist/safe-result.d.ts.map +1 -0
  24. package/dist/safe-result.js +35 -0
  25. package/dist/safe-result.js.map +1 -0
  26. package/dist/safe.d.ts +87 -30
  27. package/dist/safe.d.ts.map +1 -1
  28. package/dist/safe.js +90 -30
  29. package/dist/safe.js.map +1 -1
  30. package/dist/schemas/passkey.d.ts +160 -0
  31. package/dist/schemas/passkey.d.ts.map +1 -1
  32. package/dist/schemas/passkey.js +90 -12
  33. package/dist/schemas/passkey.js.map +1 -1
  34. package/dist/schemas/principal.d.ts +50 -0
  35. package/dist/schemas/principal.d.ts.map +1 -1
  36. package/dist/schemas/principal.js +30 -0
  37. package/dist/schemas/principal.js.map +1 -1
  38. package/dist/schemas/signup.d.ts +20 -0
  39. package/dist/schemas/signup.d.ts.map +1 -1
  40. package/dist/schemas/signup.js +10 -0
  41. package/dist/schemas/signup.js.map +1 -1
  42. package/dist/shared.d.ts +18 -0
  43. package/dist/shared.d.ts.map +1 -1
  44. package/dist/shared.js.map +1 -1
  45. package/package.json +6 -6
package/dist/network.d.ts CHANGED
@@ -66,7 +66,7 @@ export interface MatchStatusCases<Resp extends NetworkResponse = NetworkResponse
66
66
  readonly "5xx"?: MatchStatusHandler<Resp>;
67
67
  readonly orElse: MatchStatusHandler<Resp>;
68
68
  }
69
- declare const NetworkRequestError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
69
+ declare const NetworkRequestError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
70
70
  readonly _tag: "@error/NetworkRequest";
71
71
  } & Readonly<A>;
72
72
  /**
@@ -78,7 +78,7 @@ export declare class NetworkRequestError extends NetworkRequestError_base<{
78
78
  readonly message: string;
79
79
  }> {
80
80
  }
81
- declare const NetworkPayloadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
81
+ declare const NetworkPayloadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
82
82
  readonly _tag: "@error/NetworkPayload";
83
83
  } & Readonly<A>;
84
84
  /**
@@ -89,7 +89,7 @@ export declare class NetworkPayloadError extends NetworkPayloadError_base<{
89
89
  readonly message: string;
90
90
  }> {
91
91
  }
92
- declare const NetworkResponseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
92
+ declare const NetworkResponseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
93
93
  readonly _tag: "@error/NetworkResponse";
94
94
  } & Readonly<A>;
95
95
  /**
@@ -4,9 +4,14 @@ import { ForbiddenError, NotFoundError } from "../schemas/index.js";
4
4
  import * as PasskeySchemas from "../schemas/passkey.js";
5
5
  import type { AuthenticatedOptions } from "../shared.js";
6
6
  /**
7
- * WebAuthn specific passkey data
7
+ * WebAuthn-specific credential data stored for a passkey in the Passlock vault.
8
+ *
9
+ * The `id` and `userId` fields are the underlying WebAuthn values, encoded as
10
+ * Base64URL strings.
11
+ *
12
+ * @category Passkeys
8
13
  */
9
- export type Credential = {
14
+ export type PasskeyCredential = {
10
15
  id: string;
11
16
  userId: string;
12
17
  username: string;
@@ -31,13 +36,15 @@ export type Credential = {
31
36
  *
32
37
  * We've also included links to icons (SVG) so you can give your users
33
38
  * a quick visual indication.
39
+ *
40
+ * @category Passkeys
34
41
  */
35
42
  export type Platform = {
36
43
  name?: string | undefined;
37
44
  icon?: string | undefined;
38
45
  };
39
46
  /**
40
- * The server-side component of a passkey
47
+ * The server-side representation of a passkey stored in the Passlock vault.
41
48
  *
42
49
  * @category Passkeys
43
50
  */
@@ -52,13 +59,23 @@ export type Passkey = {
52
59
  */
53
60
  userId?: string | undefined;
54
61
  enabled: boolean;
55
- credential: Credential;
62
+ credential: PasskeyCredential;
56
63
  platform?: Platform | undefined;
57
64
  lastUsed?: number | undefined;
58
65
  createdAt: number;
59
66
  updatedAt: number;
60
67
  };
68
+ /**
69
+ * Type guard for {@link Passkey}.
70
+ *
71
+ * @category Passkeys
72
+ */
61
73
  export declare const isPasskey: (payload: unknown) => payload is Passkey;
74
+ /**
75
+ * Compact passkey payload returned by list operations.
76
+ *
77
+ * @category Passkeys
78
+ */
62
79
  export type PasskeySummary = {
63
80
  readonly _tag: "PasskeySummary";
64
81
  readonly id: string;
@@ -71,20 +88,96 @@ export type PasskeySummary = {
71
88
  readonly lastUsed?: number | undefined;
72
89
  readonly createdAt: number;
73
90
  };
91
+ /**
92
+ * Type guard for {@link PasskeySummary}.
93
+ *
94
+ * @category Passkeys
95
+ */
74
96
  export declare const isPasskeySummary: (payload: unknown) => payload is PasskeySummary;
97
+ /**
98
+ * Result payload returned when passkeys are updated in bulk for a user.
99
+ *
100
+ * @category Passkeys
101
+ */
75
102
  export type UpdatedPasskeys = {
76
103
  _tag: "UpdatedPasskeys";
77
104
  updated: ReadonlyArray<Passkey>;
78
105
  };
106
+ /**
107
+ * Type guard for {@link UpdatedPasskeys}.
108
+ *
109
+ * @category Passkeys
110
+ */
79
111
  export declare const isUpdatedPasskeys: (payload: unknown) => payload is UpdatedPasskeys;
112
+ /**
113
+ * Credential identifiers returned by passkey deletion operations.
114
+ *
115
+ * @category Passkeys
116
+ */
117
+ export type Credential = {
118
+ credentialId: string;
119
+ userId: string;
120
+ rpId: string;
121
+ };
122
+ /**
123
+ * Result payload returned when a single passkey has been deleted.
124
+ *
125
+ * @category Passkeys
126
+ */
127
+ export type DeletedPasskey = {
128
+ _tag: "DeletedPasskey";
129
+ deleted: Credential;
130
+ };
131
+ /**
132
+ * Type guard for {@link DeletedPasskey}.
133
+ *
134
+ * @category Passkeys
135
+ */
136
+ export declare const isDeletedPasskey: (payload: unknown) => payload is DeletedPasskey;
137
+ /**
138
+ * Result payload returned when all passkeys for a user have been deleted.
139
+ *
140
+ * @category Passkeys
141
+ */
142
+ export type DeletedPasskeys = {
143
+ _tag: "DeletedPasskeys";
144
+ deleted: ReadonlyArray<Credential>;
145
+ };
146
+ /**
147
+ * Type guard for {@link DeletedPasskeys}.
148
+ *
149
+ * @category Passkeys
150
+ */
151
+ export declare const isDeletedPasskeys: (payload: unknown) => payload is DeletedPasskeys;
152
+ /**
153
+ * A single page of passkey summaries returned by {@link listPasskeys}.
154
+ *
155
+ * @category Passkeys
156
+ */
80
157
  export type FindAllPasskeys = {
81
158
  readonly _tag: "FindAllPasskeys";
82
159
  readonly cursor: string | null;
83
160
  readonly records: ReadonlyArray<PasskeySummary>;
84
161
  };
162
+ /**
163
+ * Type guard for {@link FindAllPasskeys}.
164
+ *
165
+ * @category Passkeys
166
+ */
85
167
  export declare const isFindAllPasskeys: (payload: unknown) => payload is FindAllPasskeys;
86
- export type UpdatedPasskeyUsernames = {
87
- _tag: "UpdatedPasskeyUsernames";
168
+ /**
169
+ * Client-facing credential update payload returned by
170
+ * {@link updatePasskeyUsernames}.
171
+ *
172
+ * Each entry describes one credential to update on the user's device. The
173
+ * returned `displayName` is derived from
174
+ * {@link UpdateUsernamesOptions#displayName} when provided, otherwise it falls
175
+ * back to the stored username.
176
+ *
177
+ * @category Passkeys
178
+ */
179
+ export type UpdatedCredentials = {
180
+ _tag: "UpdatedCredentials";
88
181
  credentials: ReadonlyArray<{
89
182
  rpId: string;
90
183
  userId: string;
@@ -92,41 +185,205 @@ export type UpdatedPasskeyUsernames = {
92
185
  displayName: string;
93
186
  }>;
94
187
  };
95
- export declare const isUpdatedPasskeyUsernames: (payload: unknown) => payload is UpdatedPasskeyUsernames;
188
+ /**
189
+ * Narrow an unknown value to an `UpdatedCredentials`-tagged payload.
190
+ *
191
+ * @category Passkeys
192
+ */
193
+ export declare const isUpdatedUserDetails: (payload: unknown) => payload is UpdatedCredentials;
194
+ /**
195
+ * Options for fetching a single passkey.
196
+ *
197
+ * @category Passkeys
198
+ */
96
199
  export interface GetPasskeyOptions extends AuthenticatedOptions {
200
+ /**
201
+ * Identifier of the passkey to fetch.
202
+ */
97
203
  passkeyId: string;
98
204
  }
205
+ /**
206
+ * Fetch a single passkey from the Passlock vault.
207
+ *
208
+ * @param options Request options including the passkey identifier.
209
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
210
+ * @returns An Effect that succeeds with the requested passkey.
211
+ *
212
+ * @category Passkeys
213
+ */
99
214
  export declare const getPasskey: (options: GetPasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<Passkey, NotFoundError | ForbiddenError>;
215
+ /**
216
+ * Options for deleting a single passkey.
217
+ *
218
+ * @category Passkeys
219
+ */
100
220
  export interface DeletePasskeyOptions extends AuthenticatedOptions {
221
+ /**
222
+ * Identifier of the passkey to delete.
223
+ */
101
224
  passkeyId: string;
102
225
  }
103
- export declare const deletePasskey: (options: DeletePasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<Passkey, NotFoundError | ForbiddenError>;
104
226
  /**
227
+ * Delete a single passkey from the Passlock vault.
228
+ *
229
+ * This only removes the server-side record. It does not remove the passkey
230
+ * from the user's device.
231
+ *
232
+ * @param options Request options including the passkey identifier.
233
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
234
+ * @returns An Effect that succeeds with the deleted credential.
235
+ *
236
+ * @category Passkeys
237
+ */
238
+ export declare const deletePasskey: (options: DeletePasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<DeletedPasskey, NotFoundError | ForbiddenError>;
239
+ /**
240
+ * Options for assigning a custom user ID to a single passkey.
241
+ *
105
242
  * @category Passkeys
106
243
  */
107
244
  export interface AssignUserOptions extends AuthenticatedOptions {
245
+ /**
246
+ * Identifier of the passkey to update.
247
+ */
108
248
  passkeyId: string;
109
249
  /**
110
250
  * Custom User ID to align with your own systems
111
251
  */
112
252
  userId: string;
113
253
  }
254
+ /**
255
+ * Assign a custom user ID to a single passkey.
256
+ *
257
+ * This updates Passlock's mapping for the passkey. It does not change the
258
+ * underlying WebAuthn credential's `userId`.
259
+ *
260
+ * @param options Request options including the passkey identifier and custom user ID.
261
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
262
+ * @returns An Effect that succeeds with the updated passkey.
263
+ *
264
+ * @category Passkeys
265
+ */
114
266
  export declare const assignUser: (options: AssignUserOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<Passkey, NotFoundError | ForbiddenError>;
267
+ /**
268
+ * Options for updating a single passkey's metadata.
269
+ *
270
+ * @category Passkeys
271
+ */
115
272
  export interface UpdatePasskeyOptions extends AuthenticatedOptions {
273
+ /**
274
+ * Identifier of the passkey to update.
275
+ */
116
276
  passkeyId: string;
277
+ /**
278
+ * Custom user ID to associate with the passkey.
279
+ */
117
280
  userId?: string;
281
+ /**
282
+ * Username metadata stored alongside the passkey.
283
+ */
118
284
  username?: string;
119
285
  }
286
+ /**
287
+ * Update a single passkey's custom user ID and/or username metadata.
288
+ *
289
+ * @param options Request options including the passkey identifier and fields to update.
290
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
291
+ * @returns An Effect that succeeds with the updated passkey.
292
+ *
293
+ * @category Passkeys
294
+ */
120
295
  export declare const updatePasskey: (options: UpdatePasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<Passkey, NotFoundError | ForbiddenError>;
121
- export interface UpdatePasskeyUsernamesOptions extends AuthenticatedOptions {
296
+ /**
297
+ * Options for deleting all passkeys belonging to a user.
298
+ *
299
+ * @category Passkeys
300
+ */
301
+ export interface DeleteUserPasskeysOptions extends AuthenticatedOptions {
302
+ /**
303
+ * Custom user ID whose passkeys should be deleted.
304
+ */
122
305
  userId: string;
306
+ }
307
+ /**
308
+ * Delete all passkeys associated with a custom user ID.
309
+ *
310
+ * The resulting `deleted` credentials can be passed to
311
+ * `@passlock/client` to remove the corresponding passkeys from the user's
312
+ * device.
313
+ *
314
+ * @param options Request options including the custom user ID.
315
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
316
+ * @returns An Effect that succeeds with the deleted credential identifiers.
317
+ *
318
+ * @category Passkeys
319
+ */
320
+ export declare const deleteUserPasskeys: (options: DeleteUserPasskeysOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<DeletedPasskeys, NotFoundError | ForbiddenError>;
321
+ /**
322
+ * Options for updating username metadata for all passkeys that share a custom
323
+ * user ID, plus optional display-name data to return for client-side updates.
324
+ *
325
+ * @category Passkeys
326
+ */
327
+ export interface UpdateUsernamesOptions extends AuthenticatedOptions {
328
+ /**
329
+ * Custom user ID whose passkeys should be updated.
330
+ */
331
+ userId: string;
332
+ /**
333
+ * Username to write back to each stored passkey.
334
+ */
123
335
  username: string;
336
+ /**
337
+ * Optional display name to return for client-side credential updates.
338
+ *
339
+ * When omitted, the returned credentials use `username` as the display name.
340
+ */
124
341
  displayName?: string;
125
342
  }
126
- export declare const updatePasskeyUsernames: (options: UpdatePasskeyUsernamesOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<UpdatedPasskeyUsernames, NotFoundError | ForbiddenError>;
343
+ /**
344
+ * Update the username metadata for all passkeys belonging to a custom user ID.
345
+ *
346
+ * The resulting payload is designed to be passed to
347
+ * `@passlock/client` so matching device credentials can be updated.
348
+ * The optional `displayName` is not stored in Passlock; it is only copied into
349
+ * the returned client payload.
350
+ *
351
+ * @param options Request options including the custom user ID and username metadata.
352
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
353
+ * @returns An Effect that succeeds with one credential update per updated passkey.
354
+ *
355
+ * @category Passkeys
356
+ */
357
+ export declare const updatePasskeyUsernames: (options: UpdateUsernamesOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<UpdatedCredentials, NotFoundError | ForbiddenError>;
358
+ /**
359
+ * Stream every passkey summary for a tenancy across all result pages.
360
+ *
361
+ * @param options Request options used for each paginated request.
362
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
363
+ * @returns A stream of passkey summaries.
364
+ *
365
+ * @category Passkeys
366
+ */
127
367
  export declare const listPasskeysStream: (options: AuthenticatedOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Stream.Stream<PasskeySummary, ForbiddenError>;
368
+ /**
369
+ * Options for listing passkeys.
370
+ *
371
+ * @category Passkeys
372
+ */
128
373
  export interface ListPasskeyOptions extends AuthenticatedOptions {
374
+ /**
375
+ * Pagination cursor returned from a previous {@link listPasskeys} call.
376
+ */
129
377
  cursor?: string;
130
378
  }
379
+ /**
380
+ * Fetch a single page of passkey summaries for a tenancy.
381
+ *
382
+ * @param options Request options including an optional pagination cursor.
383
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
384
+ * @returns An Effect that succeeds with one page of passkey summaries.
385
+ *
386
+ * @category Passkeys
387
+ */
131
388
  export declare const listPasskeys: (options: ListPasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<FindAllPasskeys, ForbiddenError>;
132
389
  //# sourceMappingURL=passkey.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"passkey.d.ts","sourceRoot":"","sources":["../../src/passkey/passkey.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"passkey.d.ts","sourceRoot":"","sources":["../../src/passkey/passkey.ts"],"names":[],"mappings":"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"}
@@ -2,11 +2,48 @@ import { Array, Chunk, Effect, Match, Option, pipe, Schema, Stream, } from "effe
2
2
  import { fetchNetwork, matchStatus, NetworkFetchLive, } from "../network.js";
3
3
  import { FindAllPasskeys as FindAllPasskeysSchema, ForbiddenError, NotFoundError, } from "../schemas/index.js";
4
4
  import * as PasskeySchemas from "../schemas/passkey.js";
5
+ /**
6
+ * Type guard for {@link Passkey}.
7
+ *
8
+ * @category Passkeys
9
+ */
5
10
  export const isPasskey = (payload) => Schema.is(PasskeySchemas.Passkey)(payload);
11
+ /**
12
+ * Type guard for {@link PasskeySummary}.
13
+ *
14
+ * @category Passkeys
15
+ */
6
16
  export const isPasskeySummary = (payload) => Schema.is(PasskeySchemas.PasskeySummary)(payload);
17
+ /**
18
+ * Type guard for {@link UpdatedPasskeys}.
19
+ *
20
+ * @category Passkeys
21
+ */
7
22
  export const isUpdatedPasskeys = (payload) => Schema.is(PasskeySchemas.UpdatedPasskeys)(payload);
23
+ /**
24
+ * Type guard for {@link DeletedPasskey}.
25
+ *
26
+ * @category Passkeys
27
+ */
28
+ export const isDeletedPasskey = (payload) => Schema.is(PasskeySchemas.DeletedPasskey)(payload);
29
+ /**
30
+ * Type guard for {@link DeletedPasskeys}.
31
+ *
32
+ * @category Passkeys
33
+ */
34
+ export const isDeletedPasskeys = (payload) => Schema.is(PasskeySchemas.DeletedPasskeys)(payload);
35
+ /**
36
+ * Type guard for {@link FindAllPasskeys}.
37
+ *
38
+ * @category Passkeys
39
+ */
8
40
  export const isFindAllPasskeys = (payload) => Schema.is(PasskeySchemas.FindAllPasskeys)(payload);
9
- export const isUpdatedPasskeyUsernames = (payload) => {
41
+ /**
42
+ * Narrow an unknown value to an `UpdatedCredentials`-tagged payload.
43
+ *
44
+ * @category Passkeys
45
+ */
46
+ export const isUpdatedUserDetails = (payload) => {
10
47
  if (typeof payload !== "object")
11
48
  return false;
12
49
  if (payload === null)
@@ -15,15 +52,24 @@ export const isUpdatedPasskeyUsernames = (payload) => {
15
52
  return false;
16
53
  if (typeof payload._tag !== "string")
17
54
  return false;
18
- if (payload._tag !== "UpdatedPasskeyUsernames")
55
+ if (payload._tag !== "UpdatedCredentials")
19
56
  return false;
20
57
  return true;
21
58
  };
22
- /* END UpdatedPasskeyUsernames */
59
+ /* END UpdatedUserDetails */
23
60
  const authorizationHeaders = (apiKey) => ({
24
61
  authorization: `Bearer ${apiKey}`,
25
62
  });
26
63
  const decodeResponseJson = (response, schema) => pipe(response.json, Effect.flatMap(Schema.decodeUnknown(schema)));
64
+ /**
65
+ * Fetch a single passkey from the Passlock vault.
66
+ *
67
+ * @param options Request options including the passkey identifier.
68
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
69
+ * @returns An Effect that succeeds with the requested passkey.
70
+ *
71
+ * @category Passkeys
72
+ */
27
73
  export const getPasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
28
74
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
29
75
  const { tenancyId, passkeyId } = options;
@@ -42,6 +88,18 @@ export const getPasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Effec
42
88
  "@error/NetworkResponse": (err) => Effect.die(err),
43
89
  ParseError: (err) => Effect.die(err),
44
90
  }), Effect.provide(fetchLayer));
91
+ /**
92
+ * Delete a single passkey from the Passlock vault.
93
+ *
94
+ * This only removes the server-side record. It does not remove the passkey
95
+ * from the user's device.
96
+ *
97
+ * @param options Request options including the passkey identifier.
98
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
99
+ * @returns An Effect that succeeds with the deleted credential.
100
+ *
101
+ * @category Passkeys
102
+ */
45
103
  export const deletePasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
46
104
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
47
105
  const { tenancyId, passkeyId } = options;
@@ -53,7 +111,14 @@ export const deletePasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Ef
53
111
  "2xx": (res) => decodeResponseJson(res, PasskeySchemas.Passkey),
54
112
  orElse: (res) => decodeResponseJson(res, Schema.Union(ForbiddenError, NotFoundError)),
55
113
  });
56
- return yield* pipe(Match.value(encoded), Match.tag("Passkey", (deletedPasskey) => Effect.succeed(deletedPasskey)), Match.tag("@error/Forbidden", (err) => Effect.fail(err)), Match.tag("@error/NotFound", (err) => Effect.fail(err)), Match.exhaustive);
114
+ return yield* pipe(Match.value(encoded), Match.tag("Passkey", (passkey) => Effect.succeed({
115
+ _tag: "DeletedPasskey",
116
+ deleted: {
117
+ credentialId: passkey.credential.id,
118
+ userId: passkey.credential.userId,
119
+ rpId: passkey.credential.rpId,
120
+ },
121
+ })), Match.tag("@error/Forbidden", (err) => Effect.fail(err)), Match.tag("@error/NotFound", (err) => Effect.fail(err)), Match.exhaustive);
57
122
  }), Effect.catchTags({
58
123
  "@error/NetworkPayload": (err) => Effect.die(err),
59
124
  "@error/NetworkRequest": (err) => Effect.die(err),
@@ -61,6 +126,18 @@ export const deletePasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Ef
61
126
  ParseError: (err) => Effect.die(err),
62
127
  }), Effect.provide(fetchLayer));
63
128
  // TODO reuse updatePasskey
129
+ /**
130
+ * Assign a custom user ID to a single passkey.
131
+ *
132
+ * This updates Passlock's mapping for the passkey. It does not change the
133
+ * underlying WebAuthn credential's `userId`.
134
+ *
135
+ * @param options Request options including the passkey identifier and custom user ID.
136
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
137
+ * @returns An Effect that succeeds with the updated passkey.
138
+ *
139
+ * @category Passkeys
140
+ */
64
141
  export const assignUser = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
65
142
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
66
143
  const { userId, passkeyId } = options;
@@ -80,6 +157,15 @@ export const assignUser = (options, fetchLayer = NetworkFetchLive) => pipe(Effec
80
157
  "@error/NetworkResponse": (err) => Effect.die(err),
81
158
  ParseError: (err) => Effect.die(err),
82
159
  }), Effect.provide(fetchLayer));
160
+ /**
161
+ * Update a single passkey's custom user ID and/or username metadata.
162
+ *
163
+ * @param options Request options including the passkey identifier and fields to update.
164
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
165
+ * @returns An Effect that succeeds with the updated passkey.
166
+ *
167
+ * @category Passkeys
168
+ */
83
169
  export const updatePasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
84
170
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
85
171
  const { userId, passkeyId, username } = options;
@@ -118,6 +204,58 @@ const updateUserPasskeys = (options, fetchLayer = NetworkFetchLive) => pipe(Effe
118
204
  "@error/NetworkResponse": (err) => Effect.die(err),
119
205
  ParseError: (err) => Effect.die(err),
120
206
  }), Effect.provide(fetchLayer));
207
+ /**
208
+ * Delete all passkeys associated with a custom user ID.
209
+ *
210
+ * The resulting `deleted` credentials can be passed to
211
+ * `@passlock/client` to remove the corresponding passkeys from the user's
212
+ * device.
213
+ *
214
+ * @param options Request options including the custom user ID.
215
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
216
+ * @returns An Effect that succeeds with the deleted credential identifiers.
217
+ *
218
+ * @category Passkeys
219
+ */
220
+ export const deleteUserPasskeys = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
221
+ const baseUrl = options.endpoint ?? "https://api.passlock.dev";
222
+ const { tenancyId, userId } = options;
223
+ const url = new URL(`/${tenancyId}/users/${userId}/passkeys/`, baseUrl);
224
+ const response = yield* fetchNetwork(url, "delete", { userId }, {
225
+ headers: authorizationHeaders(options.apiKey),
226
+ });
227
+ const encoded = yield* matchStatus(response, {
228
+ "2xx": (res) => decodeResponseJson(res, PasskeySchemas.DeletedPasskeysResponse),
229
+ orElse: (res) => decodeResponseJson(res, Schema.Union(NotFoundError, ForbiddenError)),
230
+ });
231
+ return yield* pipe(Match.value(encoded), Match.tag("DeletedPasskeys", (result) => Effect.succeed({
232
+ _tag: "DeletedPasskeys",
233
+ deleted: result.deleted.map((passkey) => ({
234
+ credentialId: passkey.credential.id,
235
+ userId: passkey.credential.userId,
236
+ rpId: passkey.credential.rpId,
237
+ })),
238
+ })), Match.tag("@error/NotFound", (err) => Effect.fail(err)), Match.tag("@error/Forbidden", (err) => Effect.fail(err)), Match.exhaustive);
239
+ }), Effect.catchTags({
240
+ "@error/NetworkPayload": (err) => Effect.die(err),
241
+ "@error/NetworkRequest": (err) => Effect.die(err),
242
+ "@error/NetworkResponse": (err) => Effect.die(err),
243
+ ParseError: (err) => Effect.die(err),
244
+ }), Effect.provide(fetchLayer));
245
+ /**
246
+ * Update the username metadata for all passkeys belonging to a custom user ID.
247
+ *
248
+ * The resulting payload is designed to be passed to
249
+ * `@passlock/client` so matching device credentials can be updated.
250
+ * The optional `displayName` is not stored in Passlock; it is only copied into
251
+ * the returned client payload.
252
+ *
253
+ * @param options Request options including the custom user ID and username metadata.
254
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
255
+ * @returns An Effect that succeeds with one credential update per updated passkey.
256
+ *
257
+ * @category Passkeys
258
+ */
121
259
  export const updatePasskeyUsernames = (options, fetchLayer = NetworkFetchLive) => pipe(updateUserPasskeys(options, fetchLayer), Effect.map((result) => result.updated), Effect.map(Array.map((passkey) => {
122
260
  return {
123
261
  rpId: passkey.credential.rpId,
@@ -126,14 +264,32 @@ export const updatePasskeyUsernames = (options, fetchLayer = NetworkFetchLive) =
126
264
  displayName: options.displayName ?? passkey.credential.username,
127
265
  };
128
266
  })), Effect.map((credentials) => ({
129
- _tag: "UpdatedPasskeyUsernames",
267
+ _tag: "UpdatedCredentials",
130
268
  credentials,
131
269
  })));
132
270
  /* List Passkeys */
271
+ /**
272
+ * Stream every passkey summary for a tenancy across all result pages.
273
+ *
274
+ * @param options Request options used for each paginated request.
275
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
276
+ * @returns A stream of passkey summaries.
277
+ *
278
+ * @category Passkeys
279
+ */
133
280
  export const listPasskeysStream = (options, fetchLayer = NetworkFetchLive) => pipe(Stream.paginateChunkEffect(null, (cursor) => pipe(listPasskeys(cursor ? { ...options, cursor } : options, fetchLayer), Effect.map((result) => [
134
281
  Chunk.fromIterable(result.records),
135
282
  Option.fromNullable(result.cursor),
136
283
  ]))));
284
+ /**
285
+ * Fetch a single page of passkey summaries for a tenancy.
286
+ *
287
+ * @param options Request options including an optional pagination cursor.
288
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
289
+ * @returns An Effect that succeeds with one page of passkey summaries.
290
+ *
291
+ * @category Passkeys
292
+ */
137
293
  export const listPasskeys = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
138
294
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
139
295
  const { tenancyId } = options;