@coreiam/auth 1.0.4 → 1.0.5

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.
@@ -2,15 +2,17 @@
2
2
  // src/core/index.ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.CoreIAM = void 0;
5
- const DEFAULT_GATEWAY_URL = "https://api.e-qalam.com";
6
5
  class CoreIAM {
7
6
  apiKey = '';
8
7
  baseUrl = '';
9
8
  constructor(config) {
10
9
  this.apiKey = config?.apiKey || process.env.COREIAM_API_KEY || '';
11
- this.baseUrl = config?.baseUrl || DEFAULT_GATEWAY_URL;
10
+ // FIX: Removed hardcoded URL. Throw if missing.
11
+ this.baseUrl = config?.baseUrl || process.env.COREIAM_API_URL || '';
12
12
  if (!this.apiKey)
13
- throw new Error('CoreIAM: Missing API Key');
13
+ throw new Error('CoreIAM: Missing API Key (COREIAM_API_KEY)');
14
+ if (!this.baseUrl)
15
+ throw new Error('CoreIAM: Missing Gateway URL (COREIAM_API_URL)');
14
16
  }
15
17
  // Exposed publicly so the Next.js layer can use it for getSession()
16
18
  async refreshTokens(headers) {
@@ -5,6 +5,6 @@ import { NextRequest, NextResponse } from 'next/server';
5
5
  import { CoreIAM } from '../core';
6
6
  export declare class NextHandlers {
7
7
  private iam;
8
- constructor(iam: CoreIAM);
8
+ constructor(iam?: CoreIAM);
9
9
  handleProxy(req: NextRequest, internalPath: string): Promise<NextResponse<any>>;
10
10
  }
@@ -10,13 +10,16 @@ Object.defineProperty(exports, "loginActionSdk", { enumerable: true, get: functi
10
10
  Object.defineProperty(exports, "registerActionSdk", { enumerable: true, get: function () { return actions_1.registerActionSdk; } });
11
11
  Object.defineProperty(exports, "logoutActionSdk", { enumerable: true, get: function () { return actions_1.logoutActionSdk; } });
12
12
  Object.defineProperty(exports, "getSession", { enumerable: true, get: function () { return actions_1.getSession; } });
13
+ // FIX: Export the new handleCoreIamAuth function instead of the old middleware
13
14
  var middleware_1 = require("./middleware");
14
15
  Object.defineProperty(exports, "coreIamMiddleware", { enumerable: true, get: function () { return middleware_1.coreIamMiddleware; } });
15
16
  const server_1 = require("next/server");
17
+ const core_1 = require("../core");
16
18
  class NextHandlers {
17
19
  iam;
18
20
  constructor(iam) {
19
- this.iam = iam;
21
+ // If no iam client is provided, instantiate one using the env variables
22
+ this.iam = iam || new core_1.CoreIAM({ apiKey: process.env.COREIAM_API_KEY, baseUrl: process.env.COREIAM_API_URL });
20
23
  }
21
24
  async handleProxy(req, internalPath) {
22
25
  const method = internalPath === '/csrf' ? 'POST' : req.method;
@@ -1,2 +1,9 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- export declare function coreIamMiddleware(): (request: NextRequest) => Promise<NextResponse<unknown>>;
2
+ /**
3
+ * Handles CoreIAM token refresh and header rewriting.
4
+ * Returns the NextResponse to return, and whether the user is authenticated.
5
+ */
6
+ export declare function coreIamMiddleware(request: NextRequest): Promise<{
7
+ response: NextResponse;
8
+ isAuthenticated: boolean;
9
+ }>;
@@ -4,91 +4,79 @@ exports.coreIamMiddleware = coreIamMiddleware;
4
4
  // src/nextjs/middleware.ts
5
5
  const server_1 = require("next/server");
6
6
  const jwt_decode_1 = require("jwt-decode");
7
- const DEFAULT_GATEWAY_URL = "https://api.e-qalam.com";
8
- function coreIamMiddleware() {
9
- return async function middleware(request) {
10
- const { nextUrl } = request;
11
- const pathname = nextUrl.pathname;
12
- const jwtCookie = request.cookies.get("jwt");
13
- const refreshTokenCookie = request.cookies.get("refreshToken");
14
- let isLoggedIn = false;
15
- let needsRefresh = false;
16
- if (jwtCookie) {
17
- try {
18
- const decoded = (0, jwt_decode_1.jwtDecode)(jwtCookie.value);
19
- if (decoded.exp && decoded.exp * 1000 > Date.now()) {
20
- isLoggedIn = true;
21
- }
22
- else {
23
- if (refreshTokenCookie)
24
- needsRefresh = true;
25
- }
7
+ /**
8
+ * Handles CoreIAM token refresh and header rewriting.
9
+ * Returns the NextResponse to return, and whether the user is authenticated.
10
+ */
11
+ async function coreIamMiddleware(request) {
12
+ const jwtCookie = request.cookies.get("jwt");
13
+ const refreshTokenCookie = request.cookies.get("refreshToken");
14
+ const gatewayUrl = process.env.COREIAM_API_URL;
15
+ let isAuthenticated = false;
16
+ let needsRefresh = false;
17
+ if (jwtCookie) {
18
+ try {
19
+ const decoded = (0, jwt_decode_1.jwtDecode)(jwtCookie.value);
20
+ if (decoded.exp && decoded.exp * 1000 > Date.now()) {
21
+ isAuthenticated = true;
26
22
  }
27
- catch {
28
- if (refreshTokenCookie)
29
- needsRefresh = true;
23
+ else if (refreshTokenCookie) {
24
+ needsRefresh = true;
30
25
  }
31
26
  }
32
- else if (refreshTokenCookie) {
33
- needsRefresh = true;
27
+ catch {
28
+ if (refreshTokenCookie)
29
+ needsRefresh = true;
34
30
  }
35
- // Allow API routes to pass through (we handle their 401s normally)
36
- if (pathname.startsWith('/api')) {
37
- return server_1.NextResponse.next();
38
- }
39
- // 1. ATTEMPT SILENT REFRESH
40
- if (needsRefresh) {
41
- try {
42
- const refreshRes = await fetch(`${DEFAULT_GATEWAY_URL}/auth/refresh-token`, {
43
- method: 'POST',
44
- headers: {
45
- 'X-API-Key': process.env.COREIAM_API_KEY,
46
- 'cookie': `refreshToken=${refreshTokenCookie?.value || ''}; jwt=${jwtCookie?.value || ''}`,
47
- },
48
- });
49
- if (refreshRes.ok) {
50
- const setCookies = refreshRes.headers.getSetCookie();
51
- if (setCookies && setCookies.length > 0) {
52
- let newJwt = '';
53
- let newRefreshToken = '';
54
- setCookies.forEach(cookie => {
55
- if (cookie.startsWith('jwt='))
56
- newJwt = cookie.split(';')[0].split('=')[1];
57
- if (cookie.startsWith('refreshToken='))
58
- newRefreshToken = cookie.split(';')[0].split('=')[1];
59
- });
60
- // CRITICAL: Rewrite request headers so Server Components see the new JWT!
31
+ }
32
+ else if (refreshTokenCookie) {
33
+ needsRefresh = true;
34
+ }
35
+ // 1. ATTEMPT SILENT REFRESH
36
+ if (needsRefresh && gatewayUrl) {
37
+ try {
38
+ const refreshRes = await fetch(`${gatewayUrl}/auth/refresh-token`, {
39
+ method: 'POST',
40
+ headers: {
41
+ 'X-API-Key': process.env.COREIAM_API_KEY,
42
+ 'cookie': `refreshToken=${refreshTokenCookie?.value || ''}; jwt=${jwtCookie?.value || ''}`,
43
+ },
44
+ });
45
+ if (refreshRes.ok) {
46
+ const setCookies = refreshRes.headers.getSetCookie();
47
+ if (setCookies && setCookies.length > 0) {
48
+ let newJwt = '';
49
+ let newRefreshToken = '';
50
+ setCookies.forEach(cookie => {
51
+ if (cookie.startsWith('jwt='))
52
+ newJwt = cookie.split(';')[0].split('=')[1];
53
+ if (cookie.startsWith('refreshToken='))
54
+ newRefreshToken = cookie.split(';')[0].split('=')[1];
55
+ });
56
+ if (newJwt) {
61
57
  const requestHeaders = new Headers(request.headers);
62
58
  requestHeaders.set('cookie', `jwt=${newJwt}; refreshToken=${newRefreshToken}`);
63
59
  requestHeaders.set('Authorization', `Bearer ${newJwt}`);
64
60
  const response = server_1.NextResponse.next({
65
61
  request: { headers: requestHeaders },
66
62
  });
67
- // Set the new cookies on the browser
68
63
  setCookies.forEach(cookie => {
69
64
  response.headers.append('set-cookie', cookie);
70
65
  });
71
- return response; // Exit early, token is fresh!
66
+ return { response, isAuthenticated: true };
72
67
  }
73
68
  }
74
69
  }
75
- catch (error) {
76
- // Refresh failed, fall through to clear cookies
77
- }
78
- // 2. IF REFRESH FAILED, CLEAR COOKIES TO PREVENT INFINITE LOOP
79
- const res = server_1.NextResponse.redirect(new URL('/auth/login', nextUrl));
80
- res.cookies.delete('jwt');
81
- res.cookies.delete('refreshToken');
82
- return res;
83
- }
84
- // 3. STANDARD ROUTE PROTECTION
85
- const isAuthRoute = pathname.startsWith('/auth/login') || pathname.startsWith('/auth/register');
86
- if (isAuthRoute && isLoggedIn) {
87
- return server_1.NextResponse.redirect(new URL('/', nextUrl));
88
70
  }
89
- if (!isLoggedIn && !isAuthRoute) {
90
- return server_1.NextResponse.redirect(new URL('/auth/login', nextUrl));
71
+ catch (error) {
72
+ // Refresh failed, fall through to clear cookies
91
73
  }
92
- return server_1.NextResponse.next();
93
- };
74
+ // 2. IF REFRESH FAILED, CLEAR COOKIES
75
+ const response = server_1.NextResponse.next();
76
+ response.cookies.delete('jwt');
77
+ response.cookies.delete('refreshToken');
78
+ return { response, isAuthenticated: false };
79
+ }
80
+ // 3. NO REFRESH NEEDED (Token is valid or completely missing)
81
+ return { response: server_1.NextResponse.next(), isAuthenticated };
94
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreiam/auth",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "main": "./dist/core/index.js",
5
5
  "types": "./dist/core/index.d.ts",
6
6
  "exports": {