@fnd-platform/cognito-auth 1.0.0-alpha.1 → 1.0.0-alpha.10
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/lib/client/auth-client.d.ts +151 -94
- package/lib/client/auth-client.d.ts.map +1 -1
- package/lib/client/auth-client.js +330 -209
- package/lib/client/auth-client.js.map +1 -1
- package/lib/client/errors.d.ts +45 -23
- package/lib/client/errors.d.ts.map +1 -1
- package/lib/client/errors.js +80 -38
- package/lib/client/errors.js.map +1 -1
- package/lib/client/index.js +8 -23
- package/lib/index.d.ts +4 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/jwt.js +27 -27
- package/lib/remix/admin.server.js +44 -45
- package/lib/remix/index.d.ts +3 -11
- package/lib/remix/index.d.ts.map +1 -1
- package/lib/remix/index.js +19 -90
- package/lib/remix/index.js.map +1 -1
- package/lib/remix/session.server.d.ts +44 -33
- package/lib/remix/session.server.d.ts.map +1 -1
- package/lib/remix/session.server.js +157 -95
- package/lib/remix/session.server.js.map +1 -1
- package/lib/types.d.ts +140 -106
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +3 -3
- package/package.json +1 -1
package/lib/remix/index.js
CHANGED
|
@@ -1,95 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Remix authentication utilities exports.
|
|
4
4
|
*
|
|
5
5
|
* @packageDocumentation
|
|
6
6
|
*/
|
|
7
|
-
Object.defineProperty(exports,
|
|
8
|
-
exports.hasAnyRole =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Object.defineProperty(exports,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return session_server_js_1.createSessionStorage;
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
Object.defineProperty(exports, 'getSession', {
|
|
29
|
-
enumerable: true,
|
|
30
|
-
get: function () {
|
|
31
|
-
return session_server_js_1.getSession;
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
Object.defineProperty(exports, 'createUserSession', {
|
|
35
|
-
enumerable: true,
|
|
36
|
-
get: function () {
|
|
37
|
-
return session_server_js_1.createUserSession;
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
Object.defineProperty(exports, 'requireAuth', {
|
|
41
|
-
enumerable: true,
|
|
42
|
-
get: function () {
|
|
43
|
-
return session_server_js_1.requireAuth;
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
Object.defineProperty(exports, 'getOptionalUser', {
|
|
47
|
-
enumerable: true,
|
|
48
|
-
get: function () {
|
|
49
|
-
return session_server_js_1.getOptionalUser;
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
Object.defineProperty(exports, 'getUserSession', {
|
|
53
|
-
enumerable: true,
|
|
54
|
-
get: function () {
|
|
55
|
-
return session_server_js_1.getUserSession;
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
Object.defineProperty(exports, 'logout', {
|
|
59
|
-
enumerable: true,
|
|
60
|
-
get: function () {
|
|
61
|
-
return session_server_js_1.logout;
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
Object.defineProperty(exports, 'resetDefaultStorage', {
|
|
65
|
-
enumerable: true,
|
|
66
|
-
get: function () {
|
|
67
|
-
return session_server_js_1.resetDefaultStorage;
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
var admin_server_js_1 = require('./admin.server.js');
|
|
71
|
-
Object.defineProperty(exports, 'requireAdmin', {
|
|
72
|
-
enumerable: true,
|
|
73
|
-
get: function () {
|
|
74
|
-
return admin_server_js_1.requireAdmin;
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
Object.defineProperty(exports, 'requireRole', {
|
|
78
|
-
enumerable: true,
|
|
79
|
-
get: function () {
|
|
80
|
-
return admin_server_js_1.requireRole;
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
Object.defineProperty(exports, 'hasRole', {
|
|
84
|
-
enumerable: true,
|
|
85
|
-
get: function () {
|
|
86
|
-
return admin_server_js_1.hasRole;
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
Object.defineProperty(exports, 'hasAnyRole', {
|
|
90
|
-
enumerable: true,
|
|
91
|
-
get: function () {
|
|
92
|
-
return admin_server_js_1.hasAnyRole;
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
//# sourceMappingURL=index.js.map
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.hasAnyRole = exports.hasRole = exports.requireRole = exports.requireAdmin = exports.resetDefaultStorage = exports.logout = exports.getAccessToken = exports.getUserSession = exports.getOptionalUser = exports.requireAuth = exports.createUserSession = exports.getSession = exports.createSessionStorage = void 0;
|
|
9
|
+
var session_server_js_1 = require("./session.server.js");
|
|
10
|
+
Object.defineProperty(exports, "createSessionStorage", { enumerable: true, get: function () { return session_server_js_1.createSessionStorage; } });
|
|
11
|
+
Object.defineProperty(exports, "getSession", { enumerable: true, get: function () { return session_server_js_1.getSession; } });
|
|
12
|
+
Object.defineProperty(exports, "createUserSession", { enumerable: true, get: function () { return session_server_js_1.createUserSession; } });
|
|
13
|
+
Object.defineProperty(exports, "requireAuth", { enumerable: true, get: function () { return session_server_js_1.requireAuth; } });
|
|
14
|
+
Object.defineProperty(exports, "getOptionalUser", { enumerable: true, get: function () { return session_server_js_1.getOptionalUser; } });
|
|
15
|
+
Object.defineProperty(exports, "getUserSession", { enumerable: true, get: function () { return session_server_js_1.getUserSession; } });
|
|
16
|
+
Object.defineProperty(exports, "getAccessToken", { enumerable: true, get: function () { return session_server_js_1.getAccessToken; } });
|
|
17
|
+
Object.defineProperty(exports, "logout", { enumerable: true, get: function () { return session_server_js_1.logout; } });
|
|
18
|
+
Object.defineProperty(exports, "resetDefaultStorage", { enumerable: true, get: function () { return session_server_js_1.resetDefaultStorage; } });
|
|
19
|
+
var admin_server_js_1 = require("./admin.server.js");
|
|
20
|
+
Object.defineProperty(exports, "requireAdmin", { enumerable: true, get: function () { return admin_server_js_1.requireAdmin; } });
|
|
21
|
+
Object.defineProperty(exports, "requireRole", { enumerable: true, get: function () { return admin_server_js_1.requireRole; } });
|
|
22
|
+
Object.defineProperty(exports, "hasRole", { enumerable: true, get: function () { return admin_server_js_1.hasRole; } });
|
|
23
|
+
Object.defineProperty(exports, "hasAnyRole", { enumerable: true, get: function () { return admin_server_js_1.hasAnyRole; } });
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
package/lib/remix/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/remix/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/remix/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,yDAU6B;AAT3B,yHAAA,oBAAoB,OAAA;AACpB,+GAAA,UAAU,OAAA;AACV,sHAAA,iBAAiB,OAAA;AACjB,gHAAA,WAAW,OAAA;AACX,oHAAA,eAAe,OAAA;AACf,mHAAA,cAAc,OAAA;AACd,mHAAA,cAAc,OAAA;AACd,2GAAA,MAAM,OAAA;AACN,wHAAA,mBAAmB,OAAA;AAKrB,qDAAmF;AAA1E,+GAAA,YAAY,OAAA;AAAE,8GAAA,WAAW,OAAA;AAAE,0GAAA,OAAO,OAAA;AAAE,6GAAA,UAAU,OAAA"}
|
|
@@ -45,15 +45,7 @@ export declare function resetDefaultStorage(): void;
|
|
|
45
45
|
* }
|
|
46
46
|
* ```
|
|
47
47
|
*/
|
|
48
|
-
export declare function getSession(
|
|
49
|
-
request: Request,
|
|
50
|
-
storage?: SessionStorage
|
|
51
|
-
): Promise<
|
|
52
|
-
import('@remix-run/node').Session<
|
|
53
|
-
import('@remix-run/node').SessionData,
|
|
54
|
-
import('@remix-run/node').SessionData
|
|
55
|
-
>
|
|
56
|
-
>;
|
|
48
|
+
export declare function getSession(request: Request, storage?: SessionStorage): Promise<import("@remix-run/node").Session<import("@remix-run/node").SessionData, import("@remix-run/node").SessionData>>;
|
|
57
49
|
/**
|
|
58
50
|
* Creates a user session with authentication tokens and redirects.
|
|
59
51
|
*
|
|
@@ -73,11 +65,7 @@ export declare function getSession(
|
|
|
73
65
|
* }
|
|
74
66
|
* ```
|
|
75
67
|
*/
|
|
76
|
-
export declare function createUserSession(
|
|
77
|
-
tokens: AuthTokens,
|
|
78
|
-
redirectTo: string,
|
|
79
|
-
storage?: SessionStorage
|
|
80
|
-
): Promise<Response>;
|
|
68
|
+
export declare function createUserSession(tokens: AuthTokens, redirectTo: string, storage?: SessionStorage): Promise<Response>;
|
|
81
69
|
/**
|
|
82
70
|
* Requires authentication for a route.
|
|
83
71
|
*
|
|
@@ -99,11 +87,7 @@ export declare function createUserSession(
|
|
|
99
87
|
* }
|
|
100
88
|
* ```
|
|
101
89
|
*/
|
|
102
|
-
export declare function requireAuth(
|
|
103
|
-
request: Request,
|
|
104
|
-
redirectTo?: string,
|
|
105
|
-
storage?: SessionStorage
|
|
106
|
-
): Promise<string>;
|
|
90
|
+
export declare function requireAuth(request: Request, redirectTo?: string, storage?: SessionStorage): Promise<string>;
|
|
107
91
|
/**
|
|
108
92
|
* Gets the optional user from the session.
|
|
109
93
|
*
|
|
@@ -122,10 +106,7 @@ export declare function requireAuth(
|
|
|
122
106
|
* }
|
|
123
107
|
* ```
|
|
124
108
|
*/
|
|
125
|
-
export declare function getOptionalUser(
|
|
126
|
-
request: Request,
|
|
127
|
-
storage?: SessionStorage
|
|
128
|
-
): Promise<SessionUser | null>;
|
|
109
|
+
export declare function getOptionalUser(request: Request, storage?: SessionStorage): Promise<SessionUser | null>;
|
|
129
110
|
/**
|
|
130
111
|
* Gets full session data including tokens.
|
|
131
112
|
*
|
|
@@ -148,10 +129,7 @@ export declare function getOptionalUser(
|
|
|
148
129
|
* }
|
|
149
130
|
* ```
|
|
150
131
|
*/
|
|
151
|
-
export declare function getUserSession(
|
|
152
|
-
request: Request,
|
|
153
|
-
storage?: SessionStorage
|
|
154
|
-
): Promise<SessionData | null>;
|
|
132
|
+
export declare function getUserSession(request: Request, storage?: SessionStorage): Promise<SessionData | null>;
|
|
155
133
|
/**
|
|
156
134
|
* Logs out the user and redirects to the login page.
|
|
157
135
|
*
|
|
@@ -169,9 +147,42 @@ export declare function getUserSession(
|
|
|
169
147
|
* }
|
|
170
148
|
* ```
|
|
171
149
|
*/
|
|
172
|
-
export declare function logout(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
150
|
+
export declare function logout(request: Request, redirectTo?: string, storage?: SessionStorage): Promise<Response>;
|
|
151
|
+
/**
|
|
152
|
+
* Configuration for getting access tokens.
|
|
153
|
+
*/
|
|
154
|
+
export interface GetAccessTokenConfig {
|
|
155
|
+
/** Cognito User Pool Client ID (defaults to COGNITO_CLIENT_ID env var) */
|
|
156
|
+
clientId?: string;
|
|
157
|
+
/** AWS region (defaults to AWS_REGION env var) */
|
|
158
|
+
region?: string;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Gets a fresh ID token for making authenticated API calls.
|
|
162
|
+
*
|
|
163
|
+
* Since tokens are not stored in the session (to stay under cookie limits),
|
|
164
|
+
* this function uses the refresh token to obtain a fresh ID token from Cognito.
|
|
165
|
+
* ID tokens work with Cognito User Pools authorizers and contain user identity claims.
|
|
166
|
+
*
|
|
167
|
+
* @param request - Remix request object
|
|
168
|
+
* @param config - Optional configuration
|
|
169
|
+
* @param storage - Optional custom session storage
|
|
170
|
+
* @returns Fresh ID token or null if not authenticated
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* export async function loader({ request }: LoaderFunctionArgs) {
|
|
175
|
+
* const token = await getAccessToken(request);
|
|
176
|
+
* if (!token) {
|
|
177
|
+
* throw redirect('/login');
|
|
178
|
+
* }
|
|
179
|
+
*
|
|
180
|
+
* const response = await fetch('https://api.example.com/data', {
|
|
181
|
+
* headers: { Authorization: `Bearer ${token}` },
|
|
182
|
+
* });
|
|
183
|
+
* return json(await response.json());
|
|
184
|
+
* }
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
export declare function getAccessToken(request: Request, config?: GetAccessTokenConfig, storage?: SessionStorage): Promise<string | null>;
|
|
188
|
+
//# sourceMappingURL=session.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.server.d.ts","sourceRoot":"","sources":["../../src/remix/session.server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"session.server.d.ts","sourceRoot":"","sources":["../../src/remix/session.server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAoBxE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc,CAcpE;AAeD;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,4HAG1E;AAoBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,QAAQ,CAAC,CAuBnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,UAAU,SAAW,EACrB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAa7B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAmB7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,OAAO,EAChB,UAAU,SAAW,EACrB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,QAAQ,CAAC,CASnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6BxB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Remix session management utilities.
|
|
4
4
|
*
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @packageDocumentation
|
|
9
9
|
*/
|
|
10
|
-
Object.defineProperty(exports,
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.createSessionStorage = createSessionStorage;
|
|
12
12
|
exports.resetDefaultStorage = resetDefaultStorage;
|
|
13
13
|
exports.getSession = getSession;
|
|
@@ -16,7 +16,9 @@ exports.requireAuth = requireAuth;
|
|
|
16
16
|
exports.getOptionalUser = getOptionalUser;
|
|
17
17
|
exports.getUserSession = getUserSession;
|
|
18
18
|
exports.logout = logout;
|
|
19
|
-
|
|
19
|
+
exports.getAccessToken = getAccessToken;
|
|
20
|
+
const node_1 = require("@remix-run/node");
|
|
21
|
+
const token_refresh_js_1 = require("../utils/token-refresh.js");
|
|
20
22
|
/**
|
|
21
23
|
* Default session storage instance.
|
|
22
24
|
* Lazily initialized to avoid accessing env at module load.
|
|
@@ -26,11 +28,11 @@ let defaultSessionStorage = null;
|
|
|
26
28
|
* Cookie configuration for session storage.
|
|
27
29
|
*/
|
|
28
30
|
const COOKIE_CONFIG = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
name: '__fnd_session',
|
|
32
|
+
httpOnly: true,
|
|
33
|
+
maxAge: 60 * 60 * 24 * 7, // 1 week
|
|
34
|
+
path: '/',
|
|
35
|
+
sameSite: 'lax',
|
|
34
36
|
};
|
|
35
37
|
/**
|
|
36
38
|
* Creates a session storage with the given secret.
|
|
@@ -48,17 +50,17 @@ const COOKIE_CONFIG = {
|
|
|
48
50
|
* ```
|
|
49
51
|
*/
|
|
50
52
|
function createSessionStorage(secret) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
const sessionSecret = secret ?? process.env.SESSION_SECRET;
|
|
54
|
+
if (!sessionSecret) {
|
|
55
|
+
throw new Error('SESSION_SECRET environment variable is required');
|
|
56
|
+
}
|
|
57
|
+
return (0, node_1.createCookieSessionStorage)({
|
|
58
|
+
cookie: {
|
|
59
|
+
...COOKIE_CONFIG,
|
|
60
|
+
secrets: [sessionSecret],
|
|
61
|
+
secure: process.env.NODE_ENV === 'production',
|
|
62
|
+
},
|
|
63
|
+
});
|
|
62
64
|
}
|
|
63
65
|
/**
|
|
64
66
|
* Gets the default session storage instance.
|
|
@@ -67,10 +69,10 @@ function createSessionStorage(secret) {
|
|
|
67
69
|
* @internal
|
|
68
70
|
*/
|
|
69
71
|
function getDefaultStorage() {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
if (!defaultSessionStorage) {
|
|
73
|
+
defaultSessionStorage = createSessionStorage();
|
|
74
|
+
}
|
|
75
|
+
return defaultSessionStorage;
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
76
78
|
* Resets the default session storage. Useful for testing.
|
|
@@ -78,7 +80,7 @@ function getDefaultStorage() {
|
|
|
78
80
|
* @internal
|
|
79
81
|
*/
|
|
80
82
|
function resetDefaultStorage() {
|
|
81
|
-
|
|
83
|
+
defaultSessionStorage = null;
|
|
82
84
|
}
|
|
83
85
|
/**
|
|
84
86
|
* Gets the session from a request.
|
|
@@ -96,8 +98,8 @@ function resetDefaultStorage() {
|
|
|
96
98
|
* ```
|
|
97
99
|
*/
|
|
98
100
|
async function getSession(request, storage) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
const sessionStorage = storage ?? getDefaultStorage();
|
|
102
|
+
return sessionStorage.getSession(request.headers.get('Cookie'));
|
|
101
103
|
}
|
|
102
104
|
/**
|
|
103
105
|
* Decodes a JWT token payload (base64).
|
|
@@ -108,13 +110,14 @@ async function getSession(request, storage) {
|
|
|
108
110
|
* @internal
|
|
109
111
|
*/
|
|
110
112
|
function decodeTokenPayload(token) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
try {
|
|
114
|
+
const payload = token.split('.')[1];
|
|
115
|
+
const decoded = Buffer.from(payload, 'base64').toString('utf-8');
|
|
116
|
+
return JSON.parse(decoded);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return {};
|
|
120
|
+
}
|
|
118
121
|
}
|
|
119
122
|
/**
|
|
120
123
|
* Creates a user session with authentication tokens and redirects.
|
|
@@ -136,23 +139,25 @@ function decodeTokenPayload(token) {
|
|
|
136
139
|
* ```
|
|
137
140
|
*/
|
|
138
141
|
async function createUserSession(tokens, redirectTo, storage) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
142
|
+
const sessionStorage = storage ?? getDefaultStorage();
|
|
143
|
+
const session = await sessionStorage.getSession();
|
|
144
|
+
// Decode ID token to get user info
|
|
145
|
+
const payload = decodeTokenPayload(tokens.idToken);
|
|
146
|
+
// Store tokens and user info in session.
|
|
147
|
+
// Note: Cookies have a ~4KB limit. JWT tokens are typically 1-2KB each.
|
|
148
|
+
// We only store refreshToken (for obtaining fresh accessTokens when needed).
|
|
149
|
+
// We skip accessToken and idToken to stay under cookie limits.
|
|
150
|
+
// User info is extracted from idToken and stored separately.
|
|
151
|
+
session.set('refreshToken', tokens.refreshToken);
|
|
152
|
+
session.set('expiresAt', Date.now() + tokens.expiresIn * 1000);
|
|
153
|
+
session.set('userId', payload.sub);
|
|
154
|
+
session.set('email', payload.email ?? '');
|
|
155
|
+
session.set('groups', payload['cognito:groups'] ?? []);
|
|
156
|
+
return (0, node_1.redirect)(redirectTo, {
|
|
157
|
+
headers: {
|
|
158
|
+
'Set-Cookie': await sessionStorage.commitSession(session),
|
|
159
|
+
},
|
|
160
|
+
});
|
|
156
161
|
}
|
|
157
162
|
/**
|
|
158
163
|
* Requires authentication for a route.
|
|
@@ -176,19 +181,19 @@ async function createUserSession(tokens, redirectTo, storage) {
|
|
|
176
181
|
* ```
|
|
177
182
|
*/
|
|
178
183
|
async function requireAuth(request, redirectTo = '/login', storage) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
184
|
+
const session = await getSession(request, storage);
|
|
185
|
+
const userId = session.get('userId');
|
|
186
|
+
if (!userId) {
|
|
187
|
+
throw (0, node_1.redirect)(redirectTo);
|
|
188
|
+
}
|
|
189
|
+
// Check if tokens are near expiry (within 5 minutes)
|
|
190
|
+
const expiresAt = session.get('expiresAt');
|
|
191
|
+
if (expiresAt && Date.now() > expiresAt - 5 * 60 * 1000) {
|
|
192
|
+
// Tokens are near expiry
|
|
193
|
+
// In a full implementation, this would refresh tokens
|
|
194
|
+
// For now, we just return the userId as the session is still valid
|
|
195
|
+
}
|
|
196
|
+
return userId;
|
|
192
197
|
}
|
|
193
198
|
/**
|
|
194
199
|
* Gets the optional user from the session.
|
|
@@ -209,16 +214,16 @@ async function requireAuth(request, redirectTo = '/login', storage) {
|
|
|
209
214
|
* ```
|
|
210
215
|
*/
|
|
211
216
|
async function getOptionalUser(request, storage) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
const session = await getSession(request, storage);
|
|
218
|
+
const userId = session.get('userId');
|
|
219
|
+
if (!userId) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
userId,
|
|
224
|
+
email: session.get('email') ?? '',
|
|
225
|
+
groups: session.get('groups') ?? [],
|
|
226
|
+
};
|
|
222
227
|
}
|
|
223
228
|
/**
|
|
224
229
|
* Gets full session data including tokens.
|
|
@@ -243,20 +248,22 @@ async function getOptionalUser(request, storage) {
|
|
|
243
248
|
* ```
|
|
244
249
|
*/
|
|
245
250
|
async function getUserSession(request, storage) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
251
|
+
const session = await getSession(request, storage);
|
|
252
|
+
const userId = session.get('userId');
|
|
253
|
+
if (!userId) {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
// accessToken and idToken are NOT stored to stay under ~4KB cookie limit.
|
|
258
|
+
// Use getAccessToken() to obtain a fresh accessToken when needed for API calls.
|
|
259
|
+
accessToken: undefined,
|
|
260
|
+
idToken: undefined,
|
|
261
|
+
refreshToken: session.get('refreshToken'),
|
|
262
|
+
expiresAt: session.get('expiresAt'),
|
|
263
|
+
userId,
|
|
264
|
+
email: session.get('email') ?? '',
|
|
265
|
+
groups: session.get('groups') ?? [],
|
|
266
|
+
};
|
|
260
267
|
}
|
|
261
268
|
/**
|
|
262
269
|
* Logs out the user and redirects to the login page.
|
|
@@ -276,12 +283,67 @@ async function getUserSession(request, storage) {
|
|
|
276
283
|
* ```
|
|
277
284
|
*/
|
|
278
285
|
async function logout(request, redirectTo = '/login', storage) {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
+
const sessionStorage = storage ?? getDefaultStorage();
|
|
287
|
+
const session = await getSession(request, storage);
|
|
288
|
+
return (0, node_1.redirect)(redirectTo, {
|
|
289
|
+
headers: {
|
|
290
|
+
'Set-Cookie': await sessionStorage.destroySession(session),
|
|
291
|
+
},
|
|
292
|
+
});
|
|
286
293
|
}
|
|
287
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Gets a fresh ID token for making authenticated API calls.
|
|
296
|
+
*
|
|
297
|
+
* Since tokens are not stored in the session (to stay under cookie limits),
|
|
298
|
+
* this function uses the refresh token to obtain a fresh ID token from Cognito.
|
|
299
|
+
* ID tokens work with Cognito User Pools authorizers and contain user identity claims.
|
|
300
|
+
*
|
|
301
|
+
* @param request - Remix request object
|
|
302
|
+
* @param config - Optional configuration
|
|
303
|
+
* @param storage - Optional custom session storage
|
|
304
|
+
* @returns Fresh ID token or null if not authenticated
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* export async function loader({ request }: LoaderFunctionArgs) {
|
|
309
|
+
* const token = await getAccessToken(request);
|
|
310
|
+
* if (!token) {
|
|
311
|
+
* throw redirect('/login');
|
|
312
|
+
* }
|
|
313
|
+
*
|
|
314
|
+
* const response = await fetch('https://api.example.com/data', {
|
|
315
|
+
* headers: { Authorization: `Bearer ${token}` },
|
|
316
|
+
* });
|
|
317
|
+
* return json(await response.json());
|
|
318
|
+
* }
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
async function getAccessToken(request, config, storage) {
|
|
322
|
+
const session = await getSession(request, storage);
|
|
323
|
+
const refreshToken = session.get('refreshToken');
|
|
324
|
+
if (!refreshToken) {
|
|
325
|
+
console.warn('getAccessToken: No refresh token found in session');
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
const clientId = config?.clientId ?? process.env.COGNITO_CLIENT_ID;
|
|
329
|
+
if (!clientId) {
|
|
330
|
+
throw new Error('COGNITO_CLIENT_ID environment variable is required');
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
console.log('getAccessToken: Refreshing token with clientId:', clientId.substring(0, 8) + '...');
|
|
334
|
+
const result = await (0, token_refresh_js_1.refreshAccessToken)(refreshToken, {
|
|
335
|
+
clientId,
|
|
336
|
+
region: config?.region,
|
|
337
|
+
});
|
|
338
|
+
console.log('getAccessToken: Token refresh successful');
|
|
339
|
+
// Note: Cognito authorizers work with both access tokens and ID tokens.
|
|
340
|
+
// Using ID token as it contains user identity claims needed for authorization.
|
|
341
|
+
return result.idToken;
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
// Refresh token may be expired or invalid
|
|
345
|
+
console.error('getAccessToken: Failed to refresh access token:', error);
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
//# sourceMappingURL=session.server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.server.js","sourceRoot":"","sources":["../../src/remix/session.server.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;
|
|
1
|
+
{"version":3,"file":"session.server.js","sourceRoot":"","sources":["../../src/remix/session.server.ts"],"names":[],"mappings":"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"}
|