@frontegg/nextjs 7.0.17-alpha.5712339467 → 7.0.17-alpha.5753133642
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 +3 -1
- package/edge/shouldBypassMiddleware.js +2 -3
- package/edge/shouldBypassMiddleware.js.map +1 -1
- package/index.js +1 -1
- package/middleware/ProxyResponseCallback.js +2 -1
- package/middleware/ProxyResponseCallback.js.map +1 -1
- package/package.json +3 -3
- package/sdkVersion.js +1 -1
- package/sdkVersion.js.map +1 -1
- package/utils/cookies/index.d.ts +7 -1
- package/utils/cookies/index.js +27 -5
- package/utils/cookies/index.js.map +1 -1
- package/utils/cookies/types.d.ts +1 -0
- package/utils/cookies/types.js.map +1 -1
- package/utils/refreshAccessToken/index.js +2 -1
- package/utils/refreshAccessToken/index.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## [7.0.17](https://github.com/frontegg/frontegg-nextjs/compare/v7.0.16...v7.0.17) (2023-
|
|
3
|
+
## [7.0.17](https://github.com/frontegg/frontegg-nextjs/compare/v7.0.16...v7.0.17) (2023-8-3)
|
|
4
4
|
|
|
5
5
|
- FR-12701 - revert change settings list
|
|
6
6
|
- FR-12696 - Entitlements load on demand fix
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
### NextJS Wrapper 7.0.17:
|
|
11
|
+
- FR-12942 - fix-next-js-build-with-middleware-file
|
|
12
|
+
- FR-12947 - switching-tenant-cause-duplicated-session-cookie
|
|
11
13
|
- FR-12634 - support-custom-login-sub-domain-out-of-the-box
|
|
12
14
|
- Update Frontegg AdminPortal to 6.126.0
|
|
13
15
|
# Change Log
|
|
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.shouldByPassMiddleware = void 0;
|
|
8
8
|
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
|
9
9
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
10
|
-
var
|
|
10
|
+
var _consts = require("@frontegg/redux-store/auth/LoginState/consts");
|
|
11
11
|
const _excluded = ["authenticatedUrl"];
|
|
12
12
|
const staticFilesRegex = new RegExp('^/(_next/static).*');
|
|
13
13
|
const imageOptimizationRegex = new RegExp('^/(_next/image).*');
|
|
@@ -41,8 +41,7 @@ const shouldByPassMiddleware = (pathname, options) => {
|
|
|
41
41
|
const isImageOptimization = imageOptimizationRegex.test(pathname);
|
|
42
42
|
const isHeaderRequests = headerRequestsRegex.test(pathname);
|
|
43
43
|
const isFronteggMiddleware = fronteggMiddlewareRegex.test(pathname);
|
|
44
|
-
const
|
|
45
|
-
authRoutes = (0, _objectWithoutPropertiesLoose2.default)(_authInitialState$rou, _excluded);
|
|
44
|
+
const authRoutes = (0, _objectWithoutPropertiesLoose2.default)(_consts.defaultFronteggRoutes, _excluded);
|
|
46
45
|
const isFronteggRoutes = Object.values(authRoutes).find(path => pathname.startsWith(path)) != null;
|
|
47
46
|
if (isStaticFiles) return _options.bypassStaticFiles;
|
|
48
47
|
if (isImageOptimization) return _options.bypassImageOptimization;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shouldBypassMiddleware.js","names":["
|
|
1
|
+
{"version":3,"file":"shouldBypassMiddleware.js","names":["_consts","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 '@frontegg/redux-store/auth/LoginState/consts';\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, options?: ByPassOptions): 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 return false;\n};\n"],"mappings":";;;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAAqF,MAAAC,SAAA;AAErF,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,CAACC,QAAgB,EAAEC,OAAuB,KAAc;EAC5F,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,GAAGjB,gBAAgB,CAACkB,IAAI,CAACZ,QAAQ,CAAC;EACrD,MAAMa,mBAAmB,GAAGjB,sBAAsB,CAACgB,IAAI,CAACZ,QAAQ,CAAC;EACjE,MAAMc,gBAAgB,GAAGjB,mBAAmB,CAACe,IAAI,CAACZ,QAAQ,CAAC;EAC3D,MAAMe,oBAAoB,GAAGjB,uBAAuB,CAACc,IAAI,CAACZ,QAAQ,CAAC;EAEnE,MAA6BgB,UAAU,OAAAC,8BAAA,CAAAb,OAAA,EAAKc,6BAAqB,EAAAzB,SAAA;EACjE,MAAM0B,gBAAgB,GAAGC,MAAM,CAACC,MAAM,CAACL,UAAU,CAAC,CAACM,IAAI,CAAEC,IAAI,IAAKvB,QAAQ,CAACwB,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,OAAO,KAAK;AACd,CAAC;AAACgB,OAAA,CAAA1B,sBAAA,GAAAA,sBAAA"}
|
package/index.js
CHANGED
|
@@ -60,7 +60,8 @@ const ProxyResponseCallback = (proxyRes, req, res) => {
|
|
|
60
60
|
const sessionCookie = _cookies.default.create({
|
|
61
61
|
value: session,
|
|
62
62
|
expires: new Date(decodedJwt.exp * 1000),
|
|
63
|
-
secure: isSecured
|
|
63
|
+
secure: isSecured,
|
|
64
|
+
req
|
|
64
65
|
});
|
|
65
66
|
cookies.push(...sessionCookie);
|
|
66
67
|
}
|
|
@@ -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","url","statusCode","isSuccess","bodyStr","toString","isLogout","isFronteggLogoutUrl","CookieManager","removeCookies","cookieDomain","status","end","_CookieManager$modify","cookies","modifySetCookie","headers","body","JSON","parse","accessToken","access_token","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 { isFronteggLogoutUrl } from './helpers';\nimport fronteggLogger from '../utils/fronteggLogger';\nimport { isSSOPostRequest } from '../utils/refreshAccessToken/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 const 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 res.status(statusCode).end(bodyStr);\n return;\n }\n\n if (isSuccess) {\n const cookies = CookieManager.modifySetCookie(proxyRes.headers['set-cookie'], isSecured) ?? [];\n\n try {\n if (bodyStr && bodyStr.length > 0) {\n const body = JSON.parse(bodyStr);\n if (body.accessToken || body.access_token) {\n const [session, decodedJwt] = await createSessionFromAccessToken(body);\n if (session) {\n const sessionCookie = CookieManager.create({\n value: session,\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\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.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.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":";;;;;;;AAGA,IAAAA,OAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,QAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,QAAA,GAAAH,OAAA;AACA,IAAAI,eAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,SAAA,GAAAL,OAAA;AAEA,MAAMM,MAAM,GAAGC,uBAAc,CAACC,KAAK,CAAC;EAAEC,GAAG,EAAE;AAA8C,CAAC,CAAC;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,qBAAyE,GAAGA,CAACC,QAAQ,EAAEC,GAAG,EAAEC,GAAG,KAAK;EACxG,IAAIC,MAAM,GAAG,IAAIC,MAAM,CAAC,EAAE,CAAC;EAC3B,IAAIC,WAAmB,GAAG,CAAC;EAC3B,MAAMC,SAAS,GAAG,IAAIC,GAAG,CAACC,eAAM,CAACC,MAAM,CAAC,CAACC,QAAQ,KAAK,QAAQ;EAE9DV,QAAQ,CAACW,EAAE,CAAC,MAAM,EAAGC,KAAa,IAAK;IACrCP,WAAW,IAAIO,KAAK,CAACC,MAAM;IAC3BV,MAAM,GAAGC,MAAM,CAACU,MAAM,CAAC,CAACX,MAAM,EAAES,KAAK,CAAC,EAAEP,WAAW,CAAC;EACtD,CAAC,CAAC;EACFL,QAAQ,CAACW,EAAE,CAAC,KAAK,EAAE,YAAY;IAC7B,IAAI;MAAA,IAAAI,oBAAA;MACF,MAAMC,GAAG,GAAGf,GAAG,CAACe,GAAI;MACpB,MAAMC,UAAU,IAAAF,oBAAA,GAAGf,QAAQ,CAACiB,UAAU,YAAAF,oBAAA,GAAI,GAAG;MAC7C,MAAMG,SAAS,GAAGD,UAAU,IAAI,GAAG,IAAIA,UAAU,GAAG,GAAG;MACvD,MAAME,OAAO,GAAGhB,MAAM,CAACiB,QAAQ,CAAC,OAAO,CAAC;MACxC,MAAMC,QAAQ,GAAG,IAAAC,4BAAmB,EAACN,GAAG,CAAC;MAEzC,IAAIK,QAAQ,EAAE;QACZE,gBAAa,CAACC,aAAa,CAAC;UAC1BlB,SAAS;UACTmB,YAAY,EAAEjB,eAAM,CAACiB,YAAY;UACjCvB,GAAG;UACHD;QACF,CAAC,CAAC;QACFC,GAAG,CAACwB,MAAM,CAACT,UAAU,CAAC,CAACU,GAAG,CAACR,OAAO,CAAC;QACnC;MACF;MAEA,IAAID,SAAS,EAAE;QAAA,IAAAU,qBAAA;QACb,MAAMC,OAAO,IAAAD,qBAAA,GAAGL,gBAAa,CAACO,eAAe,CAAC9B,QAAQ,CAAC+B,OAAO,CAAC,YAAY,CAAC,EAAEzB,SAAS,CAAC,YAAAsB,qBAAA,GAAI,EAAE;QAE9F,IAAI;UACF,IAAIT,OAAO,IAAIA,OAAO,CAACN,MAAM,GAAG,CAAC,EAAE;YACjC,MAAMmB,IAAI,GAAGC,IAAI,CAACC,KAAK,CAACf,OAAO,CAAC;YAChC,IAAIa,IAAI,CAACG,WAAW,IAAIH,IAAI,CAACI,YAAY,EAAE;cACzC,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAG,MAAM,IAAAC,oCAA4B,EAACP,IAAI,CAAC;cACtE,IAAIK,OAAO,EAAE;gBACX,MAAMG,aAAa,GAAGjB,gBAAa,CAACkB,MAAM,CAAC;kBACzCC,KAAK,EAAEL,OAAO;kBACdM,OAAO,EAAE,IAAIC,IAAI,CAACN,UAAU,CAACO,GAAG,GAAG,IAAI,CAAC;kBACxCC,MAAM,EAAExC;
|
|
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","url","statusCode","isSuccess","bodyStr","toString","isLogout","isFronteggLogoutUrl","CookieManager","removeCookies","cookieDomain","status","end","_CookieManager$modify","cookies","modifySetCookie","headers","body","JSON","parse","accessToken","access_token","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 { isFronteggLogoutUrl } from './helpers';\nimport fronteggLogger from '../utils/fronteggLogger';\nimport { isSSOPostRequest } from '../utils/refreshAccessToken/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 const 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 res.status(statusCode).end(bodyStr);\n return;\n }\n\n if (isSuccess) {\n const cookies = CookieManager.modifySetCookie(proxyRes.headers['set-cookie'], isSecured) ?? [];\n\n try {\n if (bodyStr && bodyStr.length > 0) {\n const body = JSON.parse(bodyStr);\n if (body.accessToken || body.access_token) {\n const [session, decodedJwt] = await createSessionFromAccessToken(body);\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.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.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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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontegg/nextjs",
|
|
3
3
|
"libName": "FronteggNextJs",
|
|
4
|
-
"version": "7.0.17-alpha.
|
|
4
|
+
"version": "7.0.17-alpha.5753133642",
|
|
5
5
|
"author": "Frontegg LTD",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"lint-json": "eslint -c .eslintrc.json -o ./lint-report.json --format json --no-color ./src/**/*.{ts,tsx}"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@frontegg/js": "6.
|
|
31
|
-
"@frontegg/react-hooks": "6.
|
|
30
|
+
"@frontegg/js": "6.128.0",
|
|
31
|
+
"@frontegg/react-hooks": "6.128.0",
|
|
32
32
|
"http-proxy": "^1.18.1",
|
|
33
33
|
"iron-session": "^6.3.1",
|
|
34
34
|
"jose": "^4.12.2"
|
package/sdkVersion.js
CHANGED
package/sdkVersion.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdkVersion.js","names":["version","exports","default","_default"],"sources":["../../../packages/nextjs/src/sdkVersion.ts"],"sourcesContent":["export default { version: '7.0.17-alpha.
|
|
1
|
+
{"version":3,"file":"sdkVersion.js","names":["version","exports","default","_default"],"sources":["../../../packages/nextjs/src/sdkVersion.ts"],"sourcesContent":["export default { version: '7.0.17-alpha.5753133642' };\n"],"mappings":";;;;;;eAAe;EAAEA,OAAO,EAAE;AAA0B,CAAC;AAAAC,OAAA,CAAAC,OAAA,GAAAC,QAAA"}
|
package/utils/cookies/index.d.ts
CHANGED
|
@@ -3,6 +3,12 @@ import { CreateCookieOptions, RemoveCookiesOptions, RequestType } from './types'
|
|
|
3
3
|
declare class CookieManager {
|
|
4
4
|
getCookieName: (cookieNumber?: number, cookieName?: string) => string;
|
|
5
5
|
get refreshTokenKey(): string;
|
|
6
|
+
/**
|
|
7
|
+
* This function creates list of empty cookies that already exists in the request.
|
|
8
|
+
* This is used for removing existing cookies before creating new ones.
|
|
9
|
+
* @param {CreateCookieOptions} options - Create cookie options
|
|
10
|
+
*/
|
|
11
|
+
getEmptyCookiesBeforeCreatingNew({ req, value, secure, domain }: CreateCookieOptions): string[];
|
|
6
12
|
/**
|
|
7
13
|
* Validate and create new cookie headers.
|
|
8
14
|
* The default value of `cookieName` is {@link config.cookieName}
|
|
@@ -24,7 +30,7 @@ declare class CookieManager {
|
|
|
24
30
|
getSessionCookieFromRequest(request?: RequestType): string | undefined;
|
|
25
31
|
parseCookieFromArray(cookies: RequestCookie[]): string | undefined;
|
|
26
32
|
private createEmptySingleCookie;
|
|
27
|
-
createEmptyCookies: (isSecured: boolean, cookieDomain: string, _cookiesToRemove: string[]) => string[];
|
|
33
|
+
createEmptyCookies: (isSecured: boolean, cookieDomain: string, _cookiesToRemove: string[], removeRefresh?: boolean) => string[];
|
|
28
34
|
private getCookiesToRemove;
|
|
29
35
|
/**
|
|
30
36
|
* Take a list of cookieNames and modify request/response headers
|
package/utils/cookies/index.js
CHANGED
|
@@ -23,10 +23,10 @@ class CookieManager {
|
|
|
23
23
|
silent: true
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
|
-
this.createEmptyCookies = (isSecured, cookieDomain, _cookiesToRemove) => {
|
|
26
|
+
this.createEmptyCookies = (isSecured, cookieDomain, _cookiesToRemove, removeRefresh = true) => {
|
|
27
27
|
const allEmptyCookies = [];
|
|
28
28
|
const refreshTokenVariants = (0, _helpers.getRefreshTokenCookieNameVariants)();
|
|
29
|
-
const cookiesToRemove = [..._cookiesToRemove, ...refreshTokenVariants];
|
|
29
|
+
const cookiesToRemove = [..._cookiesToRemove, ...(removeRefresh ? refreshTokenVariants : [])];
|
|
30
30
|
cookiesToRemove.forEach(name => {
|
|
31
31
|
allEmptyCookies.push(...this.createEmptySingleCookie(name, isSecured, cookieDomain));
|
|
32
32
|
});
|
|
@@ -90,6 +90,27 @@ class CookieManager {
|
|
|
90
90
|
return `fe_refresh_${_config.default.clientId}`.replace(/-/g, '');
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* This function creates list of empty cookies that already exists in the request.
|
|
95
|
+
* This is used for removing existing cookies before creating new ones.
|
|
96
|
+
* @param {CreateCookieOptions} options - Create cookie options
|
|
97
|
+
*/
|
|
98
|
+
getEmptyCookiesBeforeCreatingNew({
|
|
99
|
+
req,
|
|
100
|
+
value,
|
|
101
|
+
secure,
|
|
102
|
+
domain
|
|
103
|
+
}) {
|
|
104
|
+
if (!req || !value) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
const cookiesToRemove = this.getCookiesToRemove(req);
|
|
108
|
+
if (cookiesToRemove.length === 0) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
return this.createEmptyCookies(secure, domain != null ? domain : _config.default.cookieDomain, cookiesToRemove, false);
|
|
112
|
+
}
|
|
113
|
+
|
|
93
114
|
/**
|
|
94
115
|
* Validate and create new cookie headers.
|
|
95
116
|
* The default value of `cookieName` is {@link config.cookieName}
|
|
@@ -101,7 +122,7 @@ class CookieManager {
|
|
|
101
122
|
tag: 'CookieManager.create',
|
|
102
123
|
level: options.silent ? 'error' : undefined
|
|
103
124
|
});
|
|
104
|
-
const cookieName = (_options$cookieName = options.cookieName) != null ? _options$cookieName :
|
|
125
|
+
const cookieName = (_options$cookieName = options.cookieName) != null ? _options$cookieName : this.getCookieName();
|
|
105
126
|
const cookieValue = options.value;
|
|
106
127
|
logger.info(`Creating new cookie for '${cookieName}'`);
|
|
107
128
|
const serializeOptions = {
|
|
@@ -117,15 +138,16 @@ class CookieManager {
|
|
|
117
138
|
serializeOptions.sameSite = 'none';
|
|
118
139
|
}
|
|
119
140
|
const serializedCookie = _serializer.default.serialize(cookieName, cookieValue, serializeOptions);
|
|
141
|
+
const removedCookiesValue = this.getEmptyCookiesBeforeCreatingNew(options);
|
|
120
142
|
if (serializedCookie.length <= _constants.COOKIE_MAX_LENGTH) {
|
|
121
143
|
logger.info(`Successfully create a cookie header, '${cookieName}'`);
|
|
122
|
-
return [serializedCookie];
|
|
144
|
+
return [...removedCookiesValue, serializedCookie];
|
|
123
145
|
} else {
|
|
124
146
|
logger.debug('Going to split cookie into chunks');
|
|
125
147
|
/** Create chunked cookie headers and store value as array of headers */
|
|
126
148
|
const cookies = (0, _helpers.splitValueToChunks)(cookieName, cookieValue, serializeOptions);
|
|
127
149
|
logger.info(`Successfully create chunked cookie headers, '${cookieName}' (count: ${cookies.length})`);
|
|
128
|
-
return cookies;
|
|
150
|
+
return [...removedCookiesValue, ...cookies];
|
|
129
151
|
}
|
|
130
152
|
}
|
|
131
153
|
|
|
@@ -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","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","map","c","cookie","split","debug","filter","property","toLowerCase","baseUrlHost","join","refreshTokenKey","clientId","replace","options","_options$cookieName","_options$httpOnly","_options$domain","_options$path","level","undefined","cookieValue","serializeOptions","httpOnly","path","priority","sameSite","serializedCookie","serialize","COOKIE_MAX_LENGTH","splitValueToChunks","parseCookieHeader","cookieHeader","getSessionCookieFromRequest","i","sessionCookies","sessionCookieChunk","parseCookieFromArray","cookieChunks","includes","sort","a","b","firstCookieNumber","parseInt","slice","secondCookieNumber","removeCookies","cookieNames","res","req","_ref","existingSetCookie","getHeader","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 } from './types';\nimport { COOKIE_MAX_LENGTH } from './constants';\n\nimport {\n getCookieHeader,\n getIndexedCookieName,\n getRefreshTokenCookieNameVariants,\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 return `fe_refresh_${config.clientId}`.replace(/-/g, '');\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 ?? config.cookieName;\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 = 'none';\n }\n\n const serializedCookie = cookieSerializer.serialize(cookieName, cookieValue, serializeOptions);\n\n if (serializedCookie.length <= COOKIE_MAX_LENGTH) {\n logger.info(`Successfully create a cookie header, '${cookieName}'`);\n return [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 return cookies;\n }\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 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 = (isSecured: boolean, cookieDomain: string, _cookiesToRemove: string[]): string[] => {\n const allEmptyCookies: string[] = [];\n\n const refreshTokenVariants = getRefreshTokenCookieNameVariants();\n const cookiesToRemove = [..._cookiesToRemove, ...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 if (typeof existingSetCookie === 'string') {\n existingSetCookie = [existingSetCookie];\n }\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 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.toLowerCase() === `domain=${config.baseUrlHost}`) {\n return `Domain=${config.cookieDomain}`;\n }\n return property;\n })\n .join(';') + ';'\n );\n });\n };\n}\n\nexport default new CookieManager();\n"],"mappings":";;;;;;;AAAA,IAAAA,WAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,OAAA,GAAAF,sBAAA,CAAAC,OAAA;AAEA,IAAAE,UAAA,GAAAF,OAAA;AAEA,IAAAG,QAAA,GAAAH,OAAA;AAMA,IAAAI,eAAA,GAAAL,sBAAA,CAAAC,OAAA;AAEA,MAAMK,aAAa,CAAC;EAAAC,YAAA;IAAA,KAClBC,aAAa,GAAG,CAACC,YAAqB,EAAEC,UAAU,GAAGC,eAAM,CAACD,UAAU,KACpED,YAAY,GAAG,IAAAG,6BAAoB,EAACH,YAAY,EAAEC,UAAU,CAAC,GAAGA,UAAU;IAAA,KA4HpEG,uBAAuB,GAAG,CAACH,UAAkB,EAAEI,SAAkB,EAAEC,YAAoB,KAAK;MAClG,OAAO,IAAI,CAACC,MAAM,CAAC;QACjBN,UAAU;QACVO,KAAK,EAAE,EAAE;QACTC,OAAO,EAAE,IAAIC,IAAI,EAAE;QACnBC,MAAM,EAAEN,SAAS;QACjBO,MAAM,EAAEN,YAAY;QACpBO,MAAM,EAAE;MACV,CAAC,CAAC;IACJ,CAAC;IAAA,KAEDC,kBAAkB,GAAG,CAACT,SAAkB,EAAEC,YAAoB,EAAES,gBAA0B,KAAe;MACvG,MAAMC,eAAyB,GAAG,EAAE;MAEpC,MAAMC,oBAAoB,GAAG,IAAAC,0CAAiC,GAAE;MAChE,MAAMC,eAAe,GAAG,CAAC,GAAGJ,gBAAgB,EAAE,GAAGE,oBAAoB,CAAC;MAEtEE,eAAe,CAACC,OAAO,CAAEC,IAAY,IAAK;QACxCL,eAAe,CAACM,IAAI,CAAC,GAAG,IAAI,CAAClB,uBAAuB,CAACiB,IAAI,EAAEhB,SAAS,EAAEC,YAAY,CAAC,CAAC;MACtF,CAAC,CAAC;MAEF,OAAOU,eAAe;IACxB,CAAC;IAAA,KAEOO,kBAAkB,GAAIC,OAAqB,IAAe;MAChE,MAAMC,MAAM,GAAGC,uBAAc,CAACC,KAAK,CAAC;QAAEC,GAAG,EAAE;MAAqB,CAAC,CAAC;MAClE,IAAI,CAACJ,OAAO,EAAE;QACZ,OAAO,EAAE;MACX;MACA,IAAI;QACFC,MAAM,CAACI,IAAI,CAAC,qCAAqC,CAAC;QAClD,MAAMC,SAAS,GAAG,IAAAC,wBAAe,EAACP,OAAO,CAAC;QAC1C,MAAMQ,OAAO,GAAGF,SAAS,IAAIG,mBAAgB,CAACC,KAAK,CAACJ,SAAS,CAAC;QAC9D,IAAI,CAACE,OAAO,EAAE;UACZ,OAAO,EAAE;QACX;QACA,IAAIhC,YAAY,GAAG,CAAC;QACpB,MAAMmC,cAAc,GAAG,EAAE;QACzB,IAAIH,OAAO,CAAC,IAAI,CAACjC,aAAa,EAAE,CAAC,EAAE;UACjCoC,cAAc,CAACb,IAAI,CAAC,IAAI,CAACvB,aAAa,EAAE,CAAC;QAC3C;QACA,OAAOiC,OAAO,CAAC,IAAI,CAACjC,aAAa,CAACC,YAAY,CAAC,CAAC,EAAE;UAChDmC,cAAc,CAACb,IAAI,CAAC,IAAI,CAACvB,aAAa,CAACC,YAAY,CAAC,CAAC;UACrDA,YAAY,EAAE;QAChB;QACAyB,MAAM,CAACI,IAAI,CAAE,gCAA+BM,cAAc,CAACC,MAAO,EAAC,CAAC;QACpE,OAAOD,cAAc;MACvB,CAAC,CAAC,OAAOE,CAAC,EAAE;QACVZ,MAAM,CAACa,KAAK,CAACD,CAAC,CAAC;QACf,OAAO,EAAE;MACX;IACF,CAAC;IAAA,KA6BDE,eAAe,GAAG,CAACC,cAAoC,EAAEnC,SAAkB,KAA2B;MACpG,MAAMoB,MAAM,GAAGC,uBAAc,CAACC,KAAK,CAAC;QAAEC,GAAG,EAAE;MAAgC,CAAC,CAAC;MAC7E,IAAI,CAACY,cAAc,IAAIA,cAAc,CAACJ,MAAM,KAAK,CAAC,EAAE;QAClDX,MAAM,CAACI,IAAI,CAAE,sBAAqB,CAAC;QACnC,OAAOW,cAAc;MACvB;MACAf,MAAM,CAACI,IAAI,CAAE,oCAAmCW,cAAc,CAACJ,MAAO,GAAE,CAAC;MACzE,OAAOI,cAAc,CAACC,GAAG,CAAEC,CAAC,IAAK;QAC/B,IAAIC,MAAM,GAAGD,CAAC,CAACE,KAAK,CAAC,IAAI,CAAC;QAE1BnB,MAAM,CAACoB,KAAK,CAAE,oBAAmBF,MAAM,CAAC,CAAC,CAAE,gBAAetC,SAAU,EAAC,CAAC;QACtE,IAAI,CAACA,SAAS,EAAE;UACdsC,MAAM,GAAGA,MAAM,CAACG,MAAM,CAAEC,QAAQ,IAAKA,QAAQ,KAAK,QAAQ,IAAIA,QAAQ,KAAK,eAAe,CAAC;QAC7F;QAEA,OACEJ,MAAM,CACHF,GAAG,CAAEM,QAAQ,IAAK;UACjB,IAAIA,QAAQ,CAACC,WAAW,EAAE,KAAM,UAAS9C,eAAM,CAAC+C,WAAY,EAAC,EAAE;YAC7D,OAAQ,UAAS/C,eAAM,CAACI,YAAa,EAAC;UACxC;UACA,OAAOyC,QAAQ;QACjB,CAAC,CAAC,CACDG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG;MAEtB,CAAC,CAAC;IACJ,CAAC;EAAA;EApOD,IAAIC,eAAeA,CAAA,EAAW;IAC5B,OAAQ,cAAajD,eAAM,CAACkD,QAAS,EAAC,CAACC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;EAC1D;;EAEA;AACF;AACA;AACA;AACA;EACE9C,MAAMA,CAAC+C,OAA4B,EAAY;IAAA,IAAAC,mBAAA,EAAAC,iBAAA,EAAAC,eAAA,EAAAC,aAAA;IAC7C,MAAMjC,MAAM,GAAGC,uBAAc,CAACC,KAAK,CAAC;MAAEC,GAAG,EAAE,sBAAsB;MAAE+B,KAAK,EAAEL,OAAO,CAACzC,MAAM,GAAG,OAAO,GAAG+C;IAAU,CAAC,CAAC;IACjH,MAAM3D,UAAU,IAAAsD,mBAAA,GAAGD,OAAO,CAACrD,UAAU,YAAAsD,mBAAA,GAAIrD,eAAM,CAACD,UAAU;IAC1D,MAAM4D,WAAW,GAAGP,OAAO,CAAC9C,KAAK;IACjCiB,MAAM,CAACI,IAAI,CAAE,4BAA2B5B,UAAW,GAAE,CAAC;IAEtD,MAAM6D,gBAAwC,GAAG;MAC/CrD,OAAO,EAAE6C,OAAO,CAAC7C,OAAO;MACxBsD,QAAQ,GAAAP,iBAAA,GAAEF,OAAO,CAACS,QAAQ,YAAAP,iBAAA,GAAI,IAAI;MAClC5C,MAAM,GAAA6C,eAAA,GAAEH,OAAO,CAAC1C,MAAM,YAAA6C,eAAA,GAAIvD,eAAM,CAACI,YAAY;MAC7C0D,IAAI,GAAAN,aAAA,GAAEJ,OAAO,CAACU,IAAI,YAAAN,aAAA,GAAI,GAAG;MACzBO,QAAQ,EAAE;IACZ,CAAC;IAED,IAAIX,OAAO,CAAC3C,MAAM,EAAE;MAClBc,MAAM,CAACoB,KAAK,CAAE,eAAc5C,UAAW,aAAY,CAAC;MACpD6D,gBAAgB,CAACnD,MAAM,GAAG2C,OAAO,CAAC3C,MAAM;MACxCmD,gBAAgB,CAACI,QAAQ,GAAG,MAAM;IACpC;IAEA,MAAMC,gBAAgB,GAAGlC,mBAAgB,CAACmC,SAAS,CAACnE,UAAU,EAAE4D,WAAW,EAAEC,gBAAgB,CAAC;IAE9F,IAAIK,gBAAgB,CAAC/B,MAAM,IAAIiC,4BAAiB,EAAE;MAChD5C,MAAM,CAACI,IAAI,CAAE,yCAAwC5B,UAAW,GAAE,CAAC;MACnE,OAAO,CAACkE,gBAAgB,CAAC;IAC3B,CAAC,MAAM;MACL1C,MAAM,CAACoB,KAAK,CAAC,mCAAmC,CAAC;MACjD;MACA,MAAMb,OAAO,GAAG,IAAAsC,2BAAkB,EAACrE,UAAU,EAAE4D,WAAW,EAAEC,gBAAgB,CAAC;MAC7ErC,MAAM,CAACI,IAAI,CAAE,gDAA+C5B,UAAW,aAAY+B,OAAO,CAACI,MAAO,GAAE,CAAC;MACrG,OAAOJ,OAAO;IAChB;EACF;;EAEA;AACF;AACA;AACA;AACA;AACA;EACEuC,iBAAiBA,CAAC/C,OAAoB,EAA0B;IAC9D,MAAMC,MAAM,GAAGC,uBAAc,CAACC,KAAK,CAAC;MAAEC,GAAG,EAAE;IAAkC,CAAC,CAAC;IAE/EH,MAAM,CAACI,IAAI,CAAC,kDAAkD,CAAC;IAC/D,MAAM2C,YAAY,GAAG,IAAAzC,wBAAe,EAACP,OAAO,CAAC;IAC7CC,MAAM,CAACI,IAAI,CAAC,8BAA8B,CAAC;IAC3C,OAAOI,mBAAgB,CAACC,KAAK,CAACsC,YAAY,CAAC;EAC7C;;EAEA;AACF;AACA;AACA;AACA;EACEC,2BAA2BA,CAACjD,OAAqB,EAAsB;IACrE,MAAMC,MAAM,GAAGC,uBAAc,CAACC,KAAK,CAAC;MAAEC,GAAG,EAAE;IAA4C,CAAC,CAAC;IACzFH,MAAM,CAACI,IAAI,CAAC,sDAAsD,CAAC;IAEnE,IAAI,CAACL,OAAO,EAAE;MACZC,MAAM,CAACI,IAAI,CAAE,qDAAoD,CAAC;MAClE,OAAO+B,SAAS;IAClB;IAEAnC,MAAM,CAACoB,KAAK,CAAC,uBAAuB,CAAC;IACrC,MAAMf,SAAS,GAAG,IAAAC,wBAAe,EAACP,OAAO,CAAC;IAE1CC,MAAM,CAACoB,KAAK,CAAC,8BAA8B,CAAC;IAC5C,MAAMb,OAAO,GAAGC,mBAAgB,CAACC,KAAK,CAACJ,SAAS,CAAC;IAEjDL,MAAM,CAACoB,KAAK,CAAC,kCAAkC,CAAC;IAChD,IAAI6B,CAAC,GAAG,CAAC;IACT,IAAIC,cAAc,GAAG,EAAE;IACvB,IAAIC,kBAAsC,GAAG5C,OAAO,CAAC,IAAI,CAACjC,aAAa,EAAE,CAAC;IAC1E,IAAI6E,kBAAkB,KAAKhB,SAAS,EAAE;MACpC,GAAG;QACDgB,kBAAkB,GAAG5C,OAAO,CAAC,IAAA7B,6BAAoB,EAACuE,CAAC,EAAE,CAAC,CAAC;QACvD,IAAIE,kBAAkB,EAAE;UACtBD,cAAc,IAAIC,kBAAkB;QACtC;MACF,CAAC,QAAQA,kBAAkB;IAC7B,CAAC,MAAM;MACLD,cAAc,GAAGC,kBAAkB;IACrC;IAEA,IAAID,cAAc,CAACvC,MAAM,KAAK,CAAC,EAAE;MAC/BX,MAAM,CAACI,IAAI,CAAC,0BAA0B,CAAC;MACvC,OAAO+B,SAAS;IAClB;IAEAnC,MAAM,CAACI,IAAI,CAAE,iCAAgC8C,cAAc,CAACvC,MAAO,GAAE,CAAC;IACtE,OAAOuC,cAAc;EACvB;EAEAE,oBAAoBA,CAAC7C,OAAwB,EAAsB;IACjE,MAAMP,MAAM,GAAGC,uBAAc,CAACC,KAAK,CAAC;MAAEC,GAAG,EAAE;IAAqC,CAAC,CAAC;IAClF,MAAMkD,YAAY,GAAG9C,OAAO,CAACc,MAAM,CAAEJ,CAAC,IAAKA,CAAC,CAACrB,IAAI,CAAC0D,QAAQ,CAAC,IAAI,CAAChF,aAAa,EAAE,CAAC,CAAC;IACjF0B,MAAM,CAACI,IAAI,CAAC,2DAA2D,CAAC;IAExE,IAAI,CAACiD,YAAY,IAAIA,YAAY,CAAC1C,MAAM,KAAK,CAAC,EAAE;MAC9CX,MAAM,CAACI,IAAI,CAAE,0BAAyB,CAAC;MACvC,OAAO+B,SAAS;IAClB;IACAnC,MAAM,CAACoB,KAAK,CAAE,SAAQiC,YAAY,CAAC1C,MAAO,SAAQ,CAAC;IACnD0C,YAAY,CAACE,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAK;MAC1B,MAAMC,iBAAiB,GAAGC,QAAQ,CAACH,CAAC,CAAC5D,IAAI,CAACgE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;MACpD,MAAMC,kBAAkB,GAAGF,QAAQ,CAACF,CAAC,CAAC7D,IAAI,CAACgE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;MACrD,OAAOF,iBAAiB,GAAGG,kBAAkB,GAAG,CAAC,GAAG,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF7D,MAAM,CAACI,IAAI,CAAE,oCAAmC,CAAC;IACjD,OAAOiD,YAAY,CAACrC,GAAG,CAAEC,CAAC,IAAKA,CAAC,CAAClC,KAAK,CAAC,CAAC0C,IAAI,CAAC,EAAE,CAAC;EAClD;EAuDA;AACF;AACA;AACA;AACA;AACA;EACEqC,aAAaA,CAAC;IAAEC,WAAW;IAAEnF,SAAS;IAAEC,YAAY;IAAEmF,GAAG;IAAEC;EAA0B,CAAC,EAAQ;IAAA,IAAAC,IAAA;IAC5F,MAAMlE,MAAM,GAAGC,uBAAc,CAACC,KAAK,CAAC;MAAEC,GAAG,EAAE;IAA8B,CAAC,CAAC;IAC3EH,MAAM,CAACoB,KAAK,CAAC,8DAA8D,CAAC;IAC5E,MAAM1B,eAAe,GAAG,IAAI,CAACI,kBAAkB,CAACmE,GAAG,CAAC;IACpD,MAAM7B,WAAW,GAAG,IAAI,CAAC/C,kBAAkB,CAACT,SAAS,EAAEC,YAAY,EAAEkF,WAAW,WAAXA,WAAW,GAAIrE,eAAe,CAAC;IACpG,IAAIyE,iBAAiB,IAAAD,IAAA,GAAIF,GAAG,CAACI,SAAS,CAAC,YAAY,CAAC,YAAAF,IAAA,GAA0B,EAAE;IAChF,IAAI,OAAOC,iBAAiB,KAAK,QAAQ,EAAE;MACzCA,iBAAiB,GAAG,CAACA,iBAAiB,CAAC;IACzC;IAEA,MAAME,gBAAgB,GAAG,CAAC,GAAGF,iBAAiB,EAAE,GAAG/B,WAAW,CAAC;IAC/DpC,MAAM,CAACoB,KAAK,CAAE,4BAA2BiD,gBAAgB,CAAC1D,MAAO,GAAE,CAAC;IACpEqD,GAAG,CAACM,SAAS,CAAC,YAAY,EAAED,gBAAgB,CAAC;EAC/C;;EAEA;AACF;AACA;AACA;AACA;AACA;AA4BA;AAAC,IAAAE,QAAA,GAEc,IAAInG,aAAa,EAAE;AAAAoG,OAAA,CAAAC,OAAA,GAAAF,QAAA"}
|
|
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","map","c","cookie","split","debug","filter","property","toLowerCase","baseUrlHost","join","refreshTokenKey","clientId","replace","getEmptyCookiesBeforeCreatingNew","req","options","_options$cookieName","_options$httpOnly","_options$domain","_options$path","level","undefined","cookieValue","serializeOptions","httpOnly","path","priority","sameSite","serializedCookie","serialize","removedCookiesValue","COOKIE_MAX_LENGTH","splitValueToChunks","parseCookieHeader","cookieHeader","getSessionCookieFromRequest","i","sessionCookies","sessionCookieChunk","parseCookieFromArray","cookieChunks","includes","sort","a","b","firstCookieNumber","parseInt","slice","secondCookieNumber","removeCookies","cookieNames","res","_ref","existingSetCookie","getHeader","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 } from './types';\nimport { COOKIE_MAX_LENGTH } from './constants';\n\nimport {\n getCookieHeader,\n getIndexedCookieName,\n getRefreshTokenCookieNameVariants,\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 return `fe_refresh_${config.clientId}`.replace(/-/g, '');\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({ req, value, secure, domain }: CreateCookieOptions): string[] {\n if (!req || !value) {\n return [];\n }\n const cookiesToRemove = this.getCookiesToRemove(req);\n if (cookiesToRemove.length === 0) {\n return [];\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 = 'none';\n }\n\n const serializedCookie = cookieSerializer.serialize(cookieName, cookieValue, serializeOptions);\n\n const removedCookiesValue = this.getEmptyCookiesBeforeCreatingNew(options);\n\n if (serializedCookie.length <= COOKIE_MAX_LENGTH) {\n logger.info(`Successfully create a cookie header, '${cookieName}'`);\n return [...removedCookiesValue, 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 return [...removedCookiesValue, ...cookies];\n }\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 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 if (typeof existingSetCookie === 'string') {\n existingSetCookie = [existingSetCookie];\n }\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 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.toLowerCase() === `domain=${config.baseUrlHost}`) {\n return `Domain=${config.cookieDomain}`;\n }\n return property;\n })\n .join(';') + ';'\n );\n });\n };\n}\n\nexport default new CookieManager();\n"],"mappings":"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"}
|
package/utils/cookies/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../../../packages/nextjs/src/utils/cookies/types.ts"],"sourcesContent":["import { IncomingMessage, ServerResponse } from 'http';\n\nexport type RequestType = IncomingMessage | Request;\nexport type ResponseType = ServerResponse;\n\nexport interface CreateCookieOptions extends Pick<CookieSerializeOptions, 'domain' | 'httpOnly' | 'path'> {\n cookieName?: string;\n value: string;\n secure: boolean;\n expires: Date;\n silent?: boolean;\n}\n\nexport interface RemoveCookiesOptions {\n cookieNames?: string[];\n isSecured: boolean;\n cookieDomain: string;\n res: ResponseType;\n req?: RequestType;\n}\n\n/**\n * Cookie serialization options\n */\nexport interface CookieSerializeOptions {\n domain?: string | undefined;\n expires?: Date | undefined;\n httpOnly?: boolean | undefined;\n maxAge?: number | undefined;\n path?: string | undefined;\n priority?: 'low' | 'medium' | 'high' | undefined;\n sameSite?: true | false | 'lax' | 'strict' | 'none' | undefined;\n secure?: boolean | undefined;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../../../packages/nextjs/src/utils/cookies/types.ts"],"sourcesContent":["import { IncomingMessage, ServerResponse } from 'http';\n\nexport type RequestType = IncomingMessage | Request;\nexport type ResponseType = ServerResponse;\n\nexport interface CreateCookieOptions extends Pick<CookieSerializeOptions, 'domain' | 'httpOnly' | 'path'> {\n cookieName?: string;\n value: string;\n secure: boolean;\n expires: Date;\n silent?: boolean;\n req?: RequestType;\n}\n\nexport interface RemoveCookiesOptions {\n cookieNames?: string[];\n isSecured: boolean;\n cookieDomain: string;\n res: ResponseType;\n req?: RequestType;\n}\n\n/**\n * Cookie serialization options\n */\nexport interface CookieSerializeOptions {\n domain?: string | undefined;\n expires?: Date | undefined;\n httpOnly?: boolean | undefined;\n maxAge?: number | undefined;\n path?: string | undefined;\n priority?: 'low' | 'medium' | 'high' | undefined;\n sameSite?: true | false | 'lax' | 'strict' | 'none' | undefined;\n secure?: boolean | undefined;\n}\n"],"mappings":""}
|
|
@@ -77,7 +77,8 @@ async function refreshAccessToken(ctx) {
|
|
|
77
77
|
const cookieValue = _cookies.default.create({
|
|
78
78
|
value: session,
|
|
79
79
|
expires: new Date(decodedJwt.exp * 1000),
|
|
80
|
-
secure: isSecured
|
|
80
|
+
secure: isSecured,
|
|
81
|
+
req: nextJsRequest
|
|
81
82
|
});
|
|
82
83
|
newSetCookie.push(...cookieValue);
|
|
83
84
|
(_ctx$res = ctx.res) == null ? void 0 : _ctx$res.setHeader('set-cookie', newSetCookie);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_common","require","_config","_interopRequireDefault","_cookies","_helpers","_fronteggLogger","_encryption","_createSession","refreshAccessToken","ctx","logger","fronteggLogger","child","tag","info","pathname","nextJsRequest","req","nextJsResponse","res","url","debug","_response$headers","_response$headers$raw","_CookieManager$modify","_ctx$res","_data$accessToken","isRuntimeNextRequest","cookies","CookieManager","getSessionCookieFromRequest","session","createSession","encryption","isOauthCallback","isSamlCallback","response","config","isHostedLogin","refreshAccessTokenHostedLogin","refreshAccessTokenEmbedded","isSecured","isSSL","ok","removeCookies","cookieDomain","data","json","cookieHeader","headers","raw","call","newSetCookie","modifySetCookie","decodedJwt","refreshToken","createSessionFromAccessToken","cookieValue","create","value","expires","Date","exp","secure","push","setHeader","accessToken","access_token","user","e","error"],"sources":["../../../../../packages/nextjs/src/utils/refreshAccessToken/index.ts"],"sourcesContent":["import type { NextPageContext } from 'next/dist/shared/lib/utils';\nimport type { FronteggNextJSSession } from '../../types';\nimport { createSessionFromAccessToken } from '../../common';\nimport config from '../../config';\nimport CookieManager from '../cookies';\nimport {\n isOauthCallback,\n isRuntimeNextRequest,\n isSamlCallback,\n refreshAccessTokenEmbedded,\n refreshAccessTokenHostedLogin,\n} from './helpers';\nimport fronteggLogger from '../fronteggLogger';\nimport encryption from '../encryption';\nimport createSession from '../createSession';\n\n/**\n * Refreshes the access token for the current session.\n *\n * @param {NextPageContext} ctx - The Next.js Page Context object.\n * @returns {Promise<FronteggNextJSSession | null>} A Promise that resolves to the updated session object, or `null` if the refresh failed.\n */\nexport default async function refreshAccessToken(ctx: NextPageContext): Promise<FronteggNextJSSession | null> {\n const logger = fronteggLogger.child({ tag: 'refreshAccessToken' });\n logger.info(`Refreshing token by for PageContext ${ctx.pathname}`);\n const nextJsRequest = ctx.req;\n const nextJsResponse = ctx.res;\n const url = nextJsRequest?.url;\n if (!nextJsResponse || !nextJsRequest || !url) {\n logger.debug(`abandon refreshToken due to PageContext.req = null`);\n return null;\n }\n\n try {\n logger.info(`Check if should request made from first application load`);\n\n if (isRuntimeNextRequest(url)) {\n logger.debug(`Detect runtime next.js request, resolving existing session from cookies if exists`);\n\n const cookies = CookieManager.getSessionCookieFromRequest(nextJsRequest);\n const session = await createSession(cookies, encryption);\n\n if (session) {\n logger.debug(`session resolved from session cookie`);\n return session;\n } else {\n logger.info('Failed to resolve session from cookie, going to refresh token');\n }\n }\n\n if (isOauthCallback(url) || isSamlCallback(url)) {\n /* Prevent refresh token due to oauth login callback */\n logger.debug(`abandon refreshToken for url='/oauth/callback'`);\n return null;\n }\n\n let response: Response | null;\n if (config.isHostedLogin) {\n response = await refreshAccessTokenHostedLogin(nextJsRequest);\n } else {\n response = await refreshAccessTokenEmbedded(nextJsRequest);\n }\n\n const isSecured = config.isSSL;\n if (response === null || !response.ok) {\n CookieManager.removeCookies({\n cookieDomain: config.cookieDomain,\n isSecured,\n req: nextJsRequest,\n res: nextJsResponse,\n });\n return null;\n }\n\n const data = await response.json();\n\n // @ts-ignore\n const cookieHeader = response.headers?.raw?.()['set-cookie'];\n const newSetCookie = CookieManager.modifySetCookie(cookieHeader, isSecured) ?? [];\n\n const [session, decodedJwt, refreshToken] = await createSessionFromAccessToken(data);\n\n if (!session) {\n return null;\n }\n const cookieValue = CookieManager.create({\n value: session,\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n });\n newSetCookie.push(...cookieValue);\n ctx.res?.setHeader('set-cookie', newSetCookie);\n\n return {\n accessToken: data.accessToken ?? data.access_token,\n user: decodedJwt,\n refreshToken,\n };\n } catch (e) {\n logger.error('[refreshToken] Failed to create session e', e);\n return null;\n }\n}\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","names":["_common","require","_config","_interopRequireDefault","_cookies","_helpers","_fronteggLogger","_encryption","_createSession","refreshAccessToken","ctx","logger","fronteggLogger","child","tag","info","pathname","nextJsRequest","req","nextJsResponse","res","url","debug","_response$headers","_response$headers$raw","_CookieManager$modify","_ctx$res","_data$accessToken","isRuntimeNextRequest","cookies","CookieManager","getSessionCookieFromRequest","session","createSession","encryption","isOauthCallback","isSamlCallback","response","config","isHostedLogin","refreshAccessTokenHostedLogin","refreshAccessTokenEmbedded","isSecured","isSSL","ok","removeCookies","cookieDomain","data","json","cookieHeader","headers","raw","call","newSetCookie","modifySetCookie","decodedJwt","refreshToken","createSessionFromAccessToken","cookieValue","create","value","expires","Date","exp","secure","push","setHeader","accessToken","access_token","user","e","error"],"sources":["../../../../../packages/nextjs/src/utils/refreshAccessToken/index.ts"],"sourcesContent":["import type { NextPageContext } from 'next/dist/shared/lib/utils';\nimport type { FronteggNextJSSession } from '../../types';\nimport { createSessionFromAccessToken } from '../../common';\nimport config from '../../config';\nimport CookieManager from '../cookies';\nimport {\n isOauthCallback,\n isRuntimeNextRequest,\n isSamlCallback,\n refreshAccessTokenEmbedded,\n refreshAccessTokenHostedLogin,\n} from './helpers';\nimport fronteggLogger from '../fronteggLogger';\nimport encryption from '../encryption';\nimport createSession from '../createSession';\n\n/**\n * Refreshes the access token for the current session.\n *\n * @param {NextPageContext} ctx - The Next.js Page Context object.\n * @returns {Promise<FronteggNextJSSession | null>} A Promise that resolves to the updated session object, or `null` if the refresh failed.\n */\nexport default async function refreshAccessToken(ctx: NextPageContext): Promise<FronteggNextJSSession | null> {\n const logger = fronteggLogger.child({ tag: 'refreshAccessToken' });\n logger.info(`Refreshing token by for PageContext ${ctx.pathname}`);\n const nextJsRequest = ctx.req;\n const nextJsResponse = ctx.res;\n const url = nextJsRequest?.url;\n if (!nextJsResponse || !nextJsRequest || !url) {\n logger.debug(`abandon refreshToken due to PageContext.req = null`);\n return null;\n }\n\n try {\n logger.info(`Check if should request made from first application load`);\n\n if (isRuntimeNextRequest(url)) {\n logger.debug(`Detect runtime next.js request, resolving existing session from cookies if exists`);\n\n const cookies = CookieManager.getSessionCookieFromRequest(nextJsRequest);\n const session = await createSession(cookies, encryption);\n\n if (session) {\n logger.debug(`session resolved from session cookie`);\n return session;\n } else {\n logger.info('Failed to resolve session from cookie, going to refresh token');\n }\n }\n\n if (isOauthCallback(url) || isSamlCallback(url)) {\n /* Prevent refresh token due to oauth login callback */\n logger.debug(`abandon refreshToken for url='/oauth/callback'`);\n return null;\n }\n\n let response: Response | null;\n if (config.isHostedLogin) {\n response = await refreshAccessTokenHostedLogin(nextJsRequest);\n } else {\n response = await refreshAccessTokenEmbedded(nextJsRequest);\n }\n\n const isSecured = config.isSSL;\n if (response === null || !response.ok) {\n CookieManager.removeCookies({\n cookieDomain: config.cookieDomain,\n isSecured,\n req: nextJsRequest,\n res: nextJsResponse,\n });\n return null;\n }\n\n const data = await response.json();\n\n // @ts-ignore\n const cookieHeader = response.headers?.raw?.()['set-cookie'];\n const newSetCookie = CookieManager.modifySetCookie(cookieHeader, isSecured) ?? [];\n\n const [session, decodedJwt, refreshToken] = await createSessionFromAccessToken(data);\n\n if (!session) {\n return null;\n }\n const cookieValue = CookieManager.create({\n value: session,\n expires: new Date(decodedJwt.exp * 1000),\n secure: isSecured,\n req: nextJsRequest,\n });\n newSetCookie.push(...cookieValue);\n ctx.res?.setHeader('set-cookie', newSetCookie);\n\n return {\n accessToken: data.accessToken ?? data.access_token,\n user: decodedJwt,\n refreshToken,\n };\n } catch (e) {\n logger.error('[refreshToken] Failed to create session e', e);\n return null;\n }\n}\n"],"mappings":"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"}
|