@coreiam/auth 1.0.1 → 1.0.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.
@@ -4,10 +4,6 @@ export interface AuthResult {
4
4
  status: number;
5
5
  data: any;
6
6
  }
7
- /**
8
- * NEW: Securely gets the user session.
9
- * Handles 401 by attempting a silent refresh internally.
10
- */
11
7
  export declare function getSession(): Promise<CoreIAMIdentity | null>;
12
8
  export declare function loginActionSdk(identifier: string, password: string): Promise<AuthResult>;
13
9
  export declare function registerActionSdk(userData: any): Promise<AuthResult>;
@@ -9,6 +9,8 @@ exports.logoutActionSdk = logoutActionSdk;
9
9
  const headers_1 = require("next/headers");
10
10
  const core_1 = require("../core");
11
11
  const iam = new core_1.CoreIAM();
12
+ // GLOBAL LOCK: Prevents concurrent refresh requests
13
+ let refreshLock = null;
12
14
  async function syncCookiesToNext(response) {
13
15
  const cookieStore = await (0, headers_1.cookies)();
14
16
  const setCookies = response.headers.getSetCookie();
@@ -58,30 +60,38 @@ async function syncCookiesToNext(response) {
58
60
  }
59
61
  }
60
62
  }
61
- /**
62
- * NEW: Securely gets the user session.
63
- * Handles 401 by attempting a silent refresh internally.
64
- */
65
63
  async function getSession() {
66
64
  const reqHeaders = await (0, headers_1.headers)();
67
65
  let response = await iam.proxy('/auth/profile', { method: 'GET' }, reqHeaders);
68
66
  if (response.status === 401) {
69
- const refreshRes = await iam.proxy('/auth/refresh-token', { method: 'POST' }, reqHeaders);
70
- if (refreshRes.ok) {
71
- const setCookies = refreshRes.headers.getSetCookie();
72
- if (setCookies && setCookies.length > 0) {
73
- const fakeRes = new Response(null, { headers: { 'set-cookie': setCookies.join(', ') } });
74
- await syncCookiesToNext(fakeRes);
75
- const cookieStore = await (0, headers_1.cookies)();
76
- const newJwt = cookieStore.get('jwt')?.value;
77
- const newRefresh = cookieStore.get('refreshToken')?.value;
78
- const retryHeaders = new Headers(reqHeaders);
79
- if (newJwt && newRefresh) {
80
- retryHeaders.set('cookie', `jwt=${newJwt}; refreshToken=${newRefresh}`);
81
- retryHeaders.set('Authorization', `Bearer ${newJwt}`);
82
- }
83
- response = await iam.proxy('/auth/profile', { method: 'GET' }, retryHeaders);
67
+ // 1. Use the lock! If another component is already refreshing, wait for it.
68
+ if (!refreshLock) {
69
+ refreshLock = iam.proxy('/auth/refresh-token', { method: 'POST' }, reqHeaders)
70
+ .then(res => res.ok ? res.headers.getSetCookie() : null)
71
+ .finally(() => { refreshLock = null; }); // Clear lock when done
72
+ }
73
+ const setCookies = await refreshLock;
74
+ if (setCookies && setCookies.length > 0) {
75
+ // 2. Sync the new cookies to the browser
76
+ const fakeRes = new Response(null, { headers: { 'set-cookie': setCookies.join(', ') } });
77
+ await syncCookiesToNext(fakeRes);
78
+ // 3. Build new headers with the refreshed cookies and retry
79
+ const cookieStore = await (0, headers_1.cookies)();
80
+ const newJwt = cookieStore.get('jwt')?.value;
81
+ const newRefresh = cookieStore.get('refreshToken')?.value;
82
+ const retryHeaders = new Headers(reqHeaders);
83
+ if (newJwt && newRefresh) {
84
+ retryHeaders.set('cookie', `jwt=${newJwt}; refreshToken=${newRefresh}`);
85
+ retryHeaders.set('Authorization', `Bearer ${newJwt}`);
84
86
  }
87
+ response = await iam.proxy('/auth/profile', { method: 'GET' }, retryHeaders);
88
+ }
89
+ else {
90
+ // 4. CRITICAL: If refresh failed, CLEAR THE COOKIES to break the infinite loop!
91
+ const cookieStore = await (0, headers_1.cookies)();
92
+ cookieStore.delete('jwt');
93
+ cookieStore.delete('refreshToken');
94
+ return null;
85
95
  }
86
96
  }
87
97
  if (!response.ok)
@@ -89,7 +99,6 @@ async function getSession() {
89
99
  const coreIamIdentity = await response.json();
90
100
  if (!coreIamIdentity?.sub)
91
101
  return null;
92
- // Return the Provider's Identity, NOT the Customer's User
93
102
  return coreIamIdentity;
94
103
  }
95
104
  async function loginActionSdk(identifier, password) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreiam/auth",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "main": "./dist/core/index.js",
5
5
  "types": "./dist/core/index.d.ts",
6
6
  "exports": {