js-bao-wss-client 2.1.1 → 2.1.2

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.
@@ -2827,9 +2827,17 @@ export declare class JsBaoClient extends Observable<any> {
2827
2827
  }>;
2828
2828
  /**
2829
2829
  * Start the passkey authentication flow, returns challenge options for the browser.
2830
+ * @param params - Optional flow parameters
2831
+ * @param params.rpId - The relying party to run the ceremony against. Must be
2832
+ * one of the app's configured passkey relying parties, else the call fails
2833
+ * with `PASSKEY_RP_NOT_CONFIGURED`. Omit it in a browser, where the server
2834
+ * derives the relying party from the request's `Origin`; name it from a
2835
+ * native client, which sends no `Origin` at all.
2830
2836
  * @group Authentication
2831
2837
  */
2832
- passkeyAuthStart(): Promise<{
2838
+ passkeyAuthStart(params?: {
2839
+ rpId?: string;
2840
+ }): Promise<{
2833
2841
  options: any;
2834
2842
  challengeToken: string;
2835
2843
  }>;
@@ -2849,9 +2857,16 @@ export declare class JsBaoClient extends Observable<any> {
2849
2857
  }>;
2850
2858
  /**
2851
2859
  * Start registering a new passkey for the current user.
2860
+ * @param params - Optional flow parameters
2861
+ * @param params.rpId - The relying party to register the passkey under. Must
2862
+ * be one of the app's configured passkey relying parties, else the call
2863
+ * fails with `PASSKEY_RP_NOT_CONFIGURED`. Omit it in a browser; name it
2864
+ * from a native client, which sends no `Origin` header.
2852
2865
  * @group Authentication
2853
2866
  */
2854
- passkeyRegisterStart(): Promise<{
2867
+ passkeyRegisterStart(params?: {
2868
+ rpId?: string;
2869
+ }): Promise<{
2855
2870
  options: any;
2856
2871
  challengeToken: string;
2857
2872
  }>;
@@ -7296,10 +7296,16 @@ export class JsBaoClient extends Observable {
7296
7296
  // ============ Passkey Auth Methods ============
7297
7297
  /**
7298
7298
  * Start the passkey authentication flow, returns challenge options for the browser.
7299
+ * @param params - Optional flow parameters
7300
+ * @param params.rpId - The relying party to run the ceremony against. Must be
7301
+ * one of the app's configured passkey relying parties, else the call fails
7302
+ * with `PASSKEY_RP_NOT_CONFIGURED`. Omit it in a browser, where the server
7303
+ * derives the relying party from the request's `Origin`; name it from a
7304
+ * native client, which sends no `Origin` at all.
7299
7305
  * @group Authentication
7300
7306
  */
7301
- async passkeyAuthStart() {
7302
- return this.auth.passkeyAuthStart();
7307
+ async passkeyAuthStart(params) {
7308
+ return this.auth.passkeyAuthStart(params);
7303
7309
  }
7304
7310
  /**
7305
7311
  * Complete passkey authentication with the browser's credential response.
@@ -7315,10 +7321,15 @@ export class JsBaoClient extends Observable {
7315
7321
  // ============ Passkey Registration Methods (Add to Existing Account) ============
7316
7322
  /**
7317
7323
  * Start registering a new passkey for the current user.
7324
+ * @param params - Optional flow parameters
7325
+ * @param params.rpId - The relying party to register the passkey under. Must
7326
+ * be one of the app's configured passkey relying parties, else the call
7327
+ * fails with `PASSKEY_RP_NOT_CONFIGURED`. Omit it in a browser; name it
7328
+ * from a native client, which sends no `Origin` header.
7318
7329
  * @group Authentication
7319
7330
  */
7320
- async passkeyRegisterStart() {
7321
- return this.auth.passkeyRegisterStart();
7331
+ async passkeyRegisterStart(params) {
7332
+ return this.auth.passkeyRegisterStart(params);
7322
7333
  }
7323
7334
  /**
7324
7335
  * Complete passkey registration with the browser's credential response.
@@ -4814,6 +4814,8 @@
4814
4814
  INVALID_TOKEN: "INVALID_TOKEN",
4815
4815
  TOKEN_EXPIRED: "TOKEN_EXPIRED",
4816
4816
  PASSKEY_NOT_ENABLED: "PASSKEY_NOT_ENABLED",
4817
+ // A passkey start call named an `rpId` the app does not configure (#3024).
4818
+ PASSKEY_RP_NOT_CONFIGURED: "PASSKEY_RP_NOT_CONFIGURED",
4817
4819
  MAGIC_LINK_NOT_ENABLED: "MAGIC_LINK_NOT_ENABLED",
4818
4820
  WAITLIST_ENTRY_UPDATED: "WAITLIST_ENTRY_UPDATED",
4819
4821
  // Invite-token flow (#466)
@@ -5327,11 +5329,22 @@
5327
5329
  };
5328
5330
  }
5329
5331
  // ============ Passkey Auth Methods ============
5330
- async passkeyAuthStart() {
5332
+ /**
5333
+ * `rpId` names the relying party the ceremony runs under (#3024). The server
5334
+ * validates it against the app's configured relying parties; a blank one is
5335
+ * no request at all, so it is not sent.
5336
+ */
5337
+ passkeyStartBody(params) {
5338
+ const rpId = typeof params?.rpId === "string" && params.rpId.trim()
5339
+ ? params.rpId.trim()
5340
+ : undefined;
5341
+ return JSON.stringify(rpId ? { rpId } : {});
5342
+ }
5343
+ async passkeyAuthStart(params) {
5331
5344
  const response = await fetch(`${this.deps.apiUrl}/app/${this.deps.appId}/api/passkey/auth/start`, {
5332
5345
  method: "POST",
5333
5346
  headers: { "Content-Type": "application/json" },
5334
- body: JSON.stringify({}),
5347
+ body: this.passkeyStartBody(params),
5335
5348
  credentials: "include",
5336
5349
  });
5337
5350
  if (!response.ok) {
@@ -5360,13 +5373,14 @@
5360
5373
  return { user: data.user, isNewUser: data.isNewUser };
5361
5374
  }
5362
5375
  // ============ Passkey Registration Methods (Add to Existing Account) ============
5363
- async passkeyRegisterStart() {
5376
+ async passkeyRegisterStart(params) {
5364
5377
  const response = await fetch(`${this.deps.apiUrl}/app/${this.deps.appId}/api/passkey/register/start`, {
5365
5378
  method: "POST",
5366
5379
  headers: {
5367
5380
  "Content-Type": "application/json",
5368
5381
  Authorization: `Bearer ${this.token}`,
5369
5382
  },
5383
+ body: this.passkeyStartBody(params),
5370
5384
  credentials: "include",
5371
5385
  });
5372
5386
  if (!response.ok) {
@@ -6061,17 +6075,21 @@
6061
6075
  }
6062
6076
  const response = await fetch(requestUrl, init);
6063
6077
  if (!response.ok) {
6064
- let message = `OAuth callback failed (${response?.status})`;
6078
+ // Carry the server's typed code through, exactly as the email paths do
6079
+ // (#3003) — a waitlisted OAuth sign-in has to be branchable on
6080
+ // `AUTH_CODES.ADDED_TO_WAITLIST`, not on message text.
6081
+ const body = {};
6065
6082
  try {
6066
- const error = await response.json();
6067
- if (error && typeof error.error === "string" && error.error.length > 0) {
6068
- message = error.error;
6069
- }
6083
+ const parsed = await response.json();
6084
+ if (parsed && typeof parsed.error === "string" && parsed.error.length > 0)
6085
+ body.error = parsed.error;
6086
+ if (parsed && typeof parsed.code === "string" && parsed.code.length > 0)
6087
+ body.code = parsed.code;
6070
6088
  }
6071
6089
  catch (_) {
6072
6090
  // ignore JSON parse errors
6073
6091
  }
6074
- throw new Error(message);
6092
+ throw createAuthError(body, `OAuth callback failed (${response?.status})`);
6075
6093
  }
6076
6094
  const data = await response.json();
6077
6095
  const token = data?.token;
@@ -22358,10 +22376,16 @@
22358
22376
  // ============ Passkey Auth Methods ============
22359
22377
  /**
22360
22378
  * Start the passkey authentication flow, returns challenge options for the browser.
22379
+ * @param params - Optional flow parameters
22380
+ * @param params.rpId - The relying party to run the ceremony against. Must be
22381
+ * one of the app's configured passkey relying parties, else the call fails
22382
+ * with `PASSKEY_RP_NOT_CONFIGURED`. Omit it in a browser, where the server
22383
+ * derives the relying party from the request's `Origin`; name it from a
22384
+ * native client, which sends no `Origin` at all.
22361
22385
  * @group Authentication
22362
22386
  */
22363
- async passkeyAuthStart() {
22364
- return this.auth.passkeyAuthStart();
22387
+ async passkeyAuthStart(params) {
22388
+ return this.auth.passkeyAuthStart(params);
22365
22389
  }
22366
22390
  /**
22367
22391
  * Complete passkey authentication with the browser's credential response.
@@ -22377,10 +22401,15 @@
22377
22401
  // ============ Passkey Registration Methods (Add to Existing Account) ============
22378
22402
  /**
22379
22403
  * Start registering a new passkey for the current user.
22404
+ * @param params - Optional flow parameters
22405
+ * @param params.rpId - The relying party to register the passkey under. Must
22406
+ * be one of the app's configured passkey relying parties, else the call
22407
+ * fails with `PASSKEY_RP_NOT_CONFIGURED`. Omit it in a browser; name it
22408
+ * from a native client, which sends no `Origin` header.
22380
22409
  * @group Authentication
22381
22410
  */
22382
- async passkeyRegisterStart() {
22383
- return this.auth.passkeyRegisterStart();
22411
+ async passkeyRegisterStart(params) {
22412
+ return this.auth.passkeyRegisterStart(params);
22384
22413
  }
22385
22414
  /**
22386
22415
  * Complete passkey registration with the browser's credential response.
@@ -44,6 +44,7 @@ export declare const AUTH_CODES: {
44
44
  readonly INVALID_TOKEN: "INVALID_TOKEN";
45
45
  readonly TOKEN_EXPIRED: "TOKEN_EXPIRED";
46
46
  readonly PASSKEY_NOT_ENABLED: "PASSKEY_NOT_ENABLED";
47
+ readonly PASSKEY_RP_NOT_CONFIGURED: "PASSKEY_RP_NOT_CONFIGURED";
47
48
  readonly MAGIC_LINK_NOT_ENABLED: "MAGIC_LINK_NOT_ENABLED";
48
49
  readonly WAITLIST_ENTRY_UPDATED: "WAITLIST_ENTRY_UPDATED";
49
50
  readonly INVITE_TOKEN_INVALID: "INVITE_TOKEN_INVALID";
@@ -273,7 +274,15 @@ export declare class AuthController {
273
274
  };
274
275
  isNewUser?: boolean;
275
276
  }>;
276
- passkeyAuthStart(): Promise<{
277
+ /**
278
+ * `rpId` names the relying party the ceremony runs under (#3024). The server
279
+ * validates it against the app's configured relying parties; a blank one is
280
+ * no request at all, so it is not sent.
281
+ */
282
+ private passkeyStartBody;
283
+ passkeyAuthStart(params?: {
284
+ rpId?: string;
285
+ }): Promise<{
277
286
  options: any;
278
287
  challengeToken: string;
279
288
  }>;
@@ -288,7 +297,9 @@ export declare class AuthController {
288
297
  };
289
298
  isNewUser?: boolean;
290
299
  }>;
291
- passkeyRegisterStart(): Promise<{
300
+ passkeyRegisterStart(params?: {
301
+ rpId?: string;
302
+ }): Promise<{
292
303
  options: any;
293
304
  challengeToken: string;
294
305
  }>;
@@ -32,6 +32,8 @@ export const AUTH_CODES = {
32
32
  INVALID_TOKEN: "INVALID_TOKEN",
33
33
  TOKEN_EXPIRED: "TOKEN_EXPIRED",
34
34
  PASSKEY_NOT_ENABLED: "PASSKEY_NOT_ENABLED",
35
+ // A passkey start call named an `rpId` the app does not configure (#3024).
36
+ PASSKEY_RP_NOT_CONFIGURED: "PASSKEY_RP_NOT_CONFIGURED",
35
37
  MAGIC_LINK_NOT_ENABLED: "MAGIC_LINK_NOT_ENABLED",
36
38
  WAITLIST_ENTRY_UPDATED: "WAITLIST_ENTRY_UPDATED",
37
39
  // Invite-token flow (#466)
@@ -545,11 +547,22 @@ export class AuthController {
545
547
  };
546
548
  }
547
549
  // ============ Passkey Auth Methods ============
548
- async passkeyAuthStart() {
550
+ /**
551
+ * `rpId` names the relying party the ceremony runs under (#3024). The server
552
+ * validates it against the app's configured relying parties; a blank one is
553
+ * no request at all, so it is not sent.
554
+ */
555
+ passkeyStartBody(params) {
556
+ const rpId = typeof params?.rpId === "string" && params.rpId.trim()
557
+ ? params.rpId.trim()
558
+ : undefined;
559
+ return JSON.stringify(rpId ? { rpId } : {});
560
+ }
561
+ async passkeyAuthStart(params) {
549
562
  const response = await fetch(`${this.deps.apiUrl}/app/${this.deps.appId}/api/passkey/auth/start`, {
550
563
  method: "POST",
551
564
  headers: { "Content-Type": "application/json" },
552
- body: JSON.stringify({}),
565
+ body: this.passkeyStartBody(params),
553
566
  credentials: "include",
554
567
  });
555
568
  if (!response.ok) {
@@ -578,13 +591,14 @@ export class AuthController {
578
591
  return { user: data.user, isNewUser: data.isNewUser };
579
592
  }
580
593
  // ============ Passkey Registration Methods (Add to Existing Account) ============
581
- async passkeyRegisterStart() {
594
+ async passkeyRegisterStart(params) {
582
595
  const response = await fetch(`${this.deps.apiUrl}/app/${this.deps.appId}/api/passkey/register/start`, {
583
596
  method: "POST",
584
597
  headers: {
585
598
  "Content-Type": "application/json",
586
599
  Authorization: `Bearer ${this.token}`,
587
600
  },
601
+ body: this.passkeyStartBody(params),
588
602
  credentials: "include",
589
603
  });
590
604
  if (!response.ok) {
@@ -1281,17 +1295,21 @@ export async function exchangeOAuthCode(params) {
1281
1295
  }
1282
1296
  const response = await fetch(requestUrl, init);
1283
1297
  if (!response.ok) {
1284
- let message = `OAuth callback failed (${response?.status})`;
1298
+ // Carry the server's typed code through, exactly as the email paths do
1299
+ // (#3003) — a waitlisted OAuth sign-in has to be branchable on
1300
+ // `AUTH_CODES.ADDED_TO_WAITLIST`, not on message text.
1301
+ const body = {};
1285
1302
  try {
1286
- const error = await response.json();
1287
- if (error && typeof error.error === "string" && error.error.length > 0) {
1288
- message = error.error;
1289
- }
1303
+ const parsed = await response.json();
1304
+ if (parsed && typeof parsed.error === "string" && parsed.error.length > 0)
1305
+ body.error = parsed.error;
1306
+ if (parsed && typeof parsed.code === "string" && parsed.code.length > 0)
1307
+ body.code = parsed.code;
1290
1308
  }
1291
1309
  catch (_) {
1292
1310
  // ignore JSON parse errors
1293
1311
  }
1294
- throw new Error(message);
1312
+ throw createAuthError(body, `OAuth callback failed (${response?.status})`);
1295
1313
  }
1296
1314
  const data = await response.json();
1297
1315
  const token = data?.token;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-bao-wss-client",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "Client library for js-bao-wss Yjs WebSocket service",
5
5
  "author": "Primitive LLC",
6
6
  "license": "UNLICENSED",