@nauth-toolkit/client 0.1.83 → 0.1.85

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/index.d.mts CHANGED
@@ -1254,8 +1254,21 @@ declare class ChallengeRouter {
1254
1254
  navigateToChallenge(response: AuthResponse): Promise<void>;
1255
1255
  /**
1256
1256
  * Navigate to success URL.
1257
+ *
1258
+ * @param queryParams - Optional query parameters to append to the success URL
1259
+ *
1260
+ * @example
1261
+ * ```typescript
1262
+ * await router.navigateToSuccess({ appState: 'invite-code-123' });
1263
+ * ```
1264
+ */
1265
+ navigateToSuccess(queryParams?: Record<string, string>): Promise<void>;
1266
+ /**
1267
+ * Retrieve stored OAuth appState from storage.
1268
+ *
1269
+ * @returns Query params object with appState if present, undefined otherwise
1257
1270
  */
1258
- navigateToSuccess(): Promise<void>;
1271
+ private getStoredOauthState;
1259
1272
  /**
1260
1273
  * Navigate to error URL.
1261
1274
  *
@@ -1716,6 +1729,10 @@ declare class NAuthClient {
1716
1729
  private buildUrl;
1717
1730
  /**
1718
1731
  * Build request headers for authentication.
1732
+ *
1733
+ * @param auth - Whether to include authentication headers
1734
+ * @param method - HTTP method (GET, POST, PUT, DELETE, PATCH)
1735
+ * @returns Headers object with auth, CSRF, and device trust headers
1719
1736
  * @private
1720
1737
  */
1721
1738
  private buildHeaders;
@@ -1761,6 +1778,42 @@ declare class NAuthClient {
1761
1778
  * ```
1762
1779
  */
1763
1780
  getChallengeRouter(): ChallengeRouter;
1781
+ /**
1782
+ * Store OAuth appState from social redirect callback.
1783
+ *
1784
+ * This is called automatically by the social redirect callback guard
1785
+ * when appState is present in the callback URL. The stored state can
1786
+ * be retrieved using getLastOauthState().
1787
+ *
1788
+ * @param appState - OAuth appState value from callback URL
1789
+ *
1790
+ * @example
1791
+ * ```typescript
1792
+ * await client.storeOauthState('invite-code-123');
1793
+ * ```
1794
+ */
1795
+ storeOauthState(appState: string): Promise<void>;
1796
+ /**
1797
+ * Get the last OAuth appState from social redirect callback.
1798
+ *
1799
+ * Returns the appState that was stored during the most recent social
1800
+ * login redirect callback. This is useful for restoring UI state,
1801
+ * applying invite codes, or tracking referral information.
1802
+ *
1803
+ * The state is automatically cleared after retrieval to prevent reuse.
1804
+ *
1805
+ * @returns The stored appState, or null if none exists
1806
+ *
1807
+ * @example
1808
+ * ```typescript
1809
+ * const appState = await client.getLastOauthState();
1810
+ * if (appState) {
1811
+ * // Apply invite code or restore UI state
1812
+ * console.log('OAuth state:', appState);
1813
+ * }
1814
+ * ```
1815
+ */
1816
+ getLastOauthState(): Promise<string | null>;
1764
1817
  }
1765
1818
 
1766
1819
  /**
package/dist/index.d.ts CHANGED
@@ -1254,8 +1254,21 @@ declare class ChallengeRouter {
1254
1254
  navigateToChallenge(response: AuthResponse): Promise<void>;
1255
1255
  /**
1256
1256
  * Navigate to success URL.
1257
+ *
1258
+ * @param queryParams - Optional query parameters to append to the success URL
1259
+ *
1260
+ * @example
1261
+ * ```typescript
1262
+ * await router.navigateToSuccess({ appState: 'invite-code-123' });
1263
+ * ```
1264
+ */
1265
+ navigateToSuccess(queryParams?: Record<string, string>): Promise<void>;
1266
+ /**
1267
+ * Retrieve stored OAuth appState from storage.
1268
+ *
1269
+ * @returns Query params object with appState if present, undefined otherwise
1257
1270
  */
1258
- navigateToSuccess(): Promise<void>;
1271
+ private getStoredOauthState;
1259
1272
  /**
1260
1273
  * Navigate to error URL.
1261
1274
  *
@@ -1716,6 +1729,10 @@ declare class NAuthClient {
1716
1729
  private buildUrl;
1717
1730
  /**
1718
1731
  * Build request headers for authentication.
1732
+ *
1733
+ * @param auth - Whether to include authentication headers
1734
+ * @param method - HTTP method (GET, POST, PUT, DELETE, PATCH)
1735
+ * @returns Headers object with auth, CSRF, and device trust headers
1719
1736
  * @private
1720
1737
  */
1721
1738
  private buildHeaders;
@@ -1761,6 +1778,42 @@ declare class NAuthClient {
1761
1778
  * ```
1762
1779
  */
1763
1780
  getChallengeRouter(): ChallengeRouter;
1781
+ /**
1782
+ * Store OAuth appState from social redirect callback.
1783
+ *
1784
+ * This is called automatically by the social redirect callback guard
1785
+ * when appState is present in the callback URL. The stored state can
1786
+ * be retrieved using getLastOauthState().
1787
+ *
1788
+ * @param appState - OAuth appState value from callback URL
1789
+ *
1790
+ * @example
1791
+ * ```typescript
1792
+ * await client.storeOauthState('invite-code-123');
1793
+ * ```
1794
+ */
1795
+ storeOauthState(appState: string): Promise<void>;
1796
+ /**
1797
+ * Get the last OAuth appState from social redirect callback.
1798
+ *
1799
+ * Returns the appState that was stored during the most recent social
1800
+ * login redirect callback. This is useful for restoring UI state,
1801
+ * applying invite codes, or tracking referral information.
1802
+ *
1803
+ * The state is automatically cleared after retrieval to prevent reuse.
1804
+ *
1805
+ * @returns The stored appState, or null if none exists
1806
+ *
1807
+ * @example
1808
+ * ```typescript
1809
+ * const appState = await client.getLastOauthState();
1810
+ * if (appState) {
1811
+ * // Apply invite code or restore UI state
1812
+ * console.log('OAuth state:', appState);
1813
+ * }
1814
+ * ```
1815
+ */
1816
+ getLastOauthState(): Promise<string | null>;
1764
1817
  }
1765
1818
 
1766
1819
  /**
package/dist/index.mjs CHANGED
@@ -528,6 +528,7 @@ var FetchAdapter = class {
528
528
  };
529
529
 
530
530
  // src/core/challenge-router.ts
531
+ var OAUTH_STATE_KEY = "nauth_oauth_state";
531
532
  var ChallengeRouter = class {
532
533
  constructor(config) {
533
534
  this.config = config;
@@ -546,7 +547,8 @@ var ChallengeRouter = class {
546
547
  if (response.challengeName) {
547
548
  await this.navigateToChallenge(response);
548
549
  } else {
549
- await this.navigateToSuccess();
550
+ const queryParams = await this.getStoredOauthState();
551
+ await this.navigateToSuccess(queryParams);
550
552
  }
551
553
  }
552
554
  /**
@@ -560,11 +562,44 @@ var ChallengeRouter = class {
560
562
  }
561
563
  /**
562
564
  * Navigate to success URL.
565
+ *
566
+ * @param queryParams - Optional query parameters to append to the success URL
567
+ *
568
+ * @example
569
+ * ```typescript
570
+ * await router.navigateToSuccess({ appState: 'invite-code-123' });
571
+ * ```
563
572
  */
564
- async navigateToSuccess() {
565
- const url = this.config.redirects?.success || "/";
573
+ async navigateToSuccess(queryParams) {
574
+ let url = this.config.redirects?.success || "/";
575
+ if (queryParams && Object.keys(queryParams).length > 0) {
576
+ const searchParams = new URLSearchParams();
577
+ Object.entries(queryParams).forEach(([key, value]) => {
578
+ if (value) {
579
+ searchParams.set(key, value);
580
+ }
581
+ });
582
+ const queryString = searchParams.toString();
583
+ url = queryString ? `${url}${url.includes("?") ? "&" : "?"}${queryString}` : url;
584
+ }
566
585
  await this.navigate(url);
567
586
  }
587
+ /**
588
+ * Retrieve stored OAuth appState from storage.
589
+ *
590
+ * @returns Query params object with appState if present, undefined otherwise
591
+ */
592
+ async getStoredOauthState() {
593
+ try {
594
+ const stored = await this.config.storage.getItem(OAUTH_STATE_KEY);
595
+ if (stored) {
596
+ await this.config.storage.removeItem(OAUTH_STATE_KEY);
597
+ return { appState: stored };
598
+ }
599
+ } catch {
600
+ }
601
+ return void 0;
602
+ }
568
603
  /**
569
604
  * Navigate to error URL.
570
605
  *
@@ -679,6 +714,7 @@ var ChallengeRouter = class {
679
714
  // src/core/client.ts
680
715
  var USER_KEY2 = "nauth_user";
681
716
  var CHALLENGE_KEY2 = "nauth_challenge_session";
717
+ var OAUTH_STATE_KEY2 = "nauth_oauth_state";
682
718
  var hasWindow = () => typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
683
719
  var defaultStorage = () => {
684
720
  if (hasWindow() && typeof window.localStorage !== "undefined") {
@@ -1462,13 +1498,19 @@ var NAuthClient = class {
1462
1498
  }
1463
1499
  /**
1464
1500
  * Build request headers for authentication.
1501
+ *
1502
+ * @param auth - Whether to include authentication headers
1503
+ * @param method - HTTP method (GET, POST, PUT, DELETE, PATCH)
1504
+ * @returns Headers object with auth, CSRF, and device trust headers
1465
1505
  * @private
1466
1506
  */
1467
- async buildHeaders(auth) {
1507
+ async buildHeaders(auth, method = "GET") {
1468
1508
  const headers = {
1469
- "Content-Type": "application/json",
1470
1509
  ...this.config.headers
1471
1510
  };
1511
+ if (method !== "GET") {
1512
+ headers["Content-Type"] = "application/json";
1513
+ }
1472
1514
  if (auth && this.config.tokenDelivery === "json") {
1473
1515
  const accessToken = (await this.tokenManager.getTokens()).accessToken;
1474
1516
  if (accessToken) {
@@ -1484,7 +1526,8 @@ var NAuthClient = class {
1484
1526
  } catch {
1485
1527
  }
1486
1528
  }
1487
- if (this.config.tokenDelivery === "cookies" && hasWindow()) {
1529
+ const mutatingMethods = ["POST", "PUT", "PATCH", "DELETE"];
1530
+ if (this.config.tokenDelivery === "cookies" && hasWindow() && mutatingMethods.includes(method)) {
1488
1531
  const csrfToken = this.getCsrfToken();
1489
1532
  if (csrfToken) {
1490
1533
  headers[this.config.csrf.headerName] = csrfToken;
@@ -1507,7 +1550,7 @@ var NAuthClient = class {
1507
1550
  */
1508
1551
  async get(path, auth = false) {
1509
1552
  const url = this.buildUrl(path);
1510
- const headers = await this.buildHeaders(auth);
1553
+ const headers = await this.buildHeaders(auth, "GET");
1511
1554
  const credentials = this.config.tokenDelivery === "cookies" ? "include" : "omit";
1512
1555
  const response = await this.config.httpAdapter.request({
1513
1556
  method: "GET",
@@ -1523,7 +1566,7 @@ var NAuthClient = class {
1523
1566
  */
1524
1567
  async post(path, body, auth = false) {
1525
1568
  const url = this.buildUrl(path);
1526
- const headers = await this.buildHeaders(auth);
1569
+ const headers = await this.buildHeaders(auth, "POST");
1527
1570
  const credentials = this.config.tokenDelivery === "cookies" ? "include" : "omit";
1528
1571
  const response = await this.config.httpAdapter.request({
1529
1572
  method: "POST",
@@ -1540,7 +1583,7 @@ var NAuthClient = class {
1540
1583
  */
1541
1584
  async put(path, body, auth = false) {
1542
1585
  const url = this.buildUrl(path);
1543
- const headers = await this.buildHeaders(auth);
1586
+ const headers = await this.buildHeaders(auth, "PUT");
1544
1587
  const credentials = this.config.tokenDelivery === "cookies" ? "include" : "omit";
1545
1588
  const response = await this.config.httpAdapter.request({
1546
1589
  method: "PUT",
@@ -1557,7 +1600,7 @@ var NAuthClient = class {
1557
1600
  */
1558
1601
  async delete(path, auth = false) {
1559
1602
  const url = this.buildUrl(path);
1560
- const headers = await this.buildHeaders(auth);
1603
+ const headers = await this.buildHeaders(auth, "DELETE");
1561
1604
  const credentials = this.config.tokenDelivery === "cookies" ? "include" : "omit";
1562
1605
  const response = await this.config.httpAdapter.request({
1563
1606
  method: "DELETE",
@@ -1582,6 +1625,53 @@ var NAuthClient = class {
1582
1625
  getChallengeRouter() {
1583
1626
  return this.challengeRouter;
1584
1627
  }
1628
+ /**
1629
+ * Store OAuth appState from social redirect callback.
1630
+ *
1631
+ * This is called automatically by the social redirect callback guard
1632
+ * when appState is present in the callback URL. The stored state can
1633
+ * be retrieved using getLastOauthState().
1634
+ *
1635
+ * @param appState - OAuth appState value from callback URL
1636
+ *
1637
+ * @example
1638
+ * ```typescript
1639
+ * await client.storeOauthState('invite-code-123');
1640
+ * ```
1641
+ */
1642
+ async storeOauthState(appState) {
1643
+ if (appState && appState.trim() !== "") {
1644
+ await this.config.storage.setItem(OAUTH_STATE_KEY2, appState);
1645
+ }
1646
+ }
1647
+ /**
1648
+ * Get the last OAuth appState from social redirect callback.
1649
+ *
1650
+ * Returns the appState that was stored during the most recent social
1651
+ * login redirect callback. This is useful for restoring UI state,
1652
+ * applying invite codes, or tracking referral information.
1653
+ *
1654
+ * The state is automatically cleared after retrieval to prevent reuse.
1655
+ *
1656
+ * @returns The stored appState, or null if none exists
1657
+ *
1658
+ * @example
1659
+ * ```typescript
1660
+ * const appState = await client.getLastOauthState();
1661
+ * if (appState) {
1662
+ * // Apply invite code or restore UI state
1663
+ * console.log('OAuth state:', appState);
1664
+ * }
1665
+ * ```
1666
+ */
1667
+ async getLastOauthState() {
1668
+ const stored = await this.config.storage.getItem(OAUTH_STATE_KEY2);
1669
+ if (stored) {
1670
+ await this.config.storage.removeItem(OAUTH_STATE_KEY2);
1671
+ return stored;
1672
+ }
1673
+ return null;
1674
+ }
1585
1675
  };
1586
1676
 
1587
1677
  // src/core/challenge-helpers.ts