@frontegg/nextjs 9.0.5 → 9.1.1-alpha.11727010801
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/CHANGELOG.md +24 -0
- package/common/helpers.js.map +1 -1
- package/edge/getSessionOnEdge.d.ts +77 -3
- package/edge/getSessionOnEdge.js +143 -6
- package/edge/getSessionOnEdge.js.map +1 -1
- package/edge/refreshAccessTokenIfNeededOnEdge.d.ts +4 -0
- package/edge/refreshAccessTokenIfNeededOnEdge.js +108 -0
- package/edge/refreshAccessTokenIfNeededOnEdge.js.map +1 -0
- package/edge/shouldBypassMiddleware.d.ts +2 -1
- package/edge/shouldBypassMiddleware.js +7 -1
- package/edge/shouldBypassMiddleware.js.map +1 -1
- package/index.js +1 -1
- package/middleware/ProxyResponseCallback.js +1 -1
- package/middleware/ProxyResponseCallback.js.map +1 -1
- package/package.json +1 -1
- package/pages/helpers.d.ts +2 -1
- package/pages/helpers.js +8 -3
- package/pages/helpers.js.map +1 -1
- package/sdkVersion.js +1 -1
- package/sdkVersion.js.map +1 -1
- package/types/index.d.ts +4 -7
- package/types/index.js.map +1 -1
- package/utils/cookies/index.d.ts +7 -2
- package/utils/cookies/index.js +50 -5
- package/utils/cookies/index.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## [9.1.1](https://github.com/frontegg/frontegg-nextjs/compare/v9.0.5...v9.1.1) (2024-11-7)
|
|
4
|
+
|
|
5
|
+
- FR-18476 - Added url for beforeRequestInterceptor function
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
- FR-18476 - Added request interceptor
|
|
9
|
+
- FR-18472 - Fixed Google one tap login stuck after unmounting login/signup unmounted
|
|
10
|
+
|
|
11
|
+
- FR-18436 - Fixed activate account with empty redirect bug
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
- FR-17943 - Added code pages
|
|
15
|
+
|
|
16
|
+
- FR-18427 - Added Support for triggering MFA after native passkeys / iOS apple login
|
|
17
|
+
- FR-18211 - Fixed email overlapping roles field
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### NextJS Wrapper 9.1.1:
|
|
21
|
+
- FR-18495 - refresh the token when it has expired
|
|
22
|
+
- FR-18442 - Remove cookies when landing on oauth/callback to support after hosted login activate account succeeded
|
|
23
|
+
- FR-18442 - Fix Nextjs session store injection and support SSG pages
|
|
24
|
+
- Fix session abandoned when accessing not found page
|
|
25
|
+
- Export FronteggAppRouterAsync to be imported by '@frontegg/nextjs/app'
|
|
26
|
+
|
|
3
27
|
## [9.0.5](https://github.com/frontegg/frontegg-nextjs/compare/v9.0.4...v9.0.5) (2024-10-31)
|
|
4
28
|
|
|
5
29
|
- FR-18476 - Added url for beforeRequestInterceptor function
|
package/common/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","names":["_jwt","_interopRequireDefault","require","_encryption","createSessionFromAccessToken","data","_data$accessToken","_data$refreshToken","accessToken","access_token","refreshToken","refresh_token","payload","decodedJwt","JwtManager","verify","expiresIn","Math","floor","exp","Date","now","tokens","session","
|
|
1
|
+
{"version":3,"file":"helpers.js","names":["_jwt","_interopRequireDefault","require","_encryption","createSessionFromAccessToken","data","_data$accessToken","_data$refreshToken","accessToken","access_token","refreshToken","refresh_token","payload","decodedJwt","JwtManager","verify","expiresIn","Math","floor","exp","Date","now","tokens","session","encryption","sealTokens","getTokensFromCookie","cookie","undefined","unsealTokens"],"sources":["../../../../packages/nextjs/src/common/helpers.ts"],"sourcesContent":["import type { FronteggUserTokens } from '../types';\nimport JwtManager from '../utils/jwt';\nimport encryption from '../utils/encryption';\n\nexport async function createSessionFromAccessToken(data: any): Promise<[string, any, string] | []> {\n const accessToken = data.accessToken ?? data.access_token;\n const refreshToken = data.refreshToken ?? data.refresh_token;\n const { payload: decodedJwt }: any = await JwtManager.verify(accessToken);\n decodedJwt.expiresIn = Math.floor((decodedJwt.exp * 1000 - Date.now()) / 1000);\n\n const tokens = { accessToken, refreshToken };\n const session = await encryption.sealTokens(tokens, decodedJwt.exp);\n return [session, decodedJwt, refreshToken];\n}\n\nexport async function getTokensFromCookie(cookie?: string): Promise<FronteggUserTokens | undefined> {\n if (!cookie) {\n return undefined;\n }\n return await encryption.unsealTokens(cookie);\n}\n"],"mappings":";;;;;;;;AACA,IAAAA,IAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,WAAA,GAAAF,sBAAA,CAAAC,OAAA;AAEO,eAAeE,4BAA4BA,CAACC,IAAS,EAAuC;EAAA,IAAAC,iBAAA,EAAAC,kBAAA;EACjG,MAAMC,WAAW,IAAAF,iBAAA,GAAGD,IAAI,CAACG,WAAW,YAAAF,iBAAA,GAAID,IAAI,CAACI,YAAY;EACzD,MAAMC,YAAY,IAAAH,kBAAA,GAAGF,IAAI,CAACK,YAAY,YAAAH,kBAAA,GAAIF,IAAI,CAACM,aAAa;EAC5D,MAAM;IAAEC,OAAO,EAAEC;EAAgB,CAAC,GAAG,MAAMC,YAAU,CAACC,MAAM,CAACP,WAAW,CAAC;EACzEK,UAAU,CAACG,SAAS,GAAGC,IAAI,CAACC,KAAK,CAAC,CAACL,UAAU,CAACM,GAAG,GAAG,IAAI,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;EAE9E,MAAMC,MAAM,GAAG;IAAEd,WAAW;IAAEE;EAAa,CAAC;EAC5C,MAAMa,OAAO,GAAG,MAAMC,mBAAU,CAACC,UAAU,CAACH,MAAM,EAAET,UAAU,CAACM,GAAG,CAAC;EACnE,OAAO,CAACI,OAAO,EAAEV,UAAU,EAAEH,YAAY,CAAC;AAC5C;AAEO,eAAegB,mBAAmBA,CAACC,MAAe,EAA2C;EAClG,IAAI,CAACA,MAAM,EAAE;IACX,OAAOC,SAAS;EAClB;EACA,OAAO,MAAMJ,mBAAU,CAACK,YAAY,CAACF,MAAM,CAAC;AAC9C","ignoreList":[]}
|
|
@@ -1,6 +1,80 @@
|
|
|
1
1
|
import type { IncomingMessage } from 'http';
|
|
2
|
-
import {
|
|
3
|
-
import { NextResponse } from 'next/server';
|
|
4
|
-
export
|
|
2
|
+
import { FronteggEdgeSession } from '../types';
|
|
3
|
+
import { type NextRequest, NextResponse } from 'next/server';
|
|
4
|
+
export type HandleSessionOnEdge = {
|
|
5
|
+
request: IncomingMessage | Request;
|
|
6
|
+
pathname: string;
|
|
7
|
+
headers: NextRequest['headers'];
|
|
8
|
+
searchParams: URLSearchParams;
|
|
9
|
+
};
|
|
10
|
+
export declare const handleSessionOnEdge: (params: HandleSessionOnEdge) => Promise<NextResponse>;
|
|
11
|
+
/**
|
|
12
|
+
* getSessionOnEdge is deprecated, please use handleSessionOnEdge instead example:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { NextRequest } from 'next/server';
|
|
16
|
+
* import { handleSessionOnEdge } from '@frontegg/nextjs/edge';
|
|
17
|
+
*
|
|
18
|
+
* export const middleware = async (request: NextRequest) => {
|
|
19
|
+
* const { pathname, searchParams } = request.nextUrl;
|
|
20
|
+
* const headers = request.headers;
|
|
21
|
+
*
|
|
22
|
+
* // Additional logic if needed
|
|
23
|
+
*
|
|
24
|
+
* return handleSessionOnEdge({ request, pathname, searchParams, headers });
|
|
25
|
+
* };
|
|
26
|
+
*
|
|
27
|
+
* export const config = {
|
|
28
|
+
* matcher: '/(.*)',
|
|
29
|
+
* };
|
|
30
|
+
* ```
|
|
31
|
+
* @deprecated
|
|
32
|
+
*/
|
|
33
|
+
export declare const getSessionOnEdge: (req: IncomingMessage | Request) => Promise<FronteggEdgeSession | undefined>;
|
|
34
|
+
/**
|
|
35
|
+
* Check session on edge and return session if exists this method does not redirect to login page
|
|
36
|
+
* Example:
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { NextRequest } from 'next/server';
|
|
40
|
+
* import { handleSessionOnEdge } from '@frontegg/nextjs/edge';
|
|
41
|
+
*
|
|
42
|
+
* export const middleware = async (request: NextRequest) => {
|
|
43
|
+
* const { pathname, searchParams } = request.nextUrl;
|
|
44
|
+
* const headers = request.headers;
|
|
45
|
+
*
|
|
46
|
+
* // Additional logic if needed
|
|
47
|
+
*
|
|
48
|
+
* // check if it's a hosted login callback
|
|
49
|
+
* if (isHostedLoginCallback(pathname, searchParams)) {
|
|
50
|
+
* return handleHostedLoginCallback(request, pathname, searchParams);
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
53
|
+
* // check if we should bypass the middleware
|
|
54
|
+
* if (shouldByPassMiddleware(pathname)) {
|
|
55
|
+
* return NextResponse.next();
|
|
56
|
+
* }
|
|
57
|
+
*
|
|
58
|
+
* // check session
|
|
59
|
+
* const session = await checkSessionOnEdge(request);
|
|
60
|
+
*
|
|
61
|
+
* if (!session) {
|
|
62
|
+
* return redirectToLogin(pathname);
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* // if headers are present return them to the next response
|
|
66
|
+
* if (session.headers) {
|
|
67
|
+
* return NextResponse.next({
|
|
68
|
+
* headers: session.headers,
|
|
69
|
+
* });
|
|
70
|
+
* }
|
|
71
|
+
* return NextResponse.next();
|
|
72
|
+
* };
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
*
|
|
76
|
+
* @param req
|
|
77
|
+
*/
|
|
78
|
+
export declare const checkSessionOnEdge: (req: IncomingMessage | Request) => Promise<FronteggEdgeSession | undefined>;
|
|
5
79
|
export declare const handleHostedLoginCallback: (req: IncomingMessage | Request, pathname: string, searchParams: URLSearchParams) => Promise<NextResponse>;
|
|
6
80
|
export declare const isHostedLoginCallback: (pathname: string, searchParams: URLSearchParams) => boolean;
|
package/edge/getSessionOnEdge.js
CHANGED
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.isHostedLoginCallback = exports.handleHostedLoginCallback = exports.getSessionOnEdge = void 0;
|
|
7
|
+
exports.isHostedLoginCallback = exports.handleSessionOnEdge = exports.handleHostedLoginCallback = exports.getSessionOnEdge = exports.checkSessionOnEdge = void 0;
|
|
8
8
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
9
|
var _cookies = _interopRequireDefault(require("../utils/cookies"));
|
|
10
10
|
var _createSession = _interopRequireDefault(require("../utils/createSession"));
|
|
@@ -14,6 +14,148 @@ var _server = require("next/server");
|
|
|
14
14
|
var _config = _interopRequireDefault(require("../config"));
|
|
15
15
|
var _jwt = _interopRequireDefault(require("../utils/jwt"));
|
|
16
16
|
var _utils = require("../api/utils");
|
|
17
|
+
var _fronteggLogger = _interopRequireDefault(require("../utils/fronteggLogger"));
|
|
18
|
+
var _refreshAccessTokenIfNeededOnEdge = require("./refreshAccessTokenIfNeededOnEdge");
|
|
19
|
+
var _redirectToLogin = require("./redirectToLogin");
|
|
20
|
+
var _shouldBypassMiddleware = require("./shouldBypassMiddleware");
|
|
21
|
+
const logger = _fronteggLogger.default.child({
|
|
22
|
+
tag: 'EdgeRuntime.getSessionOnEdge'
|
|
23
|
+
});
|
|
24
|
+
const handleSessionOnEdge = async params => {
|
|
25
|
+
const {
|
|
26
|
+
request,
|
|
27
|
+
pathname,
|
|
28
|
+
searchParams,
|
|
29
|
+
headers
|
|
30
|
+
} = params;
|
|
31
|
+
if (isHostedLoginCallback(pathname, searchParams)) {
|
|
32
|
+
return handleHostedLoginCallback(request, pathname, searchParams);
|
|
33
|
+
}
|
|
34
|
+
if ((0, _shouldBypassMiddleware.shouldByPassMiddleware)(pathname, headers /*, options: optional bypass configuration */)) {
|
|
35
|
+
return _server.NextResponse.next();
|
|
36
|
+
}
|
|
37
|
+
const edgeSession = await checkSessionOnEdge(request);
|
|
38
|
+
if (!edgeSession) {
|
|
39
|
+
return (0, _redirectToLogin.redirectToLogin)(pathname, searchParams);
|
|
40
|
+
}
|
|
41
|
+
if (edgeSession.headers) {
|
|
42
|
+
return _server.NextResponse.next({
|
|
43
|
+
headers: edgeSession.headers
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return _server.NextResponse.next();
|
|
47
|
+
};
|
|
48
|
+
exports.handleSessionOnEdge = handleSessionOnEdge;
|
|
49
|
+
const GET_SESSION_ON_EDGE_DEPRECATED_ERROR = `Deprecation Notice: getSessionOnEdge has been deprecated. Please use handleSessionOnEdge instead. For example:
|
|
50
|
+
|
|
51
|
+
file: middleware.ts
|
|
52
|
+
\`\`\`ts
|
|
53
|
+
import { NextRequest } from 'next/server';
|
|
54
|
+
import { handleSessionOnEdge } from '@frontegg/nextjs/edge';
|
|
55
|
+
|
|
56
|
+
export const middleware = async (request: NextRequest) => {
|
|
57
|
+
const { pathname, searchParams } = request.nextUrl;
|
|
58
|
+
const headers = request.headers;
|
|
59
|
+
|
|
60
|
+
// Additional logic if needed
|
|
61
|
+
|
|
62
|
+
return handleSessionOnEdge({ request, pathname, searchParams, headers });
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
export const config = {
|
|
67
|
+
matcher: '/(.*)',
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
\`\`\`
|
|
71
|
+
|
|
72
|
+
Alternatively, to manually verify the session, you can use checkSessionOnEdge. Note that this method does not redirect to the login page if the session is invalid.
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* getSessionOnEdge is deprecated, please use handleSessionOnEdge instead example:
|
|
77
|
+
*
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { NextRequest } from 'next/server';
|
|
80
|
+
* import { handleSessionOnEdge } from '@frontegg/nextjs/edge';
|
|
81
|
+
*
|
|
82
|
+
* export const middleware = async (request: NextRequest) => {
|
|
83
|
+
* const { pathname, searchParams } = request.nextUrl;
|
|
84
|
+
* const headers = request.headers;
|
|
85
|
+
*
|
|
86
|
+
* // Additional logic if needed
|
|
87
|
+
*
|
|
88
|
+
* return handleSessionOnEdge({ request, pathname, searchParams, headers });
|
|
89
|
+
* };
|
|
90
|
+
*
|
|
91
|
+
* export const config = {
|
|
92
|
+
* matcher: '/(.*)',
|
|
93
|
+
* };
|
|
94
|
+
* ```
|
|
95
|
+
* @deprecated
|
|
96
|
+
*/
|
|
97
|
+
const getSessionOnEdge = async req => {
|
|
98
|
+
throw new Error(GET_SESSION_ON_EDGE_DEPRECATED_ERROR);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Check session on edge and return session if exists this method does not redirect to login page
|
|
103
|
+
* Example:
|
|
104
|
+
*
|
|
105
|
+
* ```ts
|
|
106
|
+
* import { NextRequest } from 'next/server';
|
|
107
|
+
* import { handleSessionOnEdge } from '@frontegg/nextjs/edge';
|
|
108
|
+
*
|
|
109
|
+
* export const middleware = async (request: NextRequest) => {
|
|
110
|
+
* const { pathname, searchParams } = request.nextUrl;
|
|
111
|
+
* const headers = request.headers;
|
|
112
|
+
*
|
|
113
|
+
* // Additional logic if needed
|
|
114
|
+
*
|
|
115
|
+
* // check if it's a hosted login callback
|
|
116
|
+
* if (isHostedLoginCallback(pathname, searchParams)) {
|
|
117
|
+
* return handleHostedLoginCallback(request, pathname, searchParams);
|
|
118
|
+
* }
|
|
119
|
+
*
|
|
120
|
+
* // check if we should bypass the middleware
|
|
121
|
+
* if (shouldByPassMiddleware(pathname)) {
|
|
122
|
+
* return NextResponse.next();
|
|
123
|
+
* }
|
|
124
|
+
*
|
|
125
|
+
* // check session
|
|
126
|
+
* const session = await checkSessionOnEdge(request);
|
|
127
|
+
*
|
|
128
|
+
* if (!session) {
|
|
129
|
+
* return redirectToLogin(pathname);
|
|
130
|
+
* }
|
|
131
|
+
*
|
|
132
|
+
* // if headers are present return them to the next response
|
|
133
|
+
* if (session.headers) {
|
|
134
|
+
* return NextResponse.next({
|
|
135
|
+
* headers: session.headers,
|
|
136
|
+
* });
|
|
137
|
+
* }
|
|
138
|
+
* return NextResponse.next();
|
|
139
|
+
* };
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
*
|
|
143
|
+
* @param req
|
|
144
|
+
*/
|
|
145
|
+
exports.getSessionOnEdge = getSessionOnEdge;
|
|
146
|
+
const checkSessionOnEdge = async req => {
|
|
147
|
+
const sessionCookies = _cookies.default.getSessionCookieFromRequest(req);
|
|
148
|
+
let existingSession = await (0, _createSession.default)(sessionCookies, _encryptionEdge.default);
|
|
149
|
+
if (existingSession) {
|
|
150
|
+
logger.debug('session resolved from session cookie');
|
|
151
|
+
return {
|
|
152
|
+
session: existingSession
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
logger.debug('Failed to resolve session from cookie, going to refresh token');
|
|
156
|
+
return (0, _refreshAccessTokenIfNeededOnEdge.refreshAccessTokenIfNeededOnEdge)(req);
|
|
157
|
+
};
|
|
158
|
+
exports.checkSessionOnEdge = checkSessionOnEdge;
|
|
17
159
|
async function createSessionFromAccessTokenEdge(data) {
|
|
18
160
|
var _data$accessToken, _data$refreshToken;
|
|
19
161
|
const accessToken = (_data$accessToken = data.accessToken) != null ? _data$accessToken : data.access_token;
|
|
@@ -29,11 +171,6 @@ async function createSessionFromAccessTokenEdge(data) {
|
|
|
29
171
|
const session = await _encryptionEdge.default.sealTokens(tokens, decodedJwt.exp);
|
|
30
172
|
return [session, decodedJwt, refreshToken];
|
|
31
173
|
}
|
|
32
|
-
const getSessionOnEdge = req => {
|
|
33
|
-
const cookies = _cookies.default.getSessionCookieFromRequest(req);
|
|
34
|
-
return (0, _createSession.default)(cookies, _encryptionEdge.default);
|
|
35
|
-
};
|
|
36
|
-
exports.getSessionOnEdge = getSessionOnEdge;
|
|
37
174
|
const handleHostedLoginCallback = async (req, pathname, searchParams) => {
|
|
38
175
|
var _searchParams$get, _req$headers;
|
|
39
176
|
if (!isHostedLoginCallback(pathname, searchParams)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSessionOnEdge.js","names":["_cookies","_interopRequireDefault","require","_createSession","_encryptionEdge","_api","_server","_config","_jwt","_utils","createSessionFromAccessTokenEdge","data","_data$accessToken","_data$refreshToken","accessToken","access_token","refreshToken","refresh_token","payload","decodedJwt","JwtManager","verify","expiresIn","Math","floor","exp","Date","now","tokens","session","encryptionEdge","sealTokens","getSessionOnEdge","req","cookies","CookieManager","getSessionCookieFromRequest","createSession","exports","handleHostedLoginCallback","pathname","searchParams","_searchParams$get","_req$headers","isHostedLoginCallback","NextResponse","next","code","get","headers","clientIp","undefined","_socket","socket","remoteAddress","_socket2","requestHeaders","_extends2","default","config","shouldForwardIp","_config$clientSecret","FRONTEGG_FORWARD_IP_HEADER","FRONTEGG_CLIENT_SECRET_HEADER","clientSecret","response","api","exchangeHostedLoginToken","buildRequestHeaders","clientId","json","redirect","appUrl","isSecured","isSSL","cookieValue","create","value","expires","secure","cookieName","replace","rewriteCookieByAppId","appId","refreshCookie","sessionCookieHeaders","map","cookie","refreshCookieHeaders","secureJwtEnabled","startsWith"],"sources":["../../../../packages/nextjs/src/edge/getSessionOnEdge.ts"],"sourcesContent":["import type { IncomingMessage } from 'http';\nimport { FronteggNextJSSession } from '../types';\nimport CookieManager from '../utils/cookies';\nimport createSession from '../utils/createSession';\nimport encryptionEdge from '../utils/encryption-edge';\nimport api from '../api';\nimport { NextResponse } from 'next/server';\nimport config from '../config';\nimport JwtManager from '../utils/jwt';\nimport { buildRequestHeaders, FRONTEGG_CLIENT_SECRET_HEADER, FRONTEGG_FORWARD_IP_HEADER } from '../api/utils';\n\nasync function createSessionFromAccessTokenEdge(data: any): Promise<[string, any, string] | []> {\n const accessToken = data.accessToken ?? data.access_token;\n const refreshToken = data.refreshToken ?? data.refresh_token;\n const { payload: decodedJwt }: any = await JwtManager.verify(accessToken);\n decodedJwt.expiresIn = Math.floor((decodedJwt.exp * 1000 - Date.now()) / 1000);\n\n const tokens = { accessToken, refreshToken };\n const session = await encryptionEdge.sealTokens(tokens, decodedJwt.exp);\n return [session, decodedJwt, refreshToken];\n}\n\nexport const getSessionOnEdge = (req: IncomingMessage | Request): Promise<FronteggNextJSSession | undefined> => {\n const cookies = CookieManager.getSessionCookieFromRequest(req);\n return createSession(cookies, encryptionEdge);\n};\n\nexport const handleHostedLoginCallback = async (\n req: IncomingMessage | Request,\n pathname: string,\n searchParams: URLSearchParams\n): Promise<NextResponse> => {\n if (!isHostedLoginCallback(pathname, searchParams)) {\n return NextResponse.next();\n }\n\n const code = searchParams.get('code') ?? '';\n\n let headers: Record<string, string> = {};\n let clientIp: string | undefined = undefined;\n if (typeof req.headers?.get === 'function') {\n clientIp =\n req.headers.get('cf-connecting-ip') || req.headers.get('x-forwarded-for') || (req as any).socket?.remoteAddress;\n } else if (typeof req.headers === 'object') {\n let requestHeaders: any = { ...req.headers };\n clientIp =\n requestHeaders['cf-connecting-ip'] || requestHeaders['x-forwarded-for'] || (req as any).socket?.remoteAddress;\n }\n\n if (clientIp && config.shouldForwardIp) {\n headers[FRONTEGG_FORWARD_IP_HEADER] = clientIp;\n headers[FRONTEGG_CLIENT_SECRET_HEADER] = config.clientSecret ?? '';\n }\n\n const response = await api.exchangeHostedLoginToken(\n buildRequestHeaders(headers),\n code,\n config.clientId,\n config.clientSecret!\n );\n\n const data = await response.json();\n\n const [session, decodedJwt, refreshToken] = await createSessionFromAccessTokenEdge(data);\n\n if (!session) {\n return NextResponse.redirect(config.appUrl);\n }\n const isSecured = config.isSSL;\n const cookieValue = CookieManager.create({\n value: session,\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n });\n\n let cookieName = `fe_refresh_${config.clientId.replace('-', '')}`;\n if (config.rewriteCookieByAppId && config.appId) {\n cookieName = `fe_refresh_${config.appId.replace('-', '')}`;\n }\n const refreshCookie = CookieManager.create({\n cookieName,\n value: refreshToken ?? '',\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n });\n const sessionCookieHeaders: [string, string][] = cookieValue.map((cookie) => ['set-cookie', cookie]);\n const refreshCookieHeaders: [string, string][] = refreshCookie.map((cookie) => ['set-cookie', cookie]);\n\n return NextResponse.redirect(config.appUrl, {\n headers: [...sessionCookieHeaders, ...refreshCookieHeaders],\n });\n};\n\nexport const isHostedLoginCallback = (pathname: string, searchParams: URLSearchParams): boolean => {\n if (config.secureJwtEnabled) {\n if (pathname.startsWith('/oauth/callback')) {\n return searchParams.get('code') != null;\n }\n }\n return false;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"getSessionOnEdge.js","names":["_cookies","_interopRequireDefault","require","_createSession","_encryptionEdge","_api","_server","_config","_jwt","_utils","_fronteggLogger","_refreshAccessTokenIfNeededOnEdge","_redirectToLogin","_shouldBypassMiddleware","logger","fronteggLogger","child","tag","handleSessionOnEdge","params","request","pathname","searchParams","headers","isHostedLoginCallback","handleHostedLoginCallback","shouldByPassMiddleware","NextResponse","next","edgeSession","checkSessionOnEdge","redirectToLogin","exports","GET_SESSION_ON_EDGE_DEPRECATED_ERROR","getSessionOnEdge","req","Error","sessionCookies","CookieManager","getSessionCookieFromRequest","existingSession","createSession","encryptionEdge","debug","session","refreshAccessTokenIfNeededOnEdge","createSessionFromAccessTokenEdge","data","_data$accessToken","_data$refreshToken","accessToken","access_token","refreshToken","refresh_token","payload","decodedJwt","JwtManager","verify","expiresIn","Math","floor","exp","Date","now","tokens","sealTokens","_searchParams$get","_req$headers","code","get","clientIp","undefined","_socket","socket","remoteAddress","_socket2","requestHeaders","_extends2","default","config","shouldForwardIp","_config$clientSecret","FRONTEGG_FORWARD_IP_HEADER","FRONTEGG_CLIENT_SECRET_HEADER","clientSecret","response","api","exchangeHostedLoginToken","buildRequestHeaders","clientId","json","redirect","appUrl","isSecured","isSSL","cookieValue","create","value","expires","secure","cookieName","replace","rewriteCookieByAppId","appId","refreshCookie","sessionCookieHeaders","map","cookie","refreshCookieHeaders","secureJwtEnabled","startsWith"],"sources":["../../../../packages/nextjs/src/edge/getSessionOnEdge.ts"],"sourcesContent":["import type { IncomingMessage } from 'http';\nimport { FronteggEdgeSession } from '../types';\nimport CookieManager from '../utils/cookies';\nimport createSession from '../utils/createSession';\nimport encryptionEdge from '../utils/encryption-edge';\nimport api from '../api';\nimport { type NextRequest, NextResponse } from 'next/server';\nimport config from '../config';\nimport JwtManager from '../utils/jwt';\nimport { buildRequestHeaders, FRONTEGG_CLIENT_SECRET_HEADER, FRONTEGG_FORWARD_IP_HEADER } from '../api/utils';\nimport fronteggLogger from '../utils/fronteggLogger';\nimport { refreshAccessTokenIfNeededOnEdge } from './refreshAccessTokenIfNeededOnEdge';\nimport { redirectToLogin } from './redirectToLogin';\nimport { shouldByPassMiddleware } from './shouldBypassMiddleware';\n\nconst logger = fronteggLogger.child({ tag: 'EdgeRuntime.getSessionOnEdge' });\n\nexport type HandleSessionOnEdge = {\n request: IncomingMessage | Request;\n pathname: string;\n headers: NextRequest['headers'];\n searchParams: URLSearchParams;\n};\n\nexport const handleSessionOnEdge = async (params: HandleSessionOnEdge): Promise<NextResponse> => {\n const { request, pathname, searchParams, headers } = params;\n\n if (isHostedLoginCallback(pathname, searchParams)) {\n return handleHostedLoginCallback(request, pathname, searchParams);\n }\n\n if (shouldByPassMiddleware(pathname, headers /*, options: optional bypass configuration */)) {\n return NextResponse.next();\n }\n\n const edgeSession = await checkSessionOnEdge(request);\n if (!edgeSession) {\n return redirectToLogin(pathname, searchParams);\n }\n if (edgeSession.headers) {\n return NextResponse.next({\n headers: edgeSession.headers,\n });\n }\n return NextResponse.next();\n};\n\nconst GET_SESSION_ON_EDGE_DEPRECATED_ERROR = `Deprecation Notice: getSessionOnEdge has been deprecated. Please use handleSessionOnEdge instead. For example:\n\nfile: middleware.ts\n\\`\\`\\`ts\n import { NextRequest } from 'next/server';\n import { handleSessionOnEdge } from '@frontegg/nextjs/edge';\n \n export const middleware = async (request: NextRequest) => {\n const { pathname, searchParams } = request.nextUrl;\n const headers = request.headers;\n \n // Additional logic if needed\n \n return handleSessionOnEdge({ request, pathname, searchParams, headers });\n };\n \n \n export const config = {\n matcher: '/(.*)',\n };\n\n\\`\\`\\`\n\nAlternatively, to manually verify the session, you can use checkSessionOnEdge. Note that this method does not redirect to the login page if the session is invalid.\n`;\n\n/**\n * getSessionOnEdge is deprecated, please use handleSessionOnEdge instead example:\n *\n * ```ts\n * import { NextRequest } from 'next/server';\n * import { handleSessionOnEdge } from '@frontegg/nextjs/edge';\n *\n * export const middleware = async (request: NextRequest) => {\n * const { pathname, searchParams } = request.nextUrl;\n * const headers = request.headers;\n *\n * // Additional logic if needed\n *\n * return handleSessionOnEdge({ request, pathname, searchParams, headers });\n * };\n *\n * export const config = {\n * matcher: '/(.*)',\n * };\n * ```\n * @deprecated\n */\nexport const getSessionOnEdge = async (req: IncomingMessage | Request): Promise<FronteggEdgeSession | undefined> => {\n throw new Error(GET_SESSION_ON_EDGE_DEPRECATED_ERROR);\n};\n\n/**\n * Check session on edge and return session if exists this method does not redirect to login page\n * Example:\n *\n * ```ts\n * import { NextRequest } from 'next/server';\n * import { handleSessionOnEdge } from '@frontegg/nextjs/edge';\n *\n * export const middleware = async (request: NextRequest) => {\n * const { pathname, searchParams } = request.nextUrl;\n * const headers = request.headers;\n *\n * // Additional logic if needed\n *\n * // check if it's a hosted login callback\n * if (isHostedLoginCallback(pathname, searchParams)) {\n * return handleHostedLoginCallback(request, pathname, searchParams);\n * }\n *\n * // check if we should bypass the middleware\n * if (shouldByPassMiddleware(pathname)) {\n * return NextResponse.next();\n * }\n *\n * // check session\n * const session = await checkSessionOnEdge(request);\n *\n * if (!session) {\n * return redirectToLogin(pathname);\n * }\n *\n * // if headers are present return them to the next response\n * if (session.headers) {\n * return NextResponse.next({\n * headers: session.headers,\n * });\n * }\n * return NextResponse.next();\n * };\n * ```\n *\n *\n * @param req\n */\nexport const checkSessionOnEdge = async (req: IncomingMessage | Request): Promise<FronteggEdgeSession | undefined> => {\n const sessionCookies = CookieManager.getSessionCookieFromRequest(req);\n let existingSession = await createSession(sessionCookies, encryptionEdge);\n if (existingSession) {\n logger.debug('session resolved from session cookie');\n return {\n session: existingSession,\n };\n }\n\n logger.debug('Failed to resolve session from cookie, going to refresh token');\n return refreshAccessTokenIfNeededOnEdge(req);\n};\n\nasync function createSessionFromAccessTokenEdge(data: any): Promise<[string, any, string] | []> {\n const accessToken = data.accessToken ?? data.access_token;\n const refreshToken = data.refreshToken ?? data.refresh_token;\n const { payload: decodedJwt }: any = await JwtManager.verify(accessToken);\n decodedJwt.expiresIn = Math.floor((decodedJwt.exp * 1000 - Date.now()) / 1000);\n\n const tokens = { accessToken, refreshToken };\n const session = await encryptionEdge.sealTokens(tokens, decodedJwt.exp);\n return [session, decodedJwt, refreshToken];\n}\n\nexport const handleHostedLoginCallback = async (\n req: IncomingMessage | Request,\n pathname: string,\n searchParams: URLSearchParams\n): Promise<NextResponse> => {\n if (!isHostedLoginCallback(pathname, searchParams)) {\n return NextResponse.next();\n }\n\n const code = searchParams.get('code') ?? '';\n\n let headers: Record<string, string> = {};\n let clientIp: string | undefined = undefined;\n if (typeof req.headers?.get === 'function') {\n clientIp =\n req.headers.get('cf-connecting-ip') || req.headers.get('x-forwarded-for') || (req as any).socket?.remoteAddress;\n } else if (typeof req.headers === 'object') {\n let requestHeaders: any = { ...req.headers };\n clientIp =\n requestHeaders['cf-connecting-ip'] || requestHeaders['x-forwarded-for'] || (req as any).socket?.remoteAddress;\n }\n\n if (clientIp && config.shouldForwardIp) {\n headers[FRONTEGG_FORWARD_IP_HEADER] = clientIp;\n headers[FRONTEGG_CLIENT_SECRET_HEADER] = config.clientSecret ?? '';\n }\n\n const response = await api.exchangeHostedLoginToken(\n buildRequestHeaders(headers),\n code,\n config.clientId,\n config.clientSecret!\n );\n\n const data = await response.json();\n\n const [session, decodedJwt, refreshToken] = await createSessionFromAccessTokenEdge(data);\n\n if (!session) {\n return NextResponse.redirect(config.appUrl);\n }\n const isSecured = config.isSSL;\n const cookieValue = CookieManager.create({\n value: session,\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n });\n\n let cookieName = `fe_refresh_${config.clientId.replace('-', '')}`;\n if (config.rewriteCookieByAppId && config.appId) {\n cookieName = `fe_refresh_${config.appId.replace('-', '')}`;\n }\n const refreshCookie = CookieManager.create({\n cookieName,\n value: refreshToken ?? '',\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n });\n const sessionCookieHeaders: [string, string][] = cookieValue.map((cookie) => ['set-cookie', cookie]);\n const refreshCookieHeaders: [string, string][] = refreshCookie.map((cookie) => ['set-cookie', cookie]);\n\n return NextResponse.redirect(config.appUrl, {\n headers: [...sessionCookieHeaders, ...refreshCookieHeaders],\n });\n};\n\nexport const isHostedLoginCallback = (pathname: string, searchParams: URLSearchParams): boolean => {\n if (config.secureJwtEnabled) {\n if (pathname.startsWith('/oauth/callback')) {\n return searchParams.get('code') != null;\n }\n }\n return false;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { FronteggEdgeSession } from '../types';
|
|
2
|
+
import type { IncomingMessage } from 'http';
|
|
3
|
+
export declare function refreshAccessTokenIfNeededOnEdge(req: IncomingMessage | Request): Promise<FronteggEdgeSession | undefined>;
|
|
4
|
+
export declare function createSessionFromAccessTokenOnEdge(data: any): Promise<[string, any, string] | []>;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.createSessionFromAccessTokenOnEdge = createSessionFromAccessTokenOnEdge;
|
|
8
|
+
exports.refreshAccessTokenIfNeededOnEdge = refreshAccessTokenIfNeededOnEdge;
|
|
9
|
+
var _cookies = _interopRequireDefault(require("../utils/cookies"));
|
|
10
|
+
var _config = _interopRequireDefault(require("../config"));
|
|
11
|
+
var _api = _interopRequireDefault(require("../api"));
|
|
12
|
+
var _fronteggLogger = _interopRequireDefault(require("../utils/fronteggLogger"));
|
|
13
|
+
var _jwt = _interopRequireDefault(require("../utils/jwt"));
|
|
14
|
+
var _encryptionEdge = _interopRequireDefault(require("../utils/encryption-edge"));
|
|
15
|
+
const logger = _fronteggLogger.default.child({
|
|
16
|
+
tag: 'EdgeRuntime.refreshAccessTokenIfNeededOnEdge'
|
|
17
|
+
});
|
|
18
|
+
async function refreshAccessTokenIfNeededOnEdge(req) {
|
|
19
|
+
var _ref, _ref2, _response$headers$raw, _response$headers, _response$headers$raw2, _response$headers2, _response$headers2$ge, _response$headers3, _response$headers3$ge, _CookieManager$modify, _data$accessToken;
|
|
20
|
+
const refreshCookie = _cookies.default.getRefreshCookieFromRequestEdge(req);
|
|
21
|
+
if (!refreshCookie) {
|
|
22
|
+
logger.info('No refresh cookie found, No session found');
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
logger.info('going to refresh token');
|
|
26
|
+
const reqHeaders = req.headers;
|
|
27
|
+
const headers = {};
|
|
28
|
+
reqHeaders.forEach((value, key) => {
|
|
29
|
+
headers[key] = value;
|
|
30
|
+
});
|
|
31
|
+
const clientId = _config.default.clientId;
|
|
32
|
+
const clientSecret = _config.default.clientSecret;
|
|
33
|
+
let response;
|
|
34
|
+
try {
|
|
35
|
+
if (_config.default.isHostedLogin) {
|
|
36
|
+
response = await _api.default.refreshTokenHostedLogin(headers, refreshCookie, clientId, clientSecret);
|
|
37
|
+
} else {
|
|
38
|
+
response = await _api.default.refreshTokenEmbedded(headers);
|
|
39
|
+
}
|
|
40
|
+
} catch (e) {
|
|
41
|
+
logger.error('Failed to refresh token', e);
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const isSecured = _config.default.isSSL;
|
|
45
|
+
if (response === null || !response.ok) {
|
|
46
|
+
const cookiesToRemove = _cookies.default.getRequestCookiesHeaderToRemove({
|
|
47
|
+
cookieDomain: _config.default.cookieDomain,
|
|
48
|
+
isSecured,
|
|
49
|
+
req
|
|
50
|
+
});
|
|
51
|
+
if (cookiesToRemove) {
|
|
52
|
+
return {
|
|
53
|
+
session: undefined,
|
|
54
|
+
headers: {
|
|
55
|
+
'set-cookie': cookiesToRemove.join(', ')
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
const data = await response.json();
|
|
62
|
+
const cookieHeader = // @ts-ignore the first argument "raw" will only work before nextjs 13.4 and the second argument "getSetCookie" will only work after
|
|
63
|
+
(_ref = (_ref2 = (_response$headers$raw = (_response$headers = response.headers) == null || (_response$headers$raw2 = _response$headers.raw) == null ? void 0 : _response$headers$raw2.call(_response$headers)['set-cookie']) != null ? _response$headers$raw : // @ts-ignore the first argument "raw" will only work before nextjs 13.4 and the second argument "getSetCookie" will only work after
|
|
64
|
+
(_response$headers2 = response.headers) == null || (_response$headers2$ge = _response$headers2.getSetCookie) == null ? void 0 : _response$headers2$ge.call(_response$headers2)) != null ? _ref2 : (_response$headers3 = response.headers) == null || (_response$headers3$ge = _response$headers3.get) == null ? void 0 : _response$headers3$ge.call(_response$headers3, 'set-cookie')) != null ? _ref : [];
|
|
65
|
+
const newSetCookie = (_CookieManager$modify = _cookies.default.modifySetCookie(cookieHeader, isSecured)) != null ? _CookieManager$modify : [];
|
|
66
|
+
const [session, decodedJwt, refreshToken] = await createSessionFromAccessTokenOnEdge(data);
|
|
67
|
+
if (!session) {
|
|
68
|
+
return {
|
|
69
|
+
session: undefined,
|
|
70
|
+
headers: {
|
|
71
|
+
'set-cookie': newSetCookie.join(', ')
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const cookieValue = _cookies.default.create({
|
|
76
|
+
value: session,
|
|
77
|
+
expires: new Date(decodedJwt.exp * 1000),
|
|
78
|
+
secure: isSecured,
|
|
79
|
+
req
|
|
80
|
+
});
|
|
81
|
+
newSetCookie.push(...cookieValue);
|
|
82
|
+
return {
|
|
83
|
+
session: {
|
|
84
|
+
accessToken: (_data$accessToken = data.accessToken) != null ? _data$accessToken : data.access_token,
|
|
85
|
+
user: decodedJwt,
|
|
86
|
+
refreshToken
|
|
87
|
+
},
|
|
88
|
+
headers: {
|
|
89
|
+
'set-cookie': newSetCookie.join(', ')
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async function createSessionFromAccessTokenOnEdge(data) {
|
|
94
|
+
var _data$accessToken2, _data$refreshToken;
|
|
95
|
+
const accessToken = (_data$accessToken2 = data.accessToken) != null ? _data$accessToken2 : data.access_token;
|
|
96
|
+
const refreshToken = (_data$refreshToken = data.refreshToken) != null ? _data$refreshToken : data.refresh_token;
|
|
97
|
+
const {
|
|
98
|
+
payload: decodedJwt
|
|
99
|
+
} = await _jwt.default.verify(accessToken);
|
|
100
|
+
decodedJwt.expiresIn = Math.floor((decodedJwt.exp * 1000 - Date.now()) / 1000);
|
|
101
|
+
const tokens = {
|
|
102
|
+
accessToken,
|
|
103
|
+
refreshToken
|
|
104
|
+
};
|
|
105
|
+
const session = await _encryptionEdge.default.sealTokens(tokens, decodedJwt.exp);
|
|
106
|
+
return [session, decodedJwt, refreshToken];
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=refreshAccessTokenIfNeededOnEdge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refreshAccessTokenIfNeededOnEdge.js","names":["_cookies","_interopRequireDefault","require","_config","_api","_fronteggLogger","_jwt","_encryptionEdge","logger","fronteggLogger","child","tag","refreshAccessTokenIfNeededOnEdge","req","_ref","_ref2","_response$headers$raw","_response$headers","_response$headers$raw2","_response$headers2","_response$headers2$ge","_response$headers3","_response$headers3$ge","_CookieManager$modify","_data$accessToken","refreshCookie","CookieManager","getRefreshCookieFromRequestEdge","info","undefined","reqHeaders","headers","forEach","value","key","clientId","config","clientSecret","response","isHostedLogin","api","refreshTokenHostedLogin","refreshTokenEmbedded","e","error","isSecured","isSSL","ok","cookiesToRemove","getRequestCookiesHeaderToRemove","cookieDomain","session","join","data","json","cookieHeader","raw","call","getSetCookie","get","newSetCookie","modifySetCookie","decodedJwt","refreshToken","createSessionFromAccessTokenOnEdge","cookieValue","create","expires","Date","exp","secure","push","accessToken","access_token","user","_data$accessToken2","_data$refreshToken","refresh_token","payload","JwtManager","verify","expiresIn","Math","floor","now","tokens","encryptionEdge","sealTokens"],"sources":["../../../../packages/nextjs/src/edge/refreshAccessTokenIfNeededOnEdge.ts"],"sourcesContent":["import { FronteggEdgeSession } from '../types';\nimport type { IncomingMessage } from 'http';\nimport CookieManager from '../utils/cookies';\nimport config from '../config';\nimport api from '../api';\nimport fronteggLogger from '../utils/fronteggLogger';\nimport JwtManager from '../utils/jwt';\nimport encryptionEdge from '../utils/encryption-edge';\n\nconst logger = fronteggLogger.child({ tag: 'EdgeRuntime.refreshAccessTokenIfNeededOnEdge' });\n\nexport async function refreshAccessTokenIfNeededOnEdge(\n req: IncomingMessage | Request\n): Promise<FronteggEdgeSession | undefined> {\n const refreshCookie = CookieManager.getRefreshCookieFromRequestEdge(req);\n if (!refreshCookie) {\n logger.info('No refresh cookie found, No session found');\n return undefined;\n }\n\n logger.info('going to refresh token');\n\n const reqHeaders = req.headers as any as Map<string, string>;\n const headers: Record<string, string> = {};\n reqHeaders.forEach((value: string, key: string) => {\n headers[key] = value;\n });\n const clientId = config.clientId;\n const clientSecret = config.clientSecret;\n\n let response: Response | null;\n try {\n if (config.isHostedLogin) {\n response = await api.refreshTokenHostedLogin(headers, refreshCookie, clientId, clientSecret);\n } else {\n response = await api.refreshTokenEmbedded(headers);\n }\n } catch (e) {\n logger.error('Failed to refresh token', e);\n return undefined;\n }\n\n const isSecured = config.isSSL;\n if (response === null || !response.ok) {\n const cookiesToRemove = CookieManager.getRequestCookiesHeaderToRemove({\n cookieDomain: config.cookieDomain,\n isSecured,\n req,\n });\n if (cookiesToRemove) {\n return {\n session: undefined,\n headers: {\n 'set-cookie': cookiesToRemove.join(', '),\n },\n };\n }\n return undefined;\n }\n\n const data = await response.json();\n\n const cookieHeader: string[] =\n // @ts-ignore the first argument \"raw\" will only work before nextjs 13.4 and the second argument \"getSetCookie\" will only work after\n response.headers?.raw?.()['set-cookie'] ??\n // @ts-ignore the first argument \"raw\" will only work before nextjs 13.4 and the second argument \"getSetCookie\" will only work after\n response.headers?.getSetCookie?.() ??\n response.headers?.get?.('set-cookie') ??\n [];\n\n const newSetCookie = CookieManager.modifySetCookie(cookieHeader, isSecured) ?? [];\n const [session, decodedJwt, refreshToken] = await createSessionFromAccessTokenOnEdge(data);\n\n if (!session) {\n return {\n session: undefined,\n headers: {\n 'set-cookie': newSetCookie.join(', '),\n },\n };\n }\n\n const cookieValue = CookieManager.create({\n value: session,\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n req,\n });\n newSetCookie.push(...cookieValue);\n\n return {\n session: {\n accessToken: data.accessToken ?? data.access_token,\n user: decodedJwt,\n refreshToken,\n },\n headers: {\n 'set-cookie': newSetCookie.join(', '),\n },\n };\n}\n\nexport async function createSessionFromAccessTokenOnEdge(data: any): Promise<[string, any, string] | []> {\n const accessToken = data.accessToken ?? data.access_token;\n const refreshToken = data.refreshToken ?? data.refresh_token;\n const { payload: decodedJwt }: any = await JwtManager.verify(accessToken);\n decodedJwt.expiresIn = Math.floor((decodedJwt.exp * 1000 - Date.now()) / 1000);\n\n const tokens = { accessToken, refreshToken };\n const session = await encryptionEdge.sealTokens(tokens, decodedJwt.exp);\n return [session, decodedJwt, refreshToken];\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { NextRequest } from 'next/server';
|
|
1
2
|
interface ByPassOptions {
|
|
2
3
|
bypassStaticFiles?: boolean;
|
|
3
4
|
bypassImageOptimization?: boolean;
|
|
@@ -17,5 +18,5 @@ interface ByPassOptions {
|
|
|
17
18
|
* - api/frontegg (API frontegg middleware)
|
|
18
19
|
* - account/[login|logout|saml/callback|...] (frontegg authentication routes)
|
|
19
20
|
*/
|
|
20
|
-
export declare const shouldByPassMiddleware: (pathname: string, options?: ByPassOptions) => boolean;
|
|
21
|
+
export declare const shouldByPassMiddleware: (pathname: string, headers: NextRequest['headers'], options?: ByPassOptions) => boolean;
|
|
21
22
|
export {};
|
|
@@ -27,7 +27,7 @@ const fronteggMiddlewareRegex = new RegExp('^/(api/frontegg).*');
|
|
|
27
27
|
* - api/frontegg (API frontegg middleware)
|
|
28
28
|
* - account/[login|logout|saml/callback|...] (frontegg authentication routes)
|
|
29
29
|
*/
|
|
30
|
-
const shouldByPassMiddleware = (pathname, options) => {
|
|
30
|
+
const shouldByPassMiddleware = (pathname, headers, options) => {
|
|
31
31
|
const _options = (0, _extends2.default)({
|
|
32
32
|
bypassStaticFiles: true,
|
|
33
33
|
bypassImageOptimization: true,
|
|
@@ -48,6 +48,12 @@ const shouldByPassMiddleware = (pathname, options) => {
|
|
|
48
48
|
if (isHeaderRequests) return _options.bypassHeaderRequests;
|
|
49
49
|
if (isFronteggMiddleware) return _options.bypassFronteggMiddleware;
|
|
50
50
|
if (isFronteggRoutes) return _options.bypassFronteggRoutes;
|
|
51
|
+
|
|
52
|
+
// noinspection RedundantIfStatementJS
|
|
53
|
+
if (headers.has('next-router-prefetch') || headers.get('purpose') === 'prefetch') {
|
|
54
|
+
/** bypass prefetch requests on hovering links that leads to SSG pages **/
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
51
57
|
return false;
|
|
52
58
|
};
|
|
53
59
|
exports.shouldByPassMiddleware = shouldByPassMiddleware;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shouldBypassMiddleware.js","names":["_routing","require","_excluded","staticFilesRegex","RegExp","imageOptimizationRegex","headerRequestsRegex","fronteggMiddlewareRegex","shouldByPassMiddleware","pathname","options","_options","_extends2","default","bypassStaticFiles","bypassImageOptimization","bypassHeaderRequests","bypassFronteggMiddleware","bypassFronteggRoutes","bypassAuthSamlCallback","isStaticFiles","test","isImageOptimization","isHeaderRequests","isFronteggMiddleware","authRoutes","_objectWithoutPropertiesLoose2","defaultFronteggRoutes","isFronteggRoutes","Object","values","find","path","startsWith","exports"],"sources":["../../../../packages/nextjs/src/edge/shouldBypassMiddleware.ts"],"sourcesContent":["import { defaultFronteggRoutes } from '../utils/routing';\n\nconst staticFilesRegex = new RegExp('^/(_next/static).*');\nconst imageOptimizationRegex = new RegExp('^/(_next/image).*');\nconst headerRequestsRegex = new RegExp('^/(favicon.ico).*');\nconst fronteggMiddlewareRegex = new RegExp('^/(api/frontegg).*');\n\ninterface ByPassOptions {\n bypassStaticFiles?: boolean; // default: true\n bypassImageOptimization?: boolean; // default: true\n bypassHeaderRequests?: boolean; // default: true\n}\n\n/**\n * Use `shouldByPassMiddleware` in the middleware.ts file\n * to protect all application's routes.\n * You can override whitelist by passing options parameter\n * NOTE: this will slow down your application due to session check on each\n * static files and image request\n *\n * The default whitelist:\n * - _next/static (static files)\n * - _next/image (image optimization files)\n * - favicon.ico (favicon file)\n * - api/frontegg (API frontegg middleware)\n * - account/[login|logout|saml/callback|...] (frontegg authentication routes)\n */\nexport const shouldByPassMiddleware = (pathname: string
|
|
1
|
+
{"version":3,"file":"shouldBypassMiddleware.js","names":["_routing","require","_excluded","staticFilesRegex","RegExp","imageOptimizationRegex","headerRequestsRegex","fronteggMiddlewareRegex","shouldByPassMiddleware","pathname","headers","options","_options","_extends2","default","bypassStaticFiles","bypassImageOptimization","bypassHeaderRequests","bypassFronteggMiddleware","bypassFronteggRoutes","bypassAuthSamlCallback","isStaticFiles","test","isImageOptimization","isHeaderRequests","isFronteggMiddleware","authRoutes","_objectWithoutPropertiesLoose2","defaultFronteggRoutes","isFronteggRoutes","Object","values","find","path","startsWith","has","get","exports"],"sources":["../../../../packages/nextjs/src/edge/shouldBypassMiddleware.ts"],"sourcesContent":["import type { NextRequest } from 'next/server';\n\nimport { defaultFronteggRoutes } from '../utils/routing';\n\nconst staticFilesRegex = new RegExp('^/(_next/static).*');\nconst imageOptimizationRegex = new RegExp('^/(_next/image).*');\nconst headerRequestsRegex = new RegExp('^/(favicon.ico).*');\nconst fronteggMiddlewareRegex = new RegExp('^/(api/frontegg).*');\n\ninterface ByPassOptions {\n bypassStaticFiles?: boolean; // default: true\n bypassImageOptimization?: boolean; // default: true\n bypassHeaderRequests?: boolean; // default: true\n}\n\n/**\n * Use `shouldByPassMiddleware` in the middleware.ts file\n * to protect all application's routes.\n * You can override whitelist by passing options parameter\n * NOTE: this will slow down your application due to session check on each\n * static files and image request\n *\n * The default whitelist:\n * - _next/static (static files)\n * - _next/image (image optimization files)\n * - favicon.ico (favicon file)\n * - api/frontegg (API frontegg middleware)\n * - account/[login|logout|saml/callback|...] (frontegg authentication routes)\n */\nexport const shouldByPassMiddleware = (\n pathname: string,\n headers: NextRequest['headers'],\n options?: ByPassOptions\n): boolean => {\n const _options = {\n bypassStaticFiles: true,\n bypassImageOptimization: true,\n bypassHeaderRequests: true,\n ...options,\n bypassFronteggMiddleware: true,\n bypassFronteggRoutes: true,\n bypassAuthSamlCallback: true,\n };\n\n const isStaticFiles = staticFilesRegex.test(pathname);\n const isImageOptimization = imageOptimizationRegex.test(pathname);\n const isHeaderRequests = headerRequestsRegex.test(pathname);\n const isFronteggMiddleware = fronteggMiddlewareRegex.test(pathname);\n\n const { authenticatedUrl, ...authRoutes } = defaultFronteggRoutes;\n const isFronteggRoutes = Object.values(authRoutes).find((path) => pathname.startsWith(path)) != null;\n\n if (isStaticFiles) return _options.bypassStaticFiles;\n if (isImageOptimization) return _options.bypassImageOptimization;\n if (isHeaderRequests) return _options.bypassHeaderRequests;\n if (isFronteggMiddleware) return _options.bypassFronteggMiddleware;\n if (isFronteggRoutes) return _options.bypassFronteggRoutes;\n\n // noinspection RedundantIfStatementJS\n if (headers.has('next-router-prefetch') || headers.get('purpose') === 'prefetch') {\n /** bypass prefetch requests on hovering links that leads to SSG pages **/\n return true;\n }\n\n return false;\n};\n"],"mappings":";;;;;;;;;AAEA,IAAAA,QAAA,GAAAC,OAAA;AAAyD,MAAAC,SAAA;AAEzD,MAAMC,gBAAgB,GAAG,IAAIC,MAAM,CAAC,oBAAoB,CAAC;AACzD,MAAMC,sBAAsB,GAAG,IAAID,MAAM,CAAC,mBAAmB,CAAC;AAC9D,MAAME,mBAAmB,GAAG,IAAIF,MAAM,CAAC,mBAAmB,CAAC;AAC3D,MAAMG,uBAAuB,GAAG,IAAIH,MAAM,CAAC,oBAAoB,CAAC;AAQhE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMI,sBAAsB,GAAGA,CACpCC,QAAgB,EAChBC,OAA+B,EAC/BC,OAAuB,KACX;EACZ,MAAMC,QAAQ,OAAAC,SAAA,CAAAC,OAAA;IACZC,iBAAiB,EAAE,IAAI;IACvBC,uBAAuB,EAAE,IAAI;IAC7BC,oBAAoB,EAAE;EAAI,GACvBN,OAAO;IACVO,wBAAwB,EAAE,IAAI;IAC9BC,oBAAoB,EAAE,IAAI;IAC1BC,sBAAsB,EAAE;EAAI,EAC7B;EAED,MAAMC,aAAa,GAAGlB,gBAAgB,CAACmB,IAAI,CAACb,QAAQ,CAAC;EACrD,MAAMc,mBAAmB,GAAGlB,sBAAsB,CAACiB,IAAI,CAACb,QAAQ,CAAC;EACjE,MAAMe,gBAAgB,GAAGlB,mBAAmB,CAACgB,IAAI,CAACb,QAAQ,CAAC;EAC3D,MAAMgB,oBAAoB,GAAGlB,uBAAuB,CAACe,IAAI,CAACb,QAAQ,CAAC;EAEnE,MAA6BiB,UAAU,OAAAC,8BAAA,CAAAb,OAAA,EAAKc,8BAAqB,EAAA1B,SAAA;EACjE,MAAM2B,gBAAgB,GAAGC,MAAM,CAACC,MAAM,CAACL,UAAU,CAAC,CAACM,IAAI,CAAEC,IAAI,IAAKxB,QAAQ,CAACyB,UAAU,CAACD,IAAI,CAAC,CAAC,IAAI,IAAI;EAEpG,IAAIZ,aAAa,EAAE,OAAOT,QAAQ,CAACG,iBAAiB;EACpD,IAAIQ,mBAAmB,EAAE,OAAOX,QAAQ,CAACI,uBAAuB;EAChE,IAAIQ,gBAAgB,EAAE,OAAOZ,QAAQ,CAACK,oBAAoB;EAC1D,IAAIQ,oBAAoB,EAAE,OAAOb,QAAQ,CAACM,wBAAwB;EAClE,IAAIW,gBAAgB,EAAE,OAAOjB,QAAQ,CAACO,oBAAoB;;EAE1D;EACA,IAAIT,OAAO,CAACyB,GAAG,CAAC,sBAAsB,CAAC,IAAIzB,OAAO,CAAC0B,GAAG,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE;IAChF;IACA,OAAO,IAAI;EACb;EAEA,OAAO,KAAK;AACd,CAAC;AAACC,OAAA,CAAA7B,sBAAA,GAAAA,sBAAA","ignoreList":[]}
|
package/index.js
CHANGED
|
@@ -96,7 +96,7 @@ const ProxyResponseCallback = (proxyRes, req, res) => {
|
|
|
96
96
|
res.setHeader(header, `${proxyRes.headers[header]}`);
|
|
97
97
|
});
|
|
98
98
|
res.setHeader('set-cookie', cookies);
|
|
99
|
-
res.setHeader('content-length', bodyStr
|
|
99
|
+
res.setHeader('content-length', Buffer.byteLength(bodyStr));
|
|
100
100
|
res.status(statusCode).end(bodyStr);
|
|
101
101
|
} else {
|
|
102
102
|
if (statusCode >= 400 && statusCode !== 404) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProxyResponseCallback.js","names":["_config","_interopRequireDefault","require","_cookies","_common","_helpers","_fronteggLogger","_helpers2","logger","fronteggLogger","child","tag","ProxyResponseCallback","proxyRes","req","res","buffer","Buffer","totalLength","isSecured","URL","config","appUrl","protocol","on","chunk","length","concat","_proxyRes$statusCode","_CookieManager$modify","url","statusCode","isSuccess","bodyStr","toString","isLogout","isFronteggLogoutUrl","CookieManager","removeCookies","cookieDomain","isFronteggOauthLogoutUrl","isHostedLogin","asPath","hostedLogoutUrl","getHostedLogoutUrl","headers","status","end","cookies","modifySetCookie","tokens","extractAccessToken","accessToken","process","env","JSON","stringify","removeJwtSignatureFrom","parse","session","decodedJwt","createSessionFromAccessToken","sessionCookie","create","value","expires","Date","exp","secure","push","e","isSSOPostRequest","error","Object","keys","filter","header","forEach","setHeader","_default","exports","default"],"sources":["../../../../packages/nextjs/src/middleware/ProxyResponseCallback.ts"],"sourcesContent":["import { ProxyResCallback } from 'http-proxy';\nimport { IncomingMessage } from 'http';\nimport { NextApiResponse } from 'next';\nimport config from '../config';\nimport CookieManager from '../utils/cookies';\nimport { createSessionFromAccessToken } from '../common';\nimport {\n extractAccessToken,\n getHostedLogoutUrl,\n isFronteggLogoutUrl,\n isFronteggOauthLogoutUrl,\n removeJwtSignatureFrom,\n} from './helpers';\nimport fronteggLogger from '../utils/fronteggLogger';\nimport { isSSOPostRequest } from '../utils/refreshAccessTokenIfNeeded/helpers';\n\nconst logger = fronteggLogger.child({ tag: 'FronteggApiMiddleware.ProxyResponseCallback' });\n/**\n * Proxy response callback fired on after each response from Frontegg services,\n * to transport frontegg modify cookies and generating encrypted JWT session cookie.\n *\n * @param {IncomingMessage} proxyRes - Proxy response from Frontegg services\n * @param {NextApiRequest} req - Next.js request sent from client-side\n * @param {NextApiResponse} res - Next.js response to send to client-side\n */\nconst ProxyResponseCallback: ProxyResCallback<IncomingMessage, NextApiResponse> = (proxyRes, req, res) => {\n let buffer = new Buffer('');\n let totalLength: number = 0;\n const isSecured = new URL(config.appUrl).protocol === 'https:';\n\n proxyRes.on('data', (chunk: Buffer) => {\n totalLength += chunk.length;\n buffer = Buffer.concat([buffer, chunk], totalLength);\n });\n proxyRes.on('end', async () => {\n try {\n const url = req.url!;\n const statusCode = proxyRes.statusCode ?? 500;\n const isSuccess = statusCode >= 200 && statusCode < 400;\n let bodyStr = buffer.toString('utf-8');\n const isLogout = isFronteggLogoutUrl(url);\n\n if (isLogout) {\n CookieManager.removeCookies({\n isSecured,\n cookieDomain: config.cookieDomain,\n res,\n req,\n });\n if (isFronteggOauthLogoutUrl(url) || config.isHostedLogin) {\n const { asPath: hostedLogoutUrl } = getHostedLogoutUrl(req.headers['referer']);\n res.status(302).end(hostedLogoutUrl);\n return;\n }\n res.status(statusCode).end(bodyStr);\n return;\n }\n\n const cookies = CookieManager.modifySetCookie(proxyRes.headers['set-cookie'], isSecured) ?? [];\n if (isSuccess) {\n try {\n if (bodyStr && bodyStr.length > 0) {\n const tokens = extractAccessToken(bodyStr);\n\n if (tokens.accessToken) {\n if (process.env['FRONTEGG_SECURE_JWT_ENABLED'] === 'true') {\n bodyStr = JSON.stringify(removeJwtSignatureFrom(JSON.parse(bodyStr)));\n }\n\n const [session, decodedJwt] = await createSessionFromAccessToken(tokens);\n if (session) {\n const sessionCookie = CookieManager.create({\n value: session,\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n req,\n });\n cookies.push(...sessionCookie);\n }\n }\n }\n } catch (e) {\n /** ignore api call if:\n * - Does not have accessToken / access_token\n * - Not json response\n */\n if (statusCode === 302 && isSSOPostRequest(url)) {\n /**\n * Ignore saml/oidc postLogin response with redirect\n */\n } else {\n logger.error('failed to create session', e, {\n url,\n statusCode,\n });\n }\n }\n Object.keys(proxyRes.headers)\n .filter((header) => header !== 'cookie')\n .forEach((header) => {\n res.setHeader(header, `${proxyRes.headers[header]}`);\n });\n res.setHeader('set-cookie', cookies);\n res.setHeader('content-length', bodyStr
|
|
1
|
+
{"version":3,"file":"ProxyResponseCallback.js","names":["_config","_interopRequireDefault","require","_cookies","_common","_helpers","_fronteggLogger","_helpers2","logger","fronteggLogger","child","tag","ProxyResponseCallback","proxyRes","req","res","buffer","Buffer","totalLength","isSecured","URL","config","appUrl","protocol","on","chunk","length","concat","_proxyRes$statusCode","_CookieManager$modify","url","statusCode","isSuccess","bodyStr","toString","isLogout","isFronteggLogoutUrl","CookieManager","removeCookies","cookieDomain","isFronteggOauthLogoutUrl","isHostedLogin","asPath","hostedLogoutUrl","getHostedLogoutUrl","headers","status","end","cookies","modifySetCookie","tokens","extractAccessToken","accessToken","process","env","JSON","stringify","removeJwtSignatureFrom","parse","session","decodedJwt","createSessionFromAccessToken","sessionCookie","create","value","expires","Date","exp","secure","push","e","isSSOPostRequest","error","Object","keys","filter","header","forEach","setHeader","byteLength","_default","exports","default"],"sources":["../../../../packages/nextjs/src/middleware/ProxyResponseCallback.ts"],"sourcesContent":["import { ProxyResCallback } from 'http-proxy';\nimport { IncomingMessage } from 'http';\nimport { NextApiResponse } from 'next';\nimport config from '../config';\nimport CookieManager from '../utils/cookies';\nimport { createSessionFromAccessToken } from '../common';\nimport {\n extractAccessToken,\n getHostedLogoutUrl,\n isFronteggLogoutUrl,\n isFronteggOauthLogoutUrl,\n removeJwtSignatureFrom,\n} from './helpers';\nimport fronteggLogger from '../utils/fronteggLogger';\nimport { isSSOPostRequest } from '../utils/refreshAccessTokenIfNeeded/helpers';\n\nconst logger = fronteggLogger.child({ tag: 'FronteggApiMiddleware.ProxyResponseCallback' });\n/**\n * Proxy response callback fired on after each response from Frontegg services,\n * to transport frontegg modify cookies and generating encrypted JWT session cookie.\n *\n * @param {IncomingMessage} proxyRes - Proxy response from Frontegg services\n * @param {NextApiRequest} req - Next.js request sent from client-side\n * @param {NextApiResponse} res - Next.js response to send to client-side\n */\nconst ProxyResponseCallback: ProxyResCallback<IncomingMessage, NextApiResponse> = (proxyRes, req, res) => {\n let buffer = new Buffer('');\n let totalLength: number = 0;\n const isSecured = new URL(config.appUrl).protocol === 'https:';\n\n proxyRes.on('data', (chunk: Buffer) => {\n totalLength += chunk.length;\n buffer = Buffer.concat([buffer, chunk], totalLength);\n });\n proxyRes.on('end', async () => {\n try {\n const url = req.url!;\n const statusCode = proxyRes.statusCode ?? 500;\n const isSuccess = statusCode >= 200 && statusCode < 400;\n let bodyStr = buffer.toString('utf-8');\n const isLogout = isFronteggLogoutUrl(url);\n\n if (isLogout) {\n CookieManager.removeCookies({\n isSecured,\n cookieDomain: config.cookieDomain,\n res,\n req,\n });\n if (isFronteggOauthLogoutUrl(url) || config.isHostedLogin) {\n const { asPath: hostedLogoutUrl } = getHostedLogoutUrl(req.headers['referer']);\n res.status(302).end(hostedLogoutUrl);\n return;\n }\n res.status(statusCode).end(bodyStr);\n return;\n }\n\n const cookies = CookieManager.modifySetCookie(proxyRes.headers['set-cookie'], isSecured) ?? [];\n if (isSuccess) {\n try {\n if (bodyStr && bodyStr.length > 0) {\n const tokens = extractAccessToken(bodyStr);\n\n if (tokens.accessToken) {\n if (process.env['FRONTEGG_SECURE_JWT_ENABLED'] === 'true') {\n bodyStr = JSON.stringify(removeJwtSignatureFrom(JSON.parse(bodyStr)));\n }\n\n const [session, decodedJwt] = await createSessionFromAccessToken(tokens);\n if (session) {\n const sessionCookie = CookieManager.create({\n value: session,\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n req,\n });\n cookies.push(...sessionCookie);\n }\n }\n }\n } catch (e) {\n /** ignore api call if:\n * - Does not have accessToken / access_token\n * - Not json response\n */\n if (statusCode === 302 && isSSOPostRequest(url)) {\n /**\n * Ignore saml/oidc postLogin response with redirect\n */\n } else {\n logger.error('failed to create session', e, {\n url,\n statusCode,\n });\n }\n }\n Object.keys(proxyRes.headers)\n .filter((header) => header !== 'cookie')\n .forEach((header) => {\n res.setHeader(header, `${proxyRes.headers[header]}`);\n });\n res.setHeader('set-cookie', cookies);\n res.setHeader('content-length', Buffer.byteLength(bodyStr));\n res.status(statusCode).end(bodyStr);\n } else {\n if (statusCode >= 400 && statusCode !== 404) {\n logger.error(`Middleware request failed statusCode: ${statusCode} for url: ${url}`);\n }\n Object.keys(proxyRes.headers)\n .filter((header) => header !== 'cookie')\n .forEach((header) => {\n res.setHeader(header, `${proxyRes.headers[header]}`);\n });\n res.setHeader('set-cookie', cookies);\n res.status(statusCode).end(bodyStr);\n }\n } catch (e: any) {\n logger.error('proxy failed to send request', e);\n res.status(500).end('Internal Server Error');\n }\n });\n};\n\nexport default ProxyResponseCallback;\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
package/pages/helpers.d.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
|
|
3
3
|
import type { ParsedUrlQuery } from 'querystring';
|
|
4
4
|
import type { FronteggNextJSSession, RequestType } from '../types';
|
|
5
|
-
|
|
5
|
+
import { ServerResponse } from 'http';
|
|
6
|
+
export declare const getSession: (req: RequestType, res?: ServerResponse) => Promise<FronteggNextJSSession | undefined>;
|
|
6
7
|
export declare function withSSRSession<P extends {
|
|
7
8
|
[key: string]: any;
|
|
8
9
|
} = {
|
package/pages/helpers.js
CHANGED
|
@@ -11,19 +11,24 @@ var _config = _interopRequireDefault(require("../config"));
|
|
|
11
11
|
var _cookies = _interopRequireDefault(require("../utils/cookies"));
|
|
12
12
|
var _createSession = _interopRequireDefault(require("../utils/createSession"));
|
|
13
13
|
var _encryption = _interopRequireDefault(require("../utils/encryption"));
|
|
14
|
-
|
|
14
|
+
var _helpers = require("../utils/refreshAccessTokenIfNeeded/helpers");
|
|
15
|
+
const getSession = (req, res) => {
|
|
16
|
+
if (res && (0, _helpers.hasSetSessionCookie)(res.getHeader('set-cookie'))) {
|
|
17
|
+
const cookies = _cookies.default.getSessionCookieFromRedirectedResponse(res);
|
|
18
|
+
return (0, _createSession.default)(cookies, _encryption.default);
|
|
19
|
+
}
|
|
15
20
|
const cookies = _cookies.default.getSessionCookieFromRequest(req);
|
|
16
21
|
return (0, _createSession.default)(cookies, _encryption.default);
|
|
17
22
|
};
|
|
18
23
|
exports.getSession = getSession;
|
|
19
24
|
function withSSRSession(handler) {
|
|
20
25
|
return async context => {
|
|
21
|
-
const session = await getSession(context.req);
|
|
26
|
+
const session = await getSession(context.req, context.res);
|
|
22
27
|
if (session) {
|
|
23
28
|
return handler(context, session);
|
|
24
29
|
} else {
|
|
25
30
|
var _config$authRoutes$lo, _context$resolvedUrl;
|
|
26
|
-
let loginUrl = (_config$authRoutes$lo = _config.default.authRoutes.loginUrl) != null ? _config$authRoutes$lo : _routing.defaultFronteggRoutes.
|
|
31
|
+
let loginUrl = (_config$authRoutes$lo = _config.default.authRoutes.loginUrl) != null ? _config$authRoutes$lo : _routing.defaultFronteggRoutes.loginUrl;
|
|
27
32
|
if (!loginUrl.startsWith('/')) {
|
|
28
33
|
loginUrl = `/${loginUrl}`;
|
|
29
34
|
}
|
package/pages/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","names":["_routing","require","_config","_interopRequireDefault","_cookies","_createSession","_encryption","getSession","req","cookies","CookieManager","
|
|
1
|
+
{"version":3,"file":"helpers.js","names":["_routing","require","_config","_interopRequireDefault","_cookies","_createSession","_encryption","_helpers","getSession","req","res","hasSetSessionCookie","getHeader","cookies","CookieManager","getSessionCookieFromRedirectedResponse","createSession","encryption","getSessionCookieFromRequest","exports","withSSRSession","handler","context","session","_config$authRoutes$lo","_context$resolvedUrl","loginUrl","config","authRoutes","defaultFronteggRoutes","startsWith","fullUrl","URL","appUrl","resolvedUrl","urlSearchParams","searchParams","set","url","redirect","permanent","destination","toString","props"],"sources":["../../../../packages/nextjs/src/pages/helpers.ts"],"sourcesContent":["import { defaultFronteggRoutes } from '../utils/routing';\nimport type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next';\nimport type { ParsedUrlQuery } from 'querystring';\nimport type { FronteggNextJSSession, RequestType } from '../types';\nimport config from '../config';\nimport CookieManager from '../utils/cookies';\nimport createSession from '../utils/createSession';\nimport encryption from '../utils/encryption';\nimport { hasSetSessionCookie } from '../utils/refreshAccessTokenIfNeeded/helpers';\nimport { NextResponse } from 'next/server';\nimport { ServerResponse } from 'http';\n\nexport const getSession = (req: RequestType, res?: ServerResponse) => {\n if (res && hasSetSessionCookie(res.getHeader('set-cookie'))) {\n const cookies = CookieManager.getSessionCookieFromRedirectedResponse(res);\n return createSession(cookies, encryption);\n }\n const cookies = CookieManager.getSessionCookieFromRequest(req);\n return createSession(cookies, encryption);\n};\n\nexport function withSSRSession<\n P extends { [key: string]: any } = { [key: string]: any },\n Q extends ParsedUrlQuery = ParsedUrlQuery\n>(\n handler: (\n context: GetServerSidePropsContext<Q>,\n session: FronteggNextJSSession\n ) => GetServerSidePropsResult<P> | Promise<GetServerSidePropsResult<P>>\n) {\n return async (context: GetServerSidePropsContext<Q>): Promise<GetServerSidePropsResult<P>> => {\n const session = await getSession(context.req, context.res);\n if (session) {\n return handler(context, session);\n } else {\n let loginUrl = config.authRoutes.loginUrl ?? defaultFronteggRoutes.loginUrl;\n\n if (!loginUrl.startsWith('/')) {\n loginUrl = `/${loginUrl}`;\n }\n\n const fullUrl = new URL(config.appUrl + context.resolvedUrl);\n const urlSearchParams = fullUrl.searchParams;\n urlSearchParams.set('redirectUrl', context.resolvedUrl ?? context.req.url);\n\n return {\n redirect: {\n permanent: false,\n destination: `${loginUrl}?${urlSearchParams.toString()}`,\n },\n props: {},\n } as GetServerSidePropsResult<P>;\n }\n };\n}\n"],"mappings":";;;;;;;;AAAA,IAAAA,QAAA,GAAAC,OAAA;AAIA,IAAAC,OAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,QAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,cAAA,GAAAF,sBAAA,CAAAF,OAAA;AACA,IAAAK,WAAA,GAAAH,sBAAA,CAAAF,OAAA;AACA,IAAAM,QAAA,GAAAN,OAAA;AAIO,MAAMO,UAAU,GAAGA,CAACC,GAAgB,EAAEC,GAAoB,KAAK;EACpE,IAAIA,GAAG,IAAI,IAAAC,4BAAmB,EAACD,GAAG,CAACE,SAAS,CAAC,YAAY,CAAC,CAAC,EAAE;IAC3D,MAAMC,OAAO,GAAGC,gBAAa,CAACC,sCAAsC,CAACL,GAAG,CAAC;IACzE,OAAO,IAAAM,sBAAa,EAACH,OAAO,EAAEI,mBAAU,CAAC;EAC3C;EACA,MAAMJ,OAAO,GAAGC,gBAAa,CAACI,2BAA2B,CAACT,GAAG,CAAC;EAC9D,OAAO,IAAAO,sBAAa,EAACH,OAAO,EAAEI,mBAAU,CAAC;AAC3C,CAAC;AAACE,OAAA,CAAAX,UAAA,GAAAA,UAAA;AAEK,SAASY,cAAcA,CAI5BC,OAGuE,EACvE;EACA,OAAO,MAAOC,OAAqC,IAA2C;IAC5F,MAAMC,OAAO,GAAG,MAAMf,UAAU,CAACc,OAAO,CAACb,GAAG,EAAEa,OAAO,CAACZ,GAAG,CAAC;IAC1D,IAAIa,OAAO,EAAE;MACX,OAAOF,OAAO,CAACC,OAAO,EAAEC,OAAO,CAAC;IAClC,CAAC,MAAM;MAAA,IAAAC,qBAAA,EAAAC,oBAAA;MACL,IAAIC,QAAQ,IAAAF,qBAAA,GAAGG,eAAM,CAACC,UAAU,CAACF,QAAQ,YAAAF,qBAAA,GAAIK,8BAAqB,CAACH,QAAQ;MAE3E,IAAI,CAACA,QAAQ,CAACI,UAAU,CAAC,GAAG,CAAC,EAAE;QAC7BJ,QAAQ,GAAG,IAAIA,QAAQ,EAAE;MAC3B;MAEA,MAAMK,OAAO,GAAG,IAAIC,GAAG,CAACL,eAAM,CAACM,MAAM,GAAGX,OAAO,CAACY,WAAW,CAAC;MAC5D,MAAMC,eAAe,GAAGJ,OAAO,CAACK,YAAY;MAC5CD,eAAe,CAACE,GAAG,CAAC,aAAa,GAAAZ,oBAAA,GAAEH,OAAO,CAACY,WAAW,YAAAT,oBAAA,GAAIH,OAAO,CAACb,GAAG,CAAC6B,GAAG,CAAC;MAE1E,OAAO;QACLC,QAAQ,EAAE;UACRC,SAAS,EAAE,KAAK;UAChBC,WAAW,EAAE,GAAGf,QAAQ,IAAIS,eAAe,CAACO,QAAQ,CAAC,CAAC;QACxD,CAAC;QACDC,KAAK,EAAE,CAAC;MACV,CAAC;IACH;EACF,CAAC;AACH","ignoreList":[]}
|
package/sdkVersion.js
CHANGED
package/sdkVersion.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdkVersion.js","names":["version"],"sources":["../../../packages/nextjs/src/sdkVersion.ts"],"sourcesContent":["export default { version: '9.
|
|
1
|
+
{"version":3,"file":"sdkVersion.js","names":["version"],"sources":["../../../packages/nextjs/src/sdkVersion.ts"],"sourcesContent":["export default { version: '9.1.1-alpha.11727010801' };\n"],"mappings":";;;;;;iCAAe;EAAEA,OAAO,EAAE;AAA0B,CAAC","ignoreList":[]}
|
package/types/index.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export interface FronteggUserTokens {
|
|
|
15
15
|
export interface FronteggNextJSSession extends FronteggUserTokens {
|
|
16
16
|
user: FronteggUserSession;
|
|
17
17
|
}
|
|
18
|
+
export interface FronteggEdgeSession {
|
|
19
|
+
session?: FronteggNextJSSession;
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
}
|
|
18
22
|
export type RequestType = IncomingMessage | Request;
|
|
19
23
|
export interface AccountEnvironment {
|
|
20
24
|
id: string;
|
|
@@ -24,10 +28,6 @@ export interface AccountEnvironment {
|
|
|
24
28
|
export interface CustomClaims {
|
|
25
29
|
accountEnvironments: AccountEnvironment[];
|
|
26
30
|
}
|
|
27
|
-
export interface FronteggUserTokens {
|
|
28
|
-
accessToken: string;
|
|
29
|
-
refreshToken?: string;
|
|
30
|
-
}
|
|
31
31
|
export interface AllUserData {
|
|
32
32
|
user?: ILoginResponse | null;
|
|
33
33
|
tenants?: ITenantsResponse[] | null;
|
|
@@ -52,9 +52,6 @@ export interface FronteggUserSession {
|
|
|
52
52
|
aud: string;
|
|
53
53
|
iss: string;
|
|
54
54
|
}
|
|
55
|
-
export interface FronteggNextJSSession extends FronteggUserTokens {
|
|
56
|
-
user: FronteggUserSession;
|
|
57
|
-
}
|
|
58
55
|
export interface FronteggProviderOptions extends Omit<FronteggAppOptions, 'contextOptions'>, AllUserData {
|
|
59
56
|
envAppUrl: string;
|
|
60
57
|
envBaseUrl: string;
|
package/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../packages/nextjs/src/types/index.ts"],"sourcesContent":["import type { FronteggAppOptions } from '@frontegg/types';\nimport type { ILoginResponse, ITenantsResponse } from '@frontegg/rest-api';\nimport type { IncomingMessage } from 'http';\nimport type { ReactNode } from 'react';\nimport type { AppRouterInstance } from 'next/dist/shared/lib/app-router-context';\nimport type { NextRouter } from 'next/router';\n\nexport interface EncryptionUtils {\n unsealTokens(data: string): Promise<FronteggUserTokens | undefined>;\n\n sealTokens(tokens: FronteggUserTokens, ttl: number): Promise<string>;\n}\n\nexport interface FronteggUserTokens {\n accessToken: string;\n refreshToken?: string;\n}\n\nexport interface FronteggNextJSSession extends FronteggUserTokens {\n user: FronteggUserSession;\n}\n\nexport type RequestType = IncomingMessage | Request;\n\nexport interface AccountEnvironment {\n id: string;\n createdAt: string;\n environment: 'production' | 'development';\n}\n\nexport interface CustomClaims {\n accountEnvironments: AccountEnvironment[];\n}\n\nexport interface
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../packages/nextjs/src/types/index.ts"],"sourcesContent":["import type { FronteggAppOptions } from '@frontegg/types';\nimport type { ILoginResponse, ITenantsResponse } from '@frontegg/rest-api';\nimport type { IncomingMessage } from 'http';\nimport type { ReactNode } from 'react';\nimport type { AppRouterInstance } from 'next/dist/shared/lib/app-router-context';\nimport type { NextRouter } from 'next/router';\n\nexport interface EncryptionUtils {\n unsealTokens(data: string): Promise<FronteggUserTokens | undefined>;\n\n sealTokens(tokens: FronteggUserTokens, ttl: number): Promise<string>;\n}\n\nexport interface FronteggUserTokens {\n accessToken: string;\n refreshToken?: string;\n}\n\nexport interface FronteggNextJSSession extends FronteggUserTokens {\n user: FronteggUserSession;\n}\n\nexport interface FronteggEdgeSession {\n session?: FronteggNextJSSession;\n headers?: Record<string, string>;\n}\n\nexport type RequestType = IncomingMessage | Request;\n\nexport interface AccountEnvironment {\n id: string;\n createdAt: string;\n environment: 'production' | 'development';\n}\n\nexport interface CustomClaims {\n accountEnvironments: AccountEnvironment[];\n}\n\nexport interface AllUserData {\n user?: ILoginResponse | null;\n tenants?: ITenantsResponse[] | null;\n activeTenant?: ITenantsResponse;\n session?: FronteggNextJSSession | null;\n}\n\nexport interface FronteggUserSession {\n sub: string;\n name: string;\n email: string;\n email_verified: boolean;\n metadata: any;\n roles: string[];\n permissions: string[];\n tenantId: string;\n tenantIds: string[];\n profilePictureUrl: string;\n type: string; // \"userToken\"\n customClaims: CustomClaims;\n iat: number;\n exp: number;\n aud: string;\n iss: string;\n}\n\nexport interface FronteggProviderOptions extends Omit<FronteggAppOptions, 'contextOptions'>, AllUserData {\n envAppUrl: string;\n envBaseUrl: string;\n envClientId: string;\n shouldRequestAuthorize?: boolean;\n isSSG?: boolean;\n envAppId?: string;\n secureJwtEnabled?: boolean;\n contextOptions?: Omit<FronteggAppOptions['contextOptions'], 'baseUrl'>;\n}\n\nexport interface FronteggProviderProps extends FronteggProviderOptions {\n children?: ReactNode;\n router: AppRouterInstance | NextRouter;\n appName?: string;\n}\n\ntype CustomLoginOptionsWithParamKeyType = {\n /**\n *The param key from your tenant login url, for 'frontegg.com?organization=[tenant]' would be 'organization'\n */\n paramKey: string;\n subDomainIndex?: never;\n};\n\ntype CustomLoginOptionsWithSubDomainType = {\n /**\n *The index of sub domain from your tenant login url, for 'https://[tenant].frontegg.com' would be 0\n */\n subDomainIndex: number;\n paramKey?: never;\n};\n\nexport type CustomLoginOptionsType = CustomLoginOptionsWithParamKeyType | CustomLoginOptionsWithSubDomainType;\n\ntype PagesDirectoryProviderProps = {\n customLoginOptions?: CustomLoginOptionsType;\n};\n\nexport type ClientFronteggProviderProps = Omit<FronteggProviderProps, 'router'> & PagesDirectoryProviderProps;\n\ndeclare module 'iron-session' {\n interface IronSessionData {\n accessToken: FronteggNextJSSession['accessToken'];\n user: FronteggNextJSSession['user'];\n }\n}\n\ndeclare global {\n var customLoginAppUrl: string | undefined;\n\n interface ProcessEnv {\n FRONTEGG_BASE_URL: string;\n PORT?: string;\n PWD: string;\n }\n}\n"],"mappings":"","ignoreList":[]}
|
package/utils/cookies/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ declare class CookieManager {
|
|
|
28
28
|
* @param {RequestType} request - Incoming HTTP Request
|
|
29
29
|
*/
|
|
30
30
|
getSessionCookieFromRequest(request?: RequestType): string | undefined;
|
|
31
|
+
getRefreshCookieFromRequestEdge(request?: RequestType): string | undefined;
|
|
31
32
|
/**
|
|
32
33
|
* Loop over cookie headers, extract, parse cookies and merged divided cookies from redirected http response,
|
|
33
34
|
* @return full session cookie headers if exists, else return undefined
|
|
@@ -38,11 +39,15 @@ declare class CookieManager {
|
|
|
38
39
|
private createEmptySingleCookie;
|
|
39
40
|
createEmptyCookies: (isSecured: boolean, cookieDomain: string, _cookiesToRemove: string[], removeRefresh?: boolean) => string[];
|
|
40
41
|
private getCookiesToRemove;
|
|
42
|
+
/**
|
|
43
|
+
* Take a list of cookieNames and return the headers to remove the cookies from the client side
|
|
44
|
+
* @param {RemoveCookiesOptions} setCookieValue
|
|
45
|
+
*/
|
|
46
|
+
getRequestCookiesHeaderToRemove({ cookieNames, isSecured, cookieDomain, req, }: Omit<RemoveCookiesOptions, 'res'>): string[];
|
|
41
47
|
/**
|
|
42
48
|
* Take a list of cookieNames and modify request/response headers
|
|
43
49
|
* to proxy the cookies from Next.js to Frontegg Services and vice-versa
|
|
44
|
-
* @param {
|
|
45
|
-
* @param {boolean} isSecured - if the running application behind SSL
|
|
50
|
+
* @param {RemoveCookiesOptions} setCookieValue
|
|
46
51
|
*/
|
|
47
52
|
removeCookies({ cookieNames, isSecured, cookieDomain, res, req }: RemoveCookiesOptions): void;
|
|
48
53
|
/**
|
package/utils/cookies/index.js
CHANGED
|
@@ -243,6 +243,30 @@ class CookieManager {
|
|
|
243
243
|
logger.info(`Session cookie found, (count: ${sessionCookies.length})`);
|
|
244
244
|
return sessionCookies;
|
|
245
245
|
}
|
|
246
|
+
getRefreshCookieFromRequestEdge(request) {
|
|
247
|
+
const logger = _fronteggLogger.default.child({
|
|
248
|
+
tag: 'CookieManager.getRefreshCookieFromRequest'
|
|
249
|
+
});
|
|
250
|
+
logger.info('Going to extract refresh cookie header from request');
|
|
251
|
+
if (!request) {
|
|
252
|
+
logger.info(`'request' argument is null, Cookie header not found`);
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
logger.debug('Getting cookie header');
|
|
256
|
+
const cookieStr = (0, _helpers.getCookieHeader)(request);
|
|
257
|
+
logger.debug('Parsing cookie header string');
|
|
258
|
+
const cookies = _serializer.default.parse(cookieStr);
|
|
259
|
+
const refreshTokenKey = this.refreshTokenKey;
|
|
260
|
+
const refreshCookie = Object.keys(cookies).find(cookie => {
|
|
261
|
+
return cookie.replace(/-/g, '') === refreshTokenKey;
|
|
262
|
+
});
|
|
263
|
+
if (!refreshCookie) {
|
|
264
|
+
logger.info('Refresh cookie NOT found');
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
logger.info(`Refresh cookie found for key: ${refreshTokenKey}`);
|
|
268
|
+
return cookies[refreshCookie];
|
|
269
|
+
}
|
|
246
270
|
|
|
247
271
|
/**
|
|
248
272
|
* Loop over cookie headers, extract, parse cookies and merged divided cookies from redirected http response,
|
|
@@ -302,11 +326,29 @@ class CookieManager {
|
|
|
302
326
|
logger.info(`Concatenate session cookies chunks`);
|
|
303
327
|
return cookieChunks.map(c => c.value).join('');
|
|
304
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* Take a list of cookieNames and return the headers to remove the cookies from the client side
|
|
331
|
+
* @param {RemoveCookiesOptions} setCookieValue
|
|
332
|
+
*/
|
|
333
|
+
getRequestCookiesHeaderToRemove({
|
|
334
|
+
cookieNames,
|
|
335
|
+
isSecured,
|
|
336
|
+
cookieDomain,
|
|
337
|
+
req
|
|
338
|
+
}) {
|
|
339
|
+
const logger = _fronteggLogger.default.child({
|
|
340
|
+
tag: 'CookieManager.getSetCookiesHeaderToRemove'
|
|
341
|
+
});
|
|
342
|
+
logger.debug('Setting empty cookie headers remove cookies from client side');
|
|
343
|
+
const cookiesToRemove = this.getCookiesToRemove(req);
|
|
344
|
+
const cookieValue = this.createEmptyCookies(isSecured, cookieDomain, cookieNames != null ? cookieNames : cookiesToRemove);
|
|
345
|
+
return [...cookieValue];
|
|
346
|
+
}
|
|
347
|
+
|
|
305
348
|
/**
|
|
306
349
|
* Take a list of cookieNames and modify request/response headers
|
|
307
350
|
* to proxy the cookies from Next.js to Frontegg Services and vice-versa
|
|
308
|
-
* @param {
|
|
309
|
-
* @param {boolean} isSecured - if the running application behind SSL
|
|
351
|
+
* @param {RemoveCookiesOptions} setCookieValue
|
|
310
352
|
*/
|
|
311
353
|
removeCookies({
|
|
312
354
|
cookieNames,
|
|
@@ -319,9 +361,12 @@ class CookieManager {
|
|
|
319
361
|
const logger = _fronteggLogger.default.child({
|
|
320
362
|
tag: 'CookieManager.removeCookies'
|
|
321
363
|
});
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
364
|
+
const cookieValue = this.getRequestCookiesHeaderToRemove({
|
|
365
|
+
cookieNames,
|
|
366
|
+
isSecured,
|
|
367
|
+
cookieDomain,
|
|
368
|
+
req
|
|
369
|
+
});
|
|
325
370
|
let existingSetCookie = (_ref = res.getHeader('set-cookie')) != null ? _ref : [];
|
|
326
371
|
if (existingSetCookie != null && typeof existingSetCookie === 'object' && !Array.isArray(existingSetCookie)) {
|
|
327
372
|
existingSetCookie = Object.values(existingSetCookie);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_serializer","_interopRequireDefault","require","_config","_constants","_helpers","_fronteggLogger","CookieManager","constructor","getCookieName","cookieNumber","cookieName","config","getIndexedCookieName","createEmptySingleCookie","isSecured","cookieDomain","create","value","expires","Date","secure","domain","silent","createEmptyCookies","_cookiesToRemove","removeRefresh","allEmptyCookies","refreshTokenVariants","getRefreshTokenCookieNameVariants","cookiesToRemove","forEach","name","push","getCookiesToRemove","request","logger","fronteggLogger","child","tag","info","cookieStr","getCookieHeader","cookies","cookieSerializer","parse","cookieToRemove","length","e","error","modifySetCookie","setCookieValue","cookieRegexSplitter","cookieHeader","match","exec","cookieString","trim","startsWith","substring","map","c","cookie","split","debug","filter","property","clientId","replace","rewriteCookieByAppId","appId","toLowerCase","baseUrlHost","join","refreshTokenKey","getEmptyCookiesBeforeCreatingNew","req","newCookies","newCookieNames","indexOf","options","_options$cookieName","_options$httpOnly","_options$domain","_options$path","level","undefined","cookieValue","serializeOptions","httpOnly","path","priority","sameSite","cookieSameSite","serializedCookie","serialize","COOKIE_MAX_LENGTH","splitValueToChunks","removedCookiesValue","parseCookieHeader","getSessionCookieFromRequest","i","sessionCookies","sessionCookieChunk","getSessionCookieFromRedirectedResponse","response","getSetCookieHeader","parseCookieFromArray","cookieChunks","includes","sort","a","b","firstCookieNumber","parseInt","slice","secondCookieNumber","removeCookies","cookieNames","res","_ref","existingSetCookie","getHeader","Array","isArray","Object","values","setCookieHeaders","setHeader","_default","exports","default"],"sources":["../../../../../packages/nextjs/src/utils/cookies/index.ts"],"sourcesContent":["import cookieSerializer from './serializer';\nimport type { RequestCookie } from 'next/dist/server/web/spec-extension/cookies';\nimport config from '../../config';\nimport { CookieSerializeOptions, CreateCookieOptions, RemoveCookiesOptions, RequestType, ResponseType } from './types';\nimport { COOKIE_MAX_LENGTH } from './constants';\n\nimport {\n getCookieHeader,\n getIndexedCookieName,\n getRefreshTokenCookieNameVariants,\n getSetCookieHeader,\n splitValueToChunks,\n} from './helpers';\nimport fronteggLogger from '../fronteggLogger';\n\nclass CookieManager {\n getCookieName = (cookieNumber?: number, cookieName = config.cookieName) =>\n cookieNumber ? getIndexedCookieName(cookieNumber, cookieName) : cookieName;\n\n get refreshTokenKey(): string {\n if (config.rewriteCookieByAppId && config.appId) {\n return `fe_refresh_${config.appId.replace(/-/g, '')}`;\n } else {\n return `fe_refresh_${config.clientId.replace(/-/g, '')}`;\n }\n }\n\n /**\n * This function creates list of empty cookies that already exists in the request.\n * This is used for removing existing cookies before creating new ones.\n * @param {CreateCookieOptions} options - Create cookie options\n */\n getEmptyCookiesBeforeCreatingNew(\n { req, value, secure, domain }: CreateCookieOptions,\n newCookies: string[]\n ): string[] {\n if (!req || !value) {\n return [];\n }\n const newCookieNames = newCookies.map((c) => c.split('=')[0]);\n const cookiesToRemove = this.getCookiesToRemove(req).filter((cookie) => newCookieNames.indexOf(cookie) === -1);\n if (cookiesToRemove.length === 0) {\n return [];\n }\n\n return this.createEmptyCookies(secure, domain ?? config.cookieDomain, cookiesToRemove, false);\n }\n\n /**\n * Validate and create new cookie headers.\n * The default value of `cookieName` is {@link config.cookieName}\n * @param {CreateCookieOptions} options - Create cookie options\n */\n create(options: CreateCookieOptions): string[] {\n const logger = fronteggLogger.child({ tag: 'CookieManager.create', level: options.silent ? 'error' : undefined });\n const cookieName = options.cookieName ?? this.getCookieName();\n const cookieValue = options.value;\n logger.info(`Creating new cookie for '${cookieName}'`);\n\n const serializeOptions: CookieSerializeOptions = {\n expires: options.expires,\n httpOnly: options.httpOnly ?? true,\n domain: options.domain ?? config.cookieDomain,\n path: options.path ?? '/',\n priority: 'high',\n };\n\n if (options.secure) {\n logger.debug(`Set cookie '${cookieName}' as secure`);\n serializeOptions.secure = options.secure;\n serializeOptions.sameSite = config.cookieSameSite;\n }\n\n const serializedCookie = cookieSerializer.serialize(cookieName, cookieValue, serializeOptions);\n\n let newCookies: string[] = [];\n if (serializedCookie.length <= COOKIE_MAX_LENGTH) {\n logger.info(`Successfully create a cookie header, '${cookieName}'`);\n newCookies = [serializedCookie];\n } else {\n logger.debug('Going to split cookie into chunks');\n /** Create chunked cookie headers and store value as array of headers */\n const cookies = splitValueToChunks(cookieName, cookieValue, serializeOptions);\n logger.info(`Successfully create chunked cookie headers, '${cookieName}' (count: ${cookies.length})`);\n newCookies = cookies;\n }\n\n const removedCookiesValue = this.getEmptyCookiesBeforeCreatingNew(options, newCookies);\n return [...removedCookiesValue, ...newCookies];\n }\n\n /**\n * Receive incoming http request, and extract the cookie header.\n * @return cookie as string if exists, else empty string\n *\n * @param {RequestType} request - Incoming HTTP Request\n */\n parseCookieHeader(request: RequestType): Record<string, string> {\n const logger = fronteggLogger.child({ tag: 'CookieManager.parseCookieHeader' });\n\n logger.info('Going to extract all cookies header from request');\n const cookieHeader = getCookieHeader(request);\n logger.info('Parsing cookie header to map');\n return cookieSerializer.parse(cookieHeader);\n }\n\n /**\n * Loop over cookie headers, extract, parse cookies and merged divided cookies from incoming http request,\n * @return full session cookie headers if exists, else return undefined\n * @param {RequestType} request - Incoming HTTP Request\n */\n getSessionCookieFromRequest(request?: RequestType): string | undefined {\n const logger = fronteggLogger.child({ tag: 'CookieManager.getSessionCookieFromRequest' });\n logger.info('Going to extract session cookies header from request');\n\n if (!request) {\n logger.info(`'request' argument is null, Cookie header not found`);\n return undefined;\n }\n\n logger.debug('Getting cookie header');\n const cookieStr = getCookieHeader(request);\n\n logger.debug('Parsing cookie header string');\n const cookies = cookieSerializer.parse(cookieStr);\n\n logger.debug('Loop over session cookie headers');\n let i = 1;\n let sessionCookies = '';\n let sessionCookieChunk: string | undefined = cookies[this.getCookieName()];\n if (sessionCookieChunk === undefined) {\n do {\n sessionCookieChunk = cookies[getIndexedCookieName(i++)];\n if (sessionCookieChunk) {\n sessionCookies += sessionCookieChunk;\n }\n } while (sessionCookieChunk);\n } else {\n sessionCookies = sessionCookieChunk;\n }\n\n if (sessionCookies.length === 0) {\n logger.info('Session cookie NOT found');\n return undefined;\n }\n\n logger.info(`Session cookie found, (count: ${sessionCookies.length})`);\n return sessionCookies;\n }\n\n /**\n * Loop over cookie headers, extract, parse cookies and merged divided cookies from redirected http response,\n * @return full session cookie headers if exists, else return undefined\n * @param {ResponseType} response - Outgoing HTTP response\n */\n getSessionCookieFromRedirectedResponse(response?: ResponseType): string | undefined {\n const logger = fronteggLogger.child({ tag: 'CookieManager.getSessionCookieFromRedirectedResponse' });\n logger.info('Going to extract session from set-cookie header from response');\n\n if (!response) {\n logger.info(`'response' argument is null, Cookie header not found`);\n return undefined;\n }\n\n logger.debug('Getting set-cookie header');\n const cookieStr = getSetCookieHeader(response);\n\n logger.debug('Parsing set-cookie header string');\n const cookies = cookieSerializer.parse(cookieStr);\n\n logger.debug('Loop over session set-cookie header');\n let i = 1;\n let sessionCookies = '';\n let sessionCookieChunk: string | undefined = cookies[this.getCookieName()];\n if (sessionCookieChunk === undefined) {\n do {\n sessionCookieChunk = cookies[getIndexedCookieName(i++)];\n if (sessionCookieChunk) {\n sessionCookies += sessionCookieChunk;\n }\n } while (sessionCookieChunk);\n } else {\n sessionCookies = sessionCookieChunk;\n }\n\n if (sessionCookies.length === 0) {\n logger.info('Session set-cookie NOT found');\n return undefined;\n }\n\n logger.info(`Session set-cookie found, (count: ${sessionCookies.length})`);\n return sessionCookies;\n }\n\n parseCookieFromArray(cookies: RequestCookie[]): string | undefined {\n const logger = fronteggLogger.child({ tag: 'CookieManager.parseCookieFromArray' });\n const cookieChunks = cookies.filter((c) => c.name.includes(this.getCookieName()));\n logger.info('Parsing session cookie from RequestCookie for Next.JS 13+');\n\n if (!cookieChunks || cookieChunks.length === 0) {\n logger.info(`No session cookies found`);\n return undefined;\n }\n logger.debug(`Found ${cookieChunks.length} chunks`);\n cookieChunks.sort((a, b) => {\n const firstCookieNumber = parseInt(a.name.slice(-1));\n const secondCookieNumber = parseInt(b.name.slice(-1));\n return firstCookieNumber > secondCookieNumber ? 1 : -1;\n });\n\n logger.info(`Concatenate session cookies chunks`);\n return cookieChunks.map((c) => c.value).join('');\n }\n\n private createEmptySingleCookie = (cookieName: string, isSecured: boolean, cookieDomain: string) => {\n return this.create({\n cookieName,\n value: '',\n expires: new Date(),\n secure: isSecured,\n domain: cookieDomain,\n silent: true,\n });\n };\n\n createEmptyCookies = (\n isSecured: boolean,\n cookieDomain: string,\n _cookiesToRemove: string[],\n removeRefresh = true\n ): string[] => {\n const allEmptyCookies: string[] = [];\n\n const refreshTokenVariants = getRefreshTokenCookieNameVariants();\n const cookiesToRemove = [..._cookiesToRemove, ...(removeRefresh ? refreshTokenVariants : [])];\n\n cookiesToRemove.forEach((name: string) => {\n allEmptyCookies.push(...this.createEmptySingleCookie(name, isSecured, cookieDomain));\n });\n\n return allEmptyCookies;\n };\n\n private getCookiesToRemove = (request?: RequestType): string[] => {\n const logger = fronteggLogger.child({ tag: 'getCookiesToRemove' });\n if (!request) {\n return [];\n }\n try {\n logger.info('extract cookie from request headers');\n const cookieStr = getCookieHeader(request);\n const cookies = cookieStr && cookieSerializer.parse(cookieStr);\n if (!cookies) {\n return [];\n }\n let cookieNumber = 1;\n const cookieToRemove = [];\n if (cookies[this.getCookieName()]) {\n cookieToRemove.push(this.getCookieName());\n }\n while (cookies[this.getCookieName(cookieNumber)]) {\n cookieToRemove.push(this.getCookieName(cookieNumber));\n cookieNumber++;\n }\n logger.info(`number of cookies to remove: ${cookieToRemove.length}`);\n return cookieToRemove;\n } catch (e) {\n logger.error(e);\n return [];\n }\n };\n\n /**\n * Take a list of cookieNames and modify request/response headers\n * to proxy the cookies from Next.js to Frontegg Services and vice-versa\n * @param {string[]} setCookieValue - list of cookies to modify\n * @param {boolean} isSecured - if the running application behind SSL\n */\n removeCookies({ cookieNames, isSecured, cookieDomain, res, req }: RemoveCookiesOptions): void {\n const logger = fronteggLogger.child({ tag: 'CookieManager.removeCookies' });\n logger.debug('Setting empty cookie headers remove cookies from client side');\n const cookiesToRemove = this.getCookiesToRemove(req);\n const cookieValue = this.createEmptyCookies(isSecured, cookieDomain, cookieNames ?? cookiesToRemove);\n let existingSetCookie = (res.getHeader('set-cookie') as string[] | string) ?? [];\n\n if (existingSetCookie != null && typeof existingSetCookie === 'object' && !Array.isArray(existingSetCookie)) {\n existingSetCookie = Object.values(existingSetCookie);\n }\n if (typeof existingSetCookie === 'string') {\n existingSetCookie = [existingSetCookie];\n }\n const setCookieHeaders = [...existingSetCookie, ...cookieValue];\n logger.debug(`removing headers (count: ${setCookieHeaders.length})`);\n res.setHeader('set-cookie', setCookieHeaders);\n }\n\n /**\n * Take a list of cookie headers and modify the Domain / Secure / SameSite\n * to proxy the cookies to Frontegg Services and vice-versa\n * @param {string[]} setCookieValue - list of cookies to modify\n * @param {boolean} isSecured - if the running application behind SSL\n */\n modifySetCookie = (setCookieValue: string[] | undefined, isSecured: boolean): string[] | undefined => {\n const logger = fronteggLogger.child({ tag: 'CookieManager.modifySetCookie' });\n if (!setCookieValue || setCookieValue.length === 0) {\n logger.info(`No headers to modify`);\n return setCookieValue;\n }\n\n // noinspection SuspiciousTypeOfGuard\n if (typeof setCookieValue === 'string') {\n const cookieRegexSplitter = /(.*?;.*?(?:Expires=[^;]+;.*?)?(?=,\\s*\\S+=|$))/g;\n const cookies = [];\n const cookieHeader = `${setCookieValue}`;\n let match;\n while ((match = cookieRegexSplitter.exec(cookieHeader)) !== null) {\n let cookieString = match[1].trim();\n if (cookieString.startsWith(',')) {\n cookies.push(cookieString.substring(1).trim());\n } else {\n cookies.push(cookieString);\n }\n }\n setCookieValue = cookies;\n }\n\n logger.info(`modifying cookie headers (count: ${setCookieValue.length})`);\n return setCookieValue.map((c) => {\n let cookie = c.split('; ');\n\n logger.debug(`modifying cookie ${cookie[0]}, isSecured: ${isSecured}`);\n if (!isSecured) {\n cookie = cookie.filter((property) => property !== 'Secure' && property !== 'SameSite=None');\n }\n\n return (\n cookie\n .map((property) => {\n if (property.trim().startsWith(`fe_refresh_${config.clientId.replace('-', '')}`)) {\n if (config.rewriteCookieByAppId && config.appId) {\n return property.replace(\n `fe_refresh_${config.clientId.replace('-', '')}`,\n `fe_refresh_${config.appId.replace('-', '')}`\n );\n } else {\n return property;\n }\n } else if (property.toLowerCase() === `domain=${config.baseUrlHost}`) {\n return `Domain=${config.cookieDomain}`;\n } else {\n return property;\n }\n })\n .join(';') + ';'\n );\n });\n };\n}\n\nexport default new CookieManager();\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_serializer","_interopRequireDefault","require","_config","_constants","_helpers","_fronteggLogger","CookieManager","constructor","getCookieName","cookieNumber","cookieName","config","getIndexedCookieName","createEmptySingleCookie","isSecured","cookieDomain","create","value","expires","Date","secure","domain","silent","createEmptyCookies","_cookiesToRemove","removeRefresh","allEmptyCookies","refreshTokenVariants","getRefreshTokenCookieNameVariants","cookiesToRemove","forEach","name","push","getCookiesToRemove","request","logger","fronteggLogger","child","tag","info","cookieStr","getCookieHeader","cookies","cookieSerializer","parse","cookieToRemove","length","e","error","modifySetCookie","setCookieValue","cookieRegexSplitter","cookieHeader","match","exec","cookieString","trim","startsWith","substring","map","c","cookie","split","debug","filter","property","clientId","replace","rewriteCookieByAppId","appId","toLowerCase","baseUrlHost","join","refreshTokenKey","getEmptyCookiesBeforeCreatingNew","req","newCookies","newCookieNames","indexOf","options","_options$cookieName","_options$httpOnly","_options$domain","_options$path","level","undefined","cookieValue","serializeOptions","httpOnly","path","priority","sameSite","cookieSameSite","serializedCookie","serialize","COOKIE_MAX_LENGTH","splitValueToChunks","removedCookiesValue","parseCookieHeader","getSessionCookieFromRequest","i","sessionCookies","sessionCookieChunk","getRefreshCookieFromRequestEdge","refreshCookie","Object","keys","find","getSessionCookieFromRedirectedResponse","response","getSetCookieHeader","parseCookieFromArray","cookieChunks","includes","sort","a","b","firstCookieNumber","parseInt","slice","secondCookieNumber","getRequestCookiesHeaderToRemove","cookieNames","removeCookies","res","_ref","existingSetCookie","getHeader","Array","isArray","values","setCookieHeaders","setHeader","_default","exports","default"],"sources":["../../../../../packages/nextjs/src/utils/cookies/index.ts"],"sourcesContent":["import cookieSerializer from './serializer';\nimport type { RequestCookie } from 'next/dist/server/web/spec-extension/cookies';\nimport config from '../../config';\nimport { CookieSerializeOptions, CreateCookieOptions, RemoveCookiesOptions, RequestType, ResponseType } from './types';\nimport { COOKIE_MAX_LENGTH } from './constants';\n\nimport {\n getCookieHeader,\n getIndexedCookieName,\n getRefreshTokenCookieNameVariants,\n getSetCookieHeader,\n splitValueToChunks,\n} from './helpers';\nimport fronteggLogger from '../fronteggLogger';\nimport { NextApiRequest } from 'next/dist/shared/lib/utils';\n\nclass CookieManager {\n getCookieName = (cookieNumber?: number, cookieName = config.cookieName) =>\n cookieNumber ? getIndexedCookieName(cookieNumber, cookieName) : cookieName;\n\n get refreshTokenKey(): string {\n if (config.rewriteCookieByAppId && config.appId) {\n return `fe_refresh_${config.appId.replace(/-/g, '')}`;\n } else {\n return `fe_refresh_${config.clientId.replace(/-/g, '')}`;\n }\n }\n\n /**\n * This function creates list of empty cookies that already exists in the request.\n * This is used for removing existing cookies before creating new ones.\n * @param {CreateCookieOptions} options - Create cookie options\n */\n getEmptyCookiesBeforeCreatingNew(\n { req, value, secure, domain }: CreateCookieOptions,\n newCookies: string[]\n ): string[] {\n if (!req || !value) {\n return [];\n }\n const newCookieNames = newCookies.map((c) => c.split('=')[0]);\n const cookiesToRemove = this.getCookiesToRemove(req).filter((cookie) => newCookieNames.indexOf(cookie) === -1);\n if (cookiesToRemove.length === 0) {\n return [];\n }\n\n return this.createEmptyCookies(secure, domain ?? config.cookieDomain, cookiesToRemove, false);\n }\n\n /**\n * Validate and create new cookie headers.\n * The default value of `cookieName` is {@link config.cookieName}\n * @param {CreateCookieOptions} options - Create cookie options\n */\n create(options: CreateCookieOptions): string[] {\n const logger = fronteggLogger.child({ tag: 'CookieManager.create', level: options.silent ? 'error' : undefined });\n const cookieName = options.cookieName ?? this.getCookieName();\n const cookieValue = options.value;\n logger.info(`Creating new cookie for '${cookieName}'`);\n\n const serializeOptions: CookieSerializeOptions = {\n expires: options.expires,\n httpOnly: options.httpOnly ?? true,\n domain: options.domain ?? config.cookieDomain,\n path: options.path ?? '/',\n priority: 'high',\n };\n\n if (options.secure) {\n logger.debug(`Set cookie '${cookieName}' as secure`);\n serializeOptions.secure = options.secure;\n serializeOptions.sameSite = config.cookieSameSite;\n }\n\n const serializedCookie = cookieSerializer.serialize(cookieName, cookieValue, serializeOptions);\n\n let newCookies: string[] = [];\n if (serializedCookie.length <= COOKIE_MAX_LENGTH) {\n logger.info(`Successfully create a cookie header, '${cookieName}'`);\n newCookies = [serializedCookie];\n } else {\n logger.debug('Going to split cookie into chunks');\n /** Create chunked cookie headers and store value as array of headers */\n const cookies = splitValueToChunks(cookieName, cookieValue, serializeOptions);\n logger.info(`Successfully create chunked cookie headers, '${cookieName}' (count: ${cookies.length})`);\n newCookies = cookies;\n }\n\n const removedCookiesValue = this.getEmptyCookiesBeforeCreatingNew(options, newCookies);\n return [...removedCookiesValue, ...newCookies];\n }\n\n /**\n * Receive incoming http request, and extract the cookie header.\n * @return cookie as string if exists, else empty string\n *\n * @param {RequestType} request - Incoming HTTP Request\n */\n parseCookieHeader(request: RequestType): Record<string, string> {\n const logger = fronteggLogger.child({ tag: 'CookieManager.parseCookieHeader' });\n\n logger.info('Going to extract all cookies header from request');\n const cookieHeader = getCookieHeader(request);\n logger.info('Parsing cookie header to map');\n return cookieSerializer.parse(cookieHeader);\n }\n\n /**\n * Loop over cookie headers, extract, parse cookies and merged divided cookies from incoming http request,\n * @return full session cookie headers if exists, else return undefined\n * @param {RequestType} request - Incoming HTTP Request\n */\n getSessionCookieFromRequest(request?: RequestType): string | undefined {\n const logger = fronteggLogger.child({ tag: 'CookieManager.getSessionCookieFromRequest' });\n logger.info('Going to extract session cookies header from request');\n\n if (!request) {\n logger.info(`'request' argument is null, Cookie header not found`);\n return undefined;\n }\n\n logger.debug('Getting cookie header');\n const cookieStr = getCookieHeader(request);\n\n logger.debug('Parsing cookie header string');\n const cookies = cookieSerializer.parse(cookieStr);\n\n logger.debug('Loop over session cookie headers');\n let i = 1;\n let sessionCookies = '';\n let sessionCookieChunk: string | undefined = cookies[this.getCookieName()];\n if (sessionCookieChunk === undefined) {\n do {\n sessionCookieChunk = cookies[getIndexedCookieName(i++)];\n if (sessionCookieChunk) {\n sessionCookies += sessionCookieChunk;\n }\n } while (sessionCookieChunk);\n } else {\n sessionCookies = sessionCookieChunk;\n }\n\n if (sessionCookies.length === 0) {\n logger.info('Session cookie NOT found');\n return undefined;\n }\n\n logger.info(`Session cookie found, (count: ${sessionCookies.length})`);\n return sessionCookies;\n }\n\n getRefreshCookieFromRequestEdge(request?: RequestType): string | undefined {\n const logger = fronteggLogger.child({ tag: 'CookieManager.getRefreshCookieFromRequest' });\n logger.info('Going to extract refresh cookie header from request');\n\n if (!request) {\n logger.info(`'request' argument is null, Cookie header not found`);\n return undefined;\n }\n\n logger.debug('Getting cookie header');\n const cookieStr = getCookieHeader(request);\n\n logger.debug('Parsing cookie header string');\n const cookies = cookieSerializer.parse(cookieStr);\n\n const refreshTokenKey = this.refreshTokenKey;\n const refreshCookie = Object.keys(cookies).find((cookie) => {\n return cookie.replace(/-/g, '') === refreshTokenKey;\n });\n\n if (!refreshCookie) {\n logger.info('Refresh cookie NOT found');\n return undefined;\n }\n\n logger.info(`Refresh cookie found for key: ${refreshTokenKey}`);\n return cookies[refreshCookie];\n }\n\n /**\n * Loop over cookie headers, extract, parse cookies and merged divided cookies from redirected http response,\n * @return full session cookie headers if exists, else return undefined\n * @param {ResponseType} response - Outgoing HTTP response\n */\n getSessionCookieFromRedirectedResponse(response?: ResponseType): string | undefined {\n const logger = fronteggLogger.child({ tag: 'CookieManager.getSessionCookieFromRedirectedResponse' });\n logger.info('Going to extract session from set-cookie header from response');\n\n if (!response) {\n logger.info(`'response' argument is null, Cookie header not found`);\n return undefined;\n }\n\n logger.debug('Getting set-cookie header');\n const cookieStr = getSetCookieHeader(response);\n\n logger.debug('Parsing set-cookie header string');\n const cookies = cookieSerializer.parse(cookieStr);\n\n logger.debug('Loop over session set-cookie header');\n let i = 1;\n let sessionCookies = '';\n let sessionCookieChunk: string | undefined = cookies[this.getCookieName()];\n if (sessionCookieChunk === undefined) {\n do {\n sessionCookieChunk = cookies[getIndexedCookieName(i++)];\n if (sessionCookieChunk) {\n sessionCookies += sessionCookieChunk;\n }\n } while (sessionCookieChunk);\n } else {\n sessionCookies = sessionCookieChunk;\n }\n\n if (sessionCookies.length === 0) {\n logger.info('Session set-cookie NOT found');\n return undefined;\n }\n\n logger.info(`Session set-cookie found, (count: ${sessionCookies.length})`);\n return sessionCookies;\n }\n\n parseCookieFromArray(cookies: RequestCookie[]): string | undefined {\n const logger = fronteggLogger.child({ tag: 'CookieManager.parseCookieFromArray' });\n const cookieChunks = cookies.filter((c) => c.name.includes(this.getCookieName()));\n logger.info('Parsing session cookie from RequestCookie for Next.JS 13+');\n\n if (!cookieChunks || cookieChunks.length === 0) {\n logger.info(`No session cookies found`);\n return undefined;\n }\n logger.debug(`Found ${cookieChunks.length} chunks`);\n cookieChunks.sort((a, b) => {\n const firstCookieNumber = parseInt(a.name.slice(-1));\n const secondCookieNumber = parseInt(b.name.slice(-1));\n return firstCookieNumber > secondCookieNumber ? 1 : -1;\n });\n\n logger.info(`Concatenate session cookies chunks`);\n return cookieChunks.map((c) => c.value).join('');\n }\n\n private createEmptySingleCookie = (cookieName: string, isSecured: boolean, cookieDomain: string) => {\n return this.create({\n cookieName,\n value: '',\n expires: new Date(),\n secure: isSecured,\n domain: cookieDomain,\n silent: true,\n });\n };\n\n createEmptyCookies = (\n isSecured: boolean,\n cookieDomain: string,\n _cookiesToRemove: string[],\n removeRefresh = true\n ): string[] => {\n const allEmptyCookies: string[] = [];\n\n const refreshTokenVariants = getRefreshTokenCookieNameVariants();\n const cookiesToRemove = [..._cookiesToRemove, ...(removeRefresh ? refreshTokenVariants : [])];\n\n cookiesToRemove.forEach((name: string) => {\n allEmptyCookies.push(...this.createEmptySingleCookie(name, isSecured, cookieDomain));\n });\n\n return allEmptyCookies;\n };\n\n private getCookiesToRemove = (request?: RequestType): string[] => {\n const logger = fronteggLogger.child({ tag: 'getCookiesToRemove' });\n if (!request) {\n return [];\n }\n try {\n logger.info('extract cookie from request headers');\n const cookieStr = getCookieHeader(request);\n const cookies = cookieStr && cookieSerializer.parse(cookieStr);\n if (!cookies) {\n return [];\n }\n let cookieNumber = 1;\n const cookieToRemove = [];\n if (cookies[this.getCookieName()]) {\n cookieToRemove.push(this.getCookieName());\n }\n while (cookies[this.getCookieName(cookieNumber)]) {\n cookieToRemove.push(this.getCookieName(cookieNumber));\n cookieNumber++;\n }\n logger.info(`number of cookies to remove: ${cookieToRemove.length}`);\n return cookieToRemove;\n } catch (e) {\n logger.error(e);\n return [];\n }\n };\n\n /**\n * Take a list of cookieNames and return the headers to remove the cookies from the client side\n * @param {RemoveCookiesOptions} setCookieValue\n */\n getRequestCookiesHeaderToRemove({\n cookieNames,\n isSecured,\n cookieDomain,\n req,\n }: Omit<RemoveCookiesOptions, 'res'>): string[] {\n const logger = fronteggLogger.child({ tag: 'CookieManager.getSetCookiesHeaderToRemove' });\n logger.debug('Setting empty cookie headers remove cookies from client side');\n const cookiesToRemove = this.getCookiesToRemove(req);\n const cookieValue = this.createEmptyCookies(isSecured, cookieDomain, cookieNames ?? cookiesToRemove);\n return [...cookieValue];\n }\n\n /**\n * Take a list of cookieNames and modify request/response headers\n * to proxy the cookies from Next.js to Frontegg Services and vice-versa\n * @param {RemoveCookiesOptions} setCookieValue\n */\n removeCookies({ cookieNames, isSecured, cookieDomain, res, req }: RemoveCookiesOptions): void {\n const logger = fronteggLogger.child({ tag: 'CookieManager.removeCookies' });\n const cookieValue = this.getRequestCookiesHeaderToRemove({ cookieNames, isSecured, cookieDomain, req });\n\n let existingSetCookie = (res.getHeader('set-cookie') as string[] | string) ?? [];\n if (existingSetCookie != null && typeof existingSetCookie === 'object' && !Array.isArray(existingSetCookie)) {\n existingSetCookie = Object.values(existingSetCookie);\n }\n if (typeof existingSetCookie === 'string') {\n existingSetCookie = [existingSetCookie];\n }\n const setCookieHeaders = [...existingSetCookie, ...cookieValue];\n\n logger.debug(`removing headers (count: ${setCookieHeaders.length})`);\n res.setHeader('set-cookie', setCookieHeaders);\n }\n\n /**\n * Take a list of cookie headers and modify the Domain / Secure / SameSite\n * to proxy the cookies to Frontegg Services and vice-versa\n * @param {string[]} setCookieValue - list of cookies to modify\n * @param {boolean} isSecured - if the running application behind SSL\n */\n modifySetCookie = (setCookieValue: string[] | undefined, isSecured: boolean): string[] | undefined => {\n const logger = fronteggLogger.child({ tag: 'CookieManager.modifySetCookie' });\n if (!setCookieValue || setCookieValue.length === 0) {\n logger.info(`No headers to modify`);\n return setCookieValue;\n }\n\n // noinspection SuspiciousTypeOfGuard\n if (typeof setCookieValue === 'string') {\n const cookieRegexSplitter = /(.*?;.*?(?:Expires=[^;]+;.*?)?(?=,\\s*\\S+=|$))/g;\n const cookies = [];\n const cookieHeader = `${setCookieValue}`;\n let match;\n while ((match = cookieRegexSplitter.exec(cookieHeader)) !== null) {\n let cookieString = match[1].trim();\n if (cookieString.startsWith(',')) {\n cookies.push(cookieString.substring(1).trim());\n } else {\n cookies.push(cookieString);\n }\n }\n setCookieValue = cookies;\n }\n\n logger.info(`modifying cookie headers (count: ${setCookieValue.length})`);\n return setCookieValue.map((c) => {\n let cookie = c.split('; ');\n\n logger.debug(`modifying cookie ${cookie[0]}, isSecured: ${isSecured}`);\n if (!isSecured) {\n cookie = cookie.filter((property) => property !== 'Secure' && property !== 'SameSite=None');\n }\n\n return (\n cookie\n .map((property) => {\n if (property.trim().startsWith(`fe_refresh_${config.clientId.replace('-', '')}`)) {\n if (config.rewriteCookieByAppId && config.appId) {\n return property.replace(\n `fe_refresh_${config.clientId.replace('-', '')}`,\n `fe_refresh_${config.appId.replace('-', '')}`\n );\n } else {\n return property;\n }\n } else if (property.toLowerCase() === `domain=${config.baseUrlHost}`) {\n return `Domain=${config.cookieDomain}`;\n } else {\n return property;\n }\n })\n .join(';') + ';'\n );\n });\n };\n}\n\nexport default new CookieManager();\n"],"mappings":"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","ignoreList":[]}
|