@backstage/plugin-auth-node 0.6.10-next.0 → 0.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @backstage/plugin-auth-node
2
2
 
3
+ ## 0.6.10
4
+
5
+ ### Patch Changes
6
+
7
+ - 2389358: remove leading dot in auth cookie cleanup call
8
+ - de96a60: chore(deps): bump `express` from 4.21.2 to 4.22.0
9
+ - b35f8b2: Fixed chunked cookie replacing edge case in OAuthCookieManager class where some of the old chunks would not get removed if new chunked cookie would have fewer chunks.
10
+ - e9dd634: fix flawed cookie removal logic with chunked tokens
11
+ - Updated dependencies
12
+ - @backstage/backend-plugin-api@1.6.0
13
+
14
+ ## 0.6.10-next.1
15
+
16
+ ### Patch Changes
17
+
18
+ - de96a60: chore(deps): bump `express` from 4.21.2 to 4.22.0
19
+ - e9dd634: fix flawed cookie removal logic with chunked tokens
20
+ - Updated dependencies
21
+ - @backstage/backend-plugin-api@1.6.0-next.1
22
+ - @backstage/catalog-client@1.12.1
23
+ - @backstage/catalog-model@1.7.6
24
+ - @backstage/config@1.3.6
25
+ - @backstage/errors@1.2.7
26
+ - @backstage/types@1.2.2
27
+
3
28
  ## 0.6.10-next.0
4
29
 
5
30
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -827,4 +827,5 @@ interface ProxyAuthRouteHandlersOptions<TResult> {
827
827
  /** @public */
828
828
  declare function createProxyAuthRouteHandlers<TResult>(options: ProxyAuthRouteHandlersOptions<TResult>): AuthProviderRouteHandlers;
829
829
 
830
- export { type AuthOwnershipResolutionExtensionPoint, type AuthOwnershipResolver, type AuthProviderConfig, type AuthProviderFactory, type AuthProviderRegistrationOptions, type AuthProviderRouteHandlers, type AuthProvidersExtensionPoint, type AuthResolverCatalogUserQuery, type AuthResolverContext, type BackstageIdentityResponse, type BackstageSignInResult, type BackstageUserIdentity, type ClientAuthResponse, type CookieConfigurer, DefaultIdentityClient, type IdentityApi, type IdentityApiGetIdentityRequest, IdentityClient, type IdentityClientOptions, type OAuthAuthenticator, type OAuthAuthenticatorAuthenticateInput, type OAuthAuthenticatorLogoutInput, type OAuthAuthenticatorRefreshInput, type OAuthAuthenticatorResult, type OAuthAuthenticatorScopeOptions, type OAuthAuthenticatorStartInput, OAuthEnvironmentHandler, type OAuthRouteHandlersOptions, type OAuthSession, type OAuthState, type OAuthStateTransform, type PassportDoneCallback, PassportHelpers, PassportOAuthAuthenticatorHelper, type PassportOAuthDoneCallback, type PassportOAuthPrivateInfo, type PassportOAuthResult, type PassportProfile, type ProfileInfo, type ProfileTransform, type ProxyAuthRouteHandlersOptions, type ProxyAuthenticator, type ReadDeclarativeSignInResolverOptions, type SignInInfo, type SignInResolver, type SignInResolverFactory, type SignInResolverFactoryOptions, type TokenParams, type WebMessageResponse, authOwnershipResolutionExtensionPoint, authProvidersExtensionPoint, commonSignInResolvers, createOAuthAuthenticator, createOAuthProviderFactory, createOAuthRouteHandlers, createProxyAuthProviderFactory, createProxyAuthRouteHandlers, createProxyAuthenticator, createSignInResolverFactory, decodeOAuthState, encodeOAuthState, getBearerTokenFromAuthorizationHeader, prepareBackstageIdentityResponse, readDeclarativeSignInResolver, sendWebMessageResponse, tokenTypes };
830
+ export { DefaultIdentityClient, IdentityClient, OAuthEnvironmentHandler, PassportHelpers, PassportOAuthAuthenticatorHelper, authOwnershipResolutionExtensionPoint, authProvidersExtensionPoint, commonSignInResolvers, createOAuthAuthenticator, createOAuthProviderFactory, createOAuthRouteHandlers, createProxyAuthProviderFactory, createProxyAuthRouteHandlers, createProxyAuthenticator, createSignInResolverFactory, decodeOAuthState, encodeOAuthState, getBearerTokenFromAuthorizationHeader, prepareBackstageIdentityResponse, readDeclarativeSignInResolver, sendWebMessageResponse, tokenTypes };
831
+ export type { AuthOwnershipResolutionExtensionPoint, AuthOwnershipResolver, AuthProviderConfig, AuthProviderFactory, AuthProviderRegistrationOptions, AuthProviderRouteHandlers, AuthProvidersExtensionPoint, AuthResolverCatalogUserQuery, AuthResolverContext, BackstageIdentityResponse, BackstageSignInResult, BackstageUserIdentity, ClientAuthResponse, CookieConfigurer, IdentityApi, IdentityApiGetIdentityRequest, IdentityClientOptions, OAuthAuthenticator, OAuthAuthenticatorAuthenticateInput, OAuthAuthenticatorLogoutInput, OAuthAuthenticatorRefreshInput, OAuthAuthenticatorResult, OAuthAuthenticatorScopeOptions, OAuthAuthenticatorStartInput, OAuthRouteHandlersOptions, OAuthSession, OAuthState, OAuthStateTransform, PassportDoneCallback, PassportOAuthDoneCallback, PassportOAuthPrivateInfo, PassportOAuthResult, PassportProfile, ProfileInfo, ProfileTransform, ProxyAuthRouteHandlersOptions, ProxyAuthenticator, ReadDeclarativeSignInResolverOptions, SignInInfo, SignInResolver, SignInResolverFactory, SignInResolverFactoryOptions, TokenParams, WebMessageResponse };
@@ -90,91 +90,111 @@ class OAuthCookieManager {
90
90
  ...this.getConfig(origin, pathSuffix)
91
91
  };
92
92
  const req = res.req;
93
- let output = res;
94
- if (val.length > MAX_COOKIE_SIZE_CHARACTERS) {
95
- const nonChunkedFormatExists = !!req.cookies[name];
96
- if (nonChunkedFormatExists) {
97
- output = output.cookie(name, "", this.getRemoveCookieOptions());
98
- }
99
- const chunked = this.splitCookieToChunks(val, MAX_COOKIE_SIZE_CHARACTERS);
100
- chunked.forEach((value, chunkNumber) => {
101
- output = output.cookie(
102
- OAuthCookieManager.getCookieChunkName(name, chunkNumber),
103
- value,
104
- options
105
- );
106
- });
107
- return output;
108
- }
109
- const chunkedFormatExists = OAuthCookieManager.chunkedCookieExists(
93
+ const newCookieShouldBeChunked = val.length > MAX_COOKIE_SIZE_CHARACTERS;
94
+ const existingChunkCount = OAuthCookieManager.countExistingCookieChunks(
110
95
  req,
111
96
  name
112
97
  );
98
+ const chunkedFormatExists = existingChunkCount > 0;
99
+ if (this.cookieConfigurer === defaultCookieConfigurer) {
100
+ this.removeLegacyCookieWithDomain(res, name, existingChunkCount);
101
+ }
113
102
  if (chunkedFormatExists) {
114
- for (let chunkNumber = 0; ; chunkNumber++) {
115
- const key = OAuthCookieManager.getCookieChunkName(name, chunkNumber);
116
- const exists = !!req.cookies[key];
117
- if (!exists) {
118
- break;
119
- }
120
- output = output.cookie(key, "", this.getRemoveCookieOptions());
121
- }
103
+ this.removeChunkedCookie(res, name, existingChunkCount);
122
104
  }
123
- if (this.cookieConfigurer === defaultCookieConfigurer) {
124
- const { hostname: domain } = new URL(this.options.callbackUrl);
125
- output = output.cookie(name, "", {
126
- ...this.getRemoveCookieOptions(),
127
- domain
128
- });
105
+ if (newCookieShouldBeChunked) {
106
+ this.setChunkedCookie(req, res, name, val, options);
107
+ } else {
108
+ res.cookie(name, val, options);
129
109
  }
130
- return output.cookie(name, val, options);
110
+ }
111
+ removeLegacyCookieWithDomain(res, name, chunkCount) {
112
+ const { hostname: domain } = new URL(this.options.callbackUrl);
113
+ res.cookie(name, "", {
114
+ ...this.getRemoveCookieOptions(),
115
+ domain
116
+ });
117
+ this.removeChunkedCookie(res, name, chunkCount, { domain });
118
+ }
119
+ setChunkedCookie(req, res, name, val, options) {
120
+ const nonChunkedFormatExists = !!req.cookies[name];
121
+ if (nonChunkedFormatExists) {
122
+ res.cookie(name, "", this.getRemoveCookieOptions());
123
+ }
124
+ const chunkedCookieArray = this.splitCookieToChunks(
125
+ val,
126
+ MAX_COOKIE_SIZE_CHARACTERS
127
+ );
128
+ chunkedCookieArray.forEach((chunkValue, chunkNumber) => {
129
+ res.cookie(
130
+ OAuthCookieManager.getCookieChunkName(name, chunkNumber),
131
+ chunkValue,
132
+ options
133
+ );
134
+ });
131
135
  }
132
136
  getCookie(req, name) {
133
- const isChunked = OAuthCookieManager.chunkedCookieExists(req, name);
137
+ const existingChunkCount = OAuthCookieManager.countExistingCookieChunks(
138
+ req,
139
+ name
140
+ );
141
+ const isChunked = existingChunkCount > 0;
134
142
  if (isChunked) {
135
- const chunks = [];
136
- let chunkNumber = 0;
137
- let chunk = req.cookies[OAuthCookieManager.getCookieChunkName(name, chunkNumber)];
138
- while (chunk) {
139
- chunks.push(chunk);
140
- chunkNumber++;
141
- chunk = req.cookies[OAuthCookieManager.getCookieChunkName(name, chunkNumber)];
142
- }
143
- return chunks.join("");
143
+ return this.getChunkedCookie(req, name, existingChunkCount);
144
144
  }
145
145
  return req.cookies[name];
146
146
  }
147
+ getChunkedCookie(req, name, chunkCount) {
148
+ const chunkedCookieArray = [];
149
+ for (let chunkNumber = 0; chunkNumber < chunkCount; chunkNumber++) {
150
+ const chunk = req.cookies[OAuthCookieManager.getCookieChunkName(name, chunkNumber)];
151
+ chunkedCookieArray.push(chunk);
152
+ }
153
+ return chunkedCookieArray.join("");
154
+ }
147
155
  removeCookie(res, name, origin) {
148
156
  const req = res.req;
149
- const options = this.getRemoveCookieOptions(origin);
150
- const isChunked = OAuthCookieManager.chunkedCookieExists(req, name);
151
- if (isChunked) {
152
- const nonChunkedFormatExists = !!req.cookies[name];
153
- let output = nonChunkedFormatExists ? res.cookie(name, "", options) : res;
154
- for (let chunkNumber = 0; ; chunkNumber++) {
155
- const key = OAuthCookieManager.getCookieChunkName(name, chunkNumber);
156
- const exists = !!req.cookies[key];
157
- if (!exists) {
158
- break;
159
- }
160
- output = output.cookie(key, "", options);
161
- }
162
- return output;
157
+ const existingChunkCount = OAuthCookieManager.countExistingCookieChunks(
158
+ req,
159
+ name
160
+ );
161
+ const chunkedFormatExists = existingChunkCount > 0;
162
+ const nonChunkedFormatExists = !!req.cookies[name];
163
+ if (nonChunkedFormatExists) {
164
+ res.cookie(name, "", this.getRemoveCookieOptions(origin));
165
+ }
166
+ if (chunkedFormatExists) {
167
+ this.removeChunkedCookie(res, name, existingChunkCount, {
168
+ origin
169
+ });
170
+ }
171
+ }
172
+ removeChunkedCookie(res, name, chunkCount, { domain, origin } = {}) {
173
+ for (let chunkNumber = 0; chunkNumber < chunkCount; chunkNumber++) {
174
+ const key = OAuthCookieManager.getCookieChunkName(name, chunkNumber);
175
+ const baseOptions = this.getRemoveCookieOptions(origin);
176
+ const options = domain ? { ...baseOptions, domain } : baseOptions;
177
+ res.cookie(key, "", options);
163
178
  }
164
- return res.cookie(name, "", options);
165
179
  }
166
180
  splitCookieToChunks(val, chunkSize) {
167
181
  const numChunks = Math.ceil(val.length / chunkSize);
168
- const chunks = Array(numChunks);
182
+ const chunkedCookieArray = Array(numChunks);
169
183
  let offset = 0;
170
184
  for (let i = 0; i < numChunks; i++) {
171
- chunks[i] = val.substring(offset, offset + chunkSize);
185
+ chunkedCookieArray[i] = val.substring(offset, offset + chunkSize);
172
186
  offset += chunkSize;
173
187
  }
174
- return chunks;
175
- }
176
- static chunkedCookieExists(req, name) {
177
- return !!req.cookies[OAuthCookieManager.getCookieChunkName(name, 0)];
188
+ return chunkedCookieArray;
189
+ }
190
+ static countExistingCookieChunks(req, name) {
191
+ for (let chunkNumber = 0; ; chunkNumber++) {
192
+ const key = OAuthCookieManager.getCookieChunkName(name, chunkNumber);
193
+ const exists = !!req.cookies[key];
194
+ if (!exists) {
195
+ return chunkNumber;
196
+ }
197
+ }
178
198
  }
179
199
  static getCookieChunkName(name, chunkIndex) {
180
200
  return `${name}-${chunkIndex}`;
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthCookieManager.cjs.js","sources":["../../src/oauth/OAuthCookieManager.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CookieOptions, Request, Response } from 'express';\nimport { CookieConfigurer } from '../types';\nimport { HumanDuration, durationToMilliseconds } from '@backstage/types';\n\nconst THOUSAND_DAYS_MS = 1000 * 24 * 60 * 60 * 1000;\nconst TEN_MINUTES_MS = 600 * 1000;\n\nconst MAX_COOKIE_SIZE_CHARACTERS = 4000;\n\nconst defaultCookieConfigurer: CookieConfigurer = ({\n callbackUrl,\n providerId,\n appOrigin,\n}) => {\n const { hostname: domain, pathname, protocol } = new URL(callbackUrl);\n const secure = protocol === 'https:';\n\n // For situations where the auth-backend is running on a\n // different domain than the app, we set the SameSite attribute\n // to 'none' to allow third-party access to the cookie, but\n // only if it's in a secure context (https).\n let sameSite: ReturnType<CookieConfigurer>['sameSite'] = 'lax';\n if (new URL(appOrigin).hostname !== domain && secure) {\n sameSite = 'none';\n }\n\n // If the provider supports callbackUrls, the pathname will\n // contain the complete path to the frame handler so we need\n // to slice off the trailing part of the path.\n const path = pathname.endsWith(`${providerId}/handler/frame`)\n ? pathname.slice(0, -'/handler/frame'.length)\n : `${pathname}/${providerId}`;\n\n return { path, secure, sameSite };\n};\n\n/** @internal */\nexport class OAuthCookieManager {\n private readonly cookieConfigurer: CookieConfigurer;\n private readonly nonceCookie: string;\n private readonly refreshTokenCookie: string;\n private readonly grantedScopeCookie: string;\n private readonly maxAge: number;\n\n constructor(\n private readonly options: {\n providerId: string;\n defaultAppOrigin: string;\n baseUrl: string;\n callbackUrl: string;\n cookieConfigurer?: CookieConfigurer;\n sessionDuration?: HumanDuration;\n },\n ) {\n this.cookieConfigurer = options.cookieConfigurer ?? defaultCookieConfigurer;\n\n this.nonceCookie = `${options.providerId}-nonce`;\n this.refreshTokenCookie = `${options.providerId}-refresh-token`;\n this.grantedScopeCookie = `${options.providerId}-granted-scope`;\n this.maxAge = options.sessionDuration\n ? durationToMilliseconds(options.sessionDuration)\n : THOUSAND_DAYS_MS;\n }\n\n private getConfig(origin?: string, pathSuffix: string = '') {\n const cookieConfig = this.cookieConfigurer({\n providerId: this.options.providerId,\n baseUrl: this.options.baseUrl,\n callbackUrl: this.options.callbackUrl,\n appOrigin: origin ?? this.options.defaultAppOrigin,\n });\n return {\n httpOnly: true,\n sameSite: 'lax' as const,\n ...cookieConfig,\n path: cookieConfig.path + pathSuffix,\n };\n }\n\n setNonce(res: Response, nonce: string, origin?: string): void {\n this.setCookie(\n res,\n this.nonceCookie,\n nonce,\n TEN_MINUTES_MS,\n origin,\n '/handler',\n );\n }\n\n setRefreshToken(res: Response, refreshToken: string, origin?: string): void {\n this.setCookie(\n res,\n this.refreshTokenCookie,\n refreshToken,\n this.maxAge,\n origin,\n );\n }\n\n removeRefreshToken(res: Response, origin?: string): void {\n this.removeCookie(res, this.refreshTokenCookie, origin);\n }\n\n removeGrantedScopes(res: Response, origin?: string): void {\n this.removeCookie(res, this.grantedScopeCookie, origin);\n }\n\n setGrantedScopes(res: Response, scope: string, origin?: string): void {\n this.setCookie(res, this.grantedScopeCookie, scope, this.maxAge, origin);\n }\n\n getNonce(req: Request): string | undefined {\n return this.getCookie(req, this.nonceCookie);\n }\n\n getRefreshToken(req: Request): string | undefined {\n return this.getCookie(req, this.refreshTokenCookie);\n }\n\n getGrantedScopes(req: Request): string | undefined {\n return this.getCookie(req, this.grantedScopeCookie);\n }\n\n private setCookie(\n res: Response,\n name: string,\n val: string,\n maxAge: number,\n origin?: string,\n pathSuffix: string = '',\n ): Response {\n const options = {\n maxAge,\n ...this.getConfig(origin, pathSuffix),\n };\n const req = res.req;\n let output = res;\n if (val.length > MAX_COOKIE_SIZE_CHARACTERS) {\n const nonChunkedFormatExists = !!req.cookies[name];\n if (nonChunkedFormatExists) {\n output = output.cookie(name, '', this.getRemoveCookieOptions());\n }\n\n const chunked = this.splitCookieToChunks(val, MAX_COOKIE_SIZE_CHARACTERS);\n chunked.forEach((value, chunkNumber) => {\n output = output.cookie(\n OAuthCookieManager.getCookieChunkName(name, chunkNumber),\n value,\n options,\n );\n });\n return output;\n }\n\n const chunkedFormatExists = OAuthCookieManager.chunkedCookieExists(\n req,\n name,\n );\n if (chunkedFormatExists) {\n for (let chunkNumber = 0; ; chunkNumber++) {\n const key = OAuthCookieManager.getCookieChunkName(name, chunkNumber);\n const exists = !!req.cookies[key];\n if (!exists) {\n break;\n }\n output = output.cookie(key, '', this.getRemoveCookieOptions());\n }\n }\n\n // If using the default cookieConfigurer, delete old cookie with domain set to the callbackUrl's domain (legacy behavior)\n if (this.cookieConfigurer === defaultCookieConfigurer) {\n const { hostname: domain } = new URL(this.options.callbackUrl);\n output = output.cookie(name, '', {\n ...this.getRemoveCookieOptions(),\n domain: domain,\n });\n }\n\n return output.cookie(name, val, options);\n }\n\n private getCookie(req: Request, name: string): string | undefined {\n const isChunked = OAuthCookieManager.chunkedCookieExists(req, name);\n if (isChunked) {\n const chunks: string[] = [];\n let chunkNumber = 0;\n let chunk =\n req.cookies[OAuthCookieManager.getCookieChunkName(name, chunkNumber)];\n while (chunk) {\n chunks.push(chunk);\n chunkNumber++;\n chunk =\n req.cookies[OAuthCookieManager.getCookieChunkName(name, chunkNumber)];\n }\n return chunks.join('');\n }\n return req.cookies[name];\n }\n\n private removeCookie(res: Response, name: string, origin?: string): Response {\n const req = res.req;\n const options = this.getRemoveCookieOptions(origin);\n const isChunked = OAuthCookieManager.chunkedCookieExists(req, name);\n if (isChunked) {\n const nonChunkedFormatExists = !!req.cookies[name];\n let output: Response = nonChunkedFormatExists\n ? res.cookie(name, '', options)\n : res;\n for (let chunkNumber = 0; ; chunkNumber++) {\n const key = OAuthCookieManager.getCookieChunkName(name, chunkNumber);\n const exists = !!req.cookies[key];\n if (!exists) {\n break;\n }\n output = output.cookie(key, '', options);\n }\n return output;\n }\n return res.cookie(name, '', options);\n }\n\n private splitCookieToChunks(val: string, chunkSize: number): string[] {\n const numChunks = Math.ceil(val.length / chunkSize);\n const chunks: string[] = Array<string>(numChunks);\n\n let offset: number = 0;\n for (let i = 0; i < numChunks; i++) {\n chunks[i] = val.substring(offset, offset + chunkSize);\n offset += chunkSize;\n }\n return chunks;\n }\n\n private static chunkedCookieExists(req: Request, name: string): boolean {\n return !!req.cookies[OAuthCookieManager.getCookieChunkName(name, 0)];\n }\n\n private static getCookieChunkName(name: string, chunkIndex: number): string {\n return `${name}-${chunkIndex}`;\n }\n\n private getRemoveCookieOptions(origin?: string): CookieOptions {\n return {\n maxAge: 0,\n ...this.getConfig(origin),\n };\n }\n}\n"],"names":["durationToMilliseconds"],"mappings":"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"}
1
+ {"version":3,"file":"OAuthCookieManager.cjs.js","sources":["../../src/oauth/OAuthCookieManager.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CookieOptions, Request, Response } from 'express';\nimport { CookieConfigurer } from '../types';\nimport { HumanDuration, durationToMilliseconds } from '@backstage/types';\n\nconst THOUSAND_DAYS_MS = 1000 * 24 * 60 * 60 * 1000;\nconst TEN_MINUTES_MS = 600 * 1000;\n\nconst MAX_COOKIE_SIZE_CHARACTERS = 4000;\n\nconst defaultCookieConfigurer: CookieConfigurer = ({\n callbackUrl,\n providerId,\n appOrigin,\n}) => {\n const { hostname: domain, pathname, protocol } = new URL(callbackUrl);\n const secure = protocol === 'https:';\n\n // For situations where the auth-backend is running on a\n // different domain than the app, we set the SameSite attribute\n // to 'none' to allow third-party access to the cookie, but\n // only if it's in a secure context (https).\n let sameSite: ReturnType<CookieConfigurer>['sameSite'] = 'lax';\n if (new URL(appOrigin).hostname !== domain && secure) {\n sameSite = 'none';\n }\n\n // If the provider supports callbackUrls, the pathname will\n // contain the complete path to the frame handler so we need\n // to slice off the trailing part of the path.\n const path = pathname.endsWith(`${providerId}/handler/frame`)\n ? pathname.slice(0, -'/handler/frame'.length)\n : `${pathname}/${providerId}`;\n\n return { path, secure, sameSite };\n};\n\n/** @internal */\nexport class OAuthCookieManager {\n private readonly cookieConfigurer: CookieConfigurer;\n private readonly nonceCookie: string;\n private readonly refreshTokenCookie: string;\n private readonly grantedScopeCookie: string;\n private readonly maxAge: number;\n\n constructor(\n private readonly options: {\n providerId: string;\n defaultAppOrigin: string;\n baseUrl: string;\n callbackUrl: string;\n cookieConfigurer?: CookieConfigurer;\n sessionDuration?: HumanDuration;\n },\n ) {\n this.cookieConfigurer = options.cookieConfigurer ?? defaultCookieConfigurer;\n\n this.nonceCookie = `${options.providerId}-nonce`;\n this.refreshTokenCookie = `${options.providerId}-refresh-token`;\n this.grantedScopeCookie = `${options.providerId}-granted-scope`;\n this.maxAge = options.sessionDuration\n ? durationToMilliseconds(options.sessionDuration)\n : THOUSAND_DAYS_MS;\n }\n\n private getConfig(origin?: string, pathSuffix: string = '') {\n const cookieConfig = this.cookieConfigurer({\n providerId: this.options.providerId,\n baseUrl: this.options.baseUrl,\n callbackUrl: this.options.callbackUrl,\n appOrigin: origin ?? this.options.defaultAppOrigin,\n });\n return {\n httpOnly: true,\n sameSite: 'lax' as const,\n ...cookieConfig,\n path: cookieConfig.path + pathSuffix,\n };\n }\n\n setNonce(res: Response, nonce: string, origin?: string): void {\n this.setCookie(\n res,\n this.nonceCookie,\n nonce,\n TEN_MINUTES_MS,\n origin,\n '/handler',\n );\n }\n\n setRefreshToken(res: Response, refreshToken: string, origin?: string): void {\n this.setCookie(\n res,\n this.refreshTokenCookie,\n refreshToken,\n this.maxAge,\n origin,\n );\n }\n\n removeRefreshToken(res: Response, origin?: string): void {\n this.removeCookie(res, this.refreshTokenCookie, origin);\n }\n\n removeGrantedScopes(res: Response, origin?: string): void {\n this.removeCookie(res, this.grantedScopeCookie, origin);\n }\n\n setGrantedScopes(res: Response, scope: string, origin?: string): void {\n this.setCookie(res, this.grantedScopeCookie, scope, this.maxAge, origin);\n }\n\n getNonce(req: Request): string | undefined {\n return this.getCookie(req, this.nonceCookie);\n }\n\n getRefreshToken(req: Request): string | undefined {\n return this.getCookie(req, this.refreshTokenCookie);\n }\n\n getGrantedScopes(req: Request): string | undefined {\n return this.getCookie(req, this.grantedScopeCookie);\n }\n\n private setCookie(\n res: Response,\n name: string,\n val: string,\n maxAge: number,\n origin?: string,\n pathSuffix: string = '',\n ): void {\n const options = {\n maxAge,\n ...this.getConfig(origin, pathSuffix),\n };\n const req = res.req;\n\n const newCookieShouldBeChunked = val.length > MAX_COOKIE_SIZE_CHARACTERS;\n const existingChunkCount = OAuthCookieManager.countExistingCookieChunks(\n req,\n name,\n );\n const chunkedFormatExists = existingChunkCount > 0;\n\n // If using the default cookieConfigurer, delete old cookie with domain\n // explicitly set to the callbackUrl's domain (legacy behavior)\n if (this.cookieConfigurer === defaultCookieConfigurer) {\n this.removeLegacyCookieWithDomain(res, name, existingChunkCount);\n }\n\n if (chunkedFormatExists) {\n this.removeChunkedCookie(res, name, existingChunkCount);\n }\n\n if (newCookieShouldBeChunked) {\n this.setChunkedCookie(req, res, name, val, options);\n } else {\n res.cookie(name, val, options);\n }\n }\n\n private removeLegacyCookieWithDomain(\n res: Response,\n name: string,\n chunkCount: number,\n ): void {\n const { hostname: domain } = new URL(this.options.callbackUrl);\n res.cookie(name, '', {\n ...this.getRemoveCookieOptions(),\n domain: domain,\n });\n\n this.removeChunkedCookie(res, name, chunkCount, { domain });\n }\n\n private setChunkedCookie(\n req: Request,\n res: Response,\n name: string,\n val: string,\n options: CookieOptions,\n ): void {\n const nonChunkedFormatExists = !!req.cookies[name];\n if (nonChunkedFormatExists) {\n res.cookie(name, '', this.getRemoveCookieOptions());\n }\n const chunkedCookieArray = this.splitCookieToChunks(\n val,\n MAX_COOKIE_SIZE_CHARACTERS,\n );\n chunkedCookieArray.forEach((chunkValue, chunkNumber) => {\n res.cookie(\n OAuthCookieManager.getCookieChunkName(name, chunkNumber),\n chunkValue,\n options,\n );\n });\n }\n\n private getCookie(req: Request, name: string): string | undefined {\n const existingChunkCount = OAuthCookieManager.countExistingCookieChunks(\n req,\n name,\n );\n const isChunked = existingChunkCount > 0;\n if (isChunked) {\n return this.getChunkedCookie(req, name, existingChunkCount);\n }\n return req.cookies[name];\n }\n\n private getChunkedCookie(\n req: Request,\n name: string,\n chunkCount: number,\n ): string | undefined {\n const chunkedCookieArray: string[] = [];\n for (let chunkNumber = 0; chunkNumber < chunkCount; chunkNumber++) {\n const chunk =\n req.cookies[OAuthCookieManager.getCookieChunkName(name, chunkNumber)];\n chunkedCookieArray.push(chunk);\n }\n return chunkedCookieArray.join('');\n }\n\n private removeCookie(res: Response, name: string, origin?: string): void {\n const req = res.req;\n const existingChunkCount = OAuthCookieManager.countExistingCookieChunks(\n req,\n name,\n );\n const chunkedFormatExists = existingChunkCount > 0;\n const nonChunkedFormatExists = !!req.cookies[name];\n\n if (nonChunkedFormatExists) {\n res.cookie(name, '', this.getRemoveCookieOptions(origin));\n }\n if (chunkedFormatExists) {\n this.removeChunkedCookie(res, name, existingChunkCount, {\n origin,\n });\n }\n }\n\n private removeChunkedCookie(\n res: Response,\n name: string,\n chunkCount: number,\n { domain, origin }: { domain?: string; origin?: string } = {},\n ): void {\n for (let chunkNumber = 0; chunkNumber < chunkCount; chunkNumber++) {\n const key = OAuthCookieManager.getCookieChunkName(name, chunkNumber);\n const baseOptions = this.getRemoveCookieOptions(origin);\n const options = domain ? { ...baseOptions, domain } : baseOptions;\n res.cookie(key, '', options);\n }\n }\n\n private splitCookieToChunks(val: string, chunkSize: number): string[] {\n const numChunks = Math.ceil(val.length / chunkSize);\n const chunkedCookieArray: string[] = Array<string>(numChunks);\n\n let offset: number = 0;\n for (let i = 0; i < numChunks; i++) {\n chunkedCookieArray[i] = val.substring(offset, offset + chunkSize);\n offset += chunkSize;\n }\n return chunkedCookieArray;\n }\n\n private static countExistingCookieChunks(req: Request, name: string): number {\n for (let chunkNumber = 0; ; chunkNumber++) {\n const key = OAuthCookieManager.getCookieChunkName(name, chunkNumber);\n const exists = !!req.cookies[key];\n if (!exists) {\n return chunkNumber;\n }\n }\n }\n\n private static getCookieChunkName(name: string, chunkIndex: number): string {\n return `${name}-${chunkIndex}`;\n }\n\n private getRemoveCookieOptions(origin?: string): CookieOptions {\n return {\n maxAge: 0,\n ...this.getConfig(origin),\n };\n }\n}\n"],"names":["durationToMilliseconds"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-auth-node",
3
- "version": "0.6.10-next.0",
3
+ "version": "0.6.10",
4
4
  "backstage": {
5
5
  "role": "node-library",
6
6
  "pluginId": "auth",
@@ -38,15 +38,15 @@
38
38
  "test": "backstage-cli package test"
39
39
  },
40
40
  "dependencies": {
41
- "@backstage/backend-plugin-api": "1.5.1-next.0",
42
- "@backstage/catalog-client": "1.12.1",
43
- "@backstage/catalog-model": "1.7.6",
44
- "@backstage/config": "1.3.6",
45
- "@backstage/errors": "1.2.7",
46
- "@backstage/types": "1.2.2",
41
+ "@backstage/backend-plugin-api": "^1.6.0",
42
+ "@backstage/catalog-client": "^1.12.1",
43
+ "@backstage/catalog-model": "^1.7.6",
44
+ "@backstage/config": "^1.3.6",
45
+ "@backstage/errors": "^1.2.7",
46
+ "@backstage/types": "^1.2.2",
47
47
  "@types/express": "^4.17.6",
48
48
  "@types/passport": "^1.0.3",
49
- "express": "^4.17.1",
49
+ "express": "^4.22.0",
50
50
  "jose": "^5.0.0",
51
51
  "lodash": "^4.17.21",
52
52
  "passport": "^0.7.0",
@@ -55,9 +55,9 @@
55
55
  "zod-validation-error": "^3.4.0"
56
56
  },
57
57
  "devDependencies": {
58
- "@backstage/backend-defaults": "0.14.0-next.0",
59
- "@backstage/backend-test-utils": "1.10.1-next.0",
60
- "@backstage/cli": "0.34.6-next.0",
58
+ "@backstage/backend-defaults": "^0.14.0",
59
+ "@backstage/backend-test-utils": "^1.10.2",
60
+ "@backstage/cli": "^0.35.0",
61
61
  "cookie-parser": "^1.4.6",
62
62
  "express-promise-router": "^4.1.1",
63
63
  "lodash": "^4.17.21",