@backstage/plugin-auth-node 0.7.5-next.1 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
# @backstage/plugin-auth-node
|
|
2
2
|
|
|
3
|
-
## 0.7.5
|
|
3
|
+
## 0.7.5
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- @backstage/config@1.3.9-next.0
|
|
9
|
-
- @backstage/catalog-client@1.16.2-next.1
|
|
10
|
-
- @backstage/backend-plugin-api@1.10.1-next.1
|
|
11
|
-
|
|
12
|
-
## 0.7.5-next.0
|
|
13
|
-
|
|
14
|
-
### Patch Changes
|
|
15
|
-
|
|
16
|
-
- Updated dependencies
|
|
17
|
-
- @backstage/catalog-client@1.16.2-next.0
|
|
18
|
-
- @backstage/backend-plugin-api@1.10.1-next.0
|
|
7
|
+
- fc5e30a: OAuth profile normalization now respects matching negative email verification information supplied by the provider.
|
|
19
8
|
|
|
20
9
|
## 0.7.4
|
|
21
10
|
|
|
@@ -7,13 +7,33 @@ class PassportHelpers {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
}
|
|
9
9
|
static transformProfile = (profile, idToken) => {
|
|
10
|
+
const extendedProfile = profile;
|
|
10
11
|
let email = void 0;
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
let emailWasRejected = false;
|
|
13
|
+
if (Array.isArray(extendedProfile.emails) && extendedProfile.emails.length > 0) {
|
|
14
|
+
const [firstEmail] = extendedProfile.emails;
|
|
13
15
|
email = firstEmail.value;
|
|
16
|
+
emailWasRejected = firstEmail.verified === false;
|
|
14
17
|
} else if (profile.email) {
|
|
15
18
|
email = profile.email;
|
|
16
19
|
}
|
|
20
|
+
const rawProfileValue = extendedProfile._json;
|
|
21
|
+
const rawProfile = typeof rawProfileValue === "object" && rawProfileValue !== null && !Array.isArray(rawProfileValue) ? rawProfileValue : void 0;
|
|
22
|
+
if (email && rawProfile && rawProfile.email === email && rawProfile.email_verified === false) {
|
|
23
|
+
emailWasRejected = true;
|
|
24
|
+
}
|
|
25
|
+
let decoded;
|
|
26
|
+
let decodeError;
|
|
27
|
+
if (idToken) {
|
|
28
|
+
try {
|
|
29
|
+
decoded = jose.decodeJwt(idToken);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
decodeError = error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (emailWasRejected) {
|
|
35
|
+
email = void 0;
|
|
36
|
+
}
|
|
17
37
|
let picture = void 0;
|
|
18
38
|
if (profile.avatarUrl) {
|
|
19
39
|
picture = profile.avatarUrl;
|
|
@@ -24,24 +44,22 @@ class PassportHelpers {
|
|
|
24
44
|
picture = profile.photo;
|
|
25
45
|
}
|
|
26
46
|
let displayName = profile.displayName ?? profile.username ?? profile.id;
|
|
27
|
-
if ((!email || !picture || !displayName) && idToken) {
|
|
28
|
-
|
|
29
|
-
const decoded = jose.decodeJwt(idToken);
|
|
30
|
-
if (!email && decoded.email) {
|
|
31
|
-
email = decoded.email;
|
|
32
|
-
}
|
|
33
|
-
if (!picture && decoded.picture) {
|
|
34
|
-
picture = decoded.picture;
|
|
35
|
-
}
|
|
36
|
-
if (!displayName && decoded.name) {
|
|
37
|
-
displayName = decoded.name;
|
|
38
|
-
}
|
|
39
|
-
} catch (e) {
|
|
47
|
+
if ((!email && !emailWasRejected || !picture || !displayName) && idToken) {
|
|
48
|
+
if (!decoded) {
|
|
40
49
|
throw new errors.ForwardedError(
|
|
41
50
|
`Failed to parse id token and get profile info`,
|
|
42
|
-
|
|
51
|
+
decodeError
|
|
43
52
|
);
|
|
44
53
|
}
|
|
54
|
+
if (!email && !emailWasRejected && decoded.email && decoded.email_verified !== false) {
|
|
55
|
+
email = decoded.email;
|
|
56
|
+
}
|
|
57
|
+
if (!picture && decoded.picture) {
|
|
58
|
+
picture = decoded.picture;
|
|
59
|
+
}
|
|
60
|
+
if (!displayName && decoded.name) {
|
|
61
|
+
displayName = decoded.name;
|
|
62
|
+
}
|
|
45
63
|
}
|
|
46
64
|
return {
|
|
47
65
|
email,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PassportHelpers.cjs.js","sources":["../../src/passport/PassportHelpers.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 { Request } from 'express';\nimport { decodeJwt } from 'jose';\nimport { Strategy } from 'passport';\nimport { PassportProfile } from './types';\nimport { ProfileInfo } from '../types';\nimport { ForwardedError } from '@backstage/errors';\n\n// Re-declared here to avoid direct dependency on passport-oauth2\n/** @internal */\ninterface InternalOAuthError extends Error {\n oauthError?: {\n data?: string;\n };\n}\n\n/** @public */\nexport class PassportHelpers {\n private constructor() {}\n\n static transformProfile = (\n profile: PassportProfile,\n idToken?: string,\n ): ProfileInfo => {\n let email: string | undefined = undefined;\n if (profile.emails && profile.emails.length > 0) {\n const [firstEmail] = profile.emails;\n email = firstEmail.value;\n } else if (profile.email) {\n // This is the case for Atlassian\n email = profile.email;\n }\n\n let picture: string | undefined = undefined;\n if (profile.avatarUrl) {\n picture = profile.avatarUrl;\n } else if (profile.photos && profile.photos.length > 0) {\n const [firstPhoto] = profile.photos;\n picture = firstPhoto.value;\n } else if (profile.photo) {\n // This is the case for Atlassian\n picture = profile.photo;\n }\n\n let displayName: string | undefined =\n profile.displayName ?? profile.username ?? profile.id;\n\n if ((!email || !picture || !displayName) && idToken) {\n try {\n const decoded = decodeJwt(idToken) as {\n email?: string;\n name?: string;\n picture?: string;\n };\n if (!email && decoded.email) {\n email = decoded.email;\n }\n if (!picture && decoded.picture) {\n picture = decoded.picture;\n }\n if (!displayName && decoded.name) {\n displayName = decoded.name;\n }\n } catch (e) {\n throw new ForwardedError(\n `Failed to parse id token and get profile info`,\n e,\n );\n }\n }\n\n return {\n email,\n picture,\n displayName,\n };\n };\n\n static async executeRedirectStrategy(\n req: Request,\n providerStrategy: Strategy,\n options: Record<string, string>,\n ): Promise<{\n /**\n * URL to redirect to\n */\n url: string;\n /**\n * Status code to use for the redirect\n */\n status?: number;\n }> {\n return new Promise((resolve, reject) => {\n const strategy = Object.create(providerStrategy);\n strategy.error = (error: Error) => {\n reject(new Error(`Authentication failed, ${error.message ?? ''}`));\n };\n strategy.redirect = (url: string, status?: number) => {\n resolve({ url, status: status ?? undefined });\n };\n\n strategy.authenticate(req, { ...options });\n });\n }\n\n static async executeFrameHandlerStrategy<TResult, TPrivateInfo = never>(\n req: Request,\n providerStrategy: Strategy,\n options?: Record<string, string>,\n ): Promise<{ result: TResult; privateInfo: TPrivateInfo }> {\n return new Promise((resolve, reject) => {\n const strategy = Object.create(providerStrategy);\n strategy.success = (result: any, privateInfo: any) => {\n resolve({ result, privateInfo });\n };\n strategy.fail = (\n info: { type: 'success' | 'error'; message?: string },\n // _status: number,\n ) => {\n reject(new Error(`Authentication rejected, ${info.message ?? ''}`));\n };\n strategy.error = (error: InternalOAuthError) => {\n let message = `Authentication failed, ${error.message}`;\n\n if (error.oauthError?.data) {\n try {\n const errorData = JSON.parse(error.oauthError.data);\n\n if (errorData.message) {\n message += ` - ${errorData.message}`;\n }\n } catch (parseError) {\n message += ` - ${error.oauthError}`;\n }\n }\n\n reject(new Error(message));\n };\n strategy.redirect = () => {\n reject(new Error('Unexpected redirect'));\n };\n strategy.authenticate(req, { ...(options ?? {}) });\n });\n }\n\n static async executeRefreshTokenStrategy(\n providerStrategy: Strategy,\n refreshToken: string,\n scope: string,\n ): Promise<{\n /**\n * An access token issued for the signed in user.\n */\n accessToken: string;\n /**\n * Optionally, the server can issue a new Refresh Token for the user\n */\n refreshToken?: string;\n params: any;\n }> {\n return new Promise((resolve, reject) => {\n const anyStrategy = providerStrategy as any;\n const OAuth2 = anyStrategy._oauth2.constructor;\n const oauth2 = new OAuth2(\n anyStrategy._oauth2._clientId,\n anyStrategy._oauth2._clientSecret,\n anyStrategy._oauth2._baseSite,\n anyStrategy._oauth2._authorizeUrl,\n anyStrategy._refreshURL || anyStrategy._oauth2._accessTokenUrl,\n anyStrategy._oauth2._customHeaders,\n );\n\n oauth2.getOAuthAccessToken(\n refreshToken,\n {\n scope,\n grant_type: 'refresh_token',\n },\n (\n err: Error | null,\n accessToken: string,\n newRefreshToken: string,\n params: any,\n ) => {\n if (err) {\n reject(new ForwardedError(`Failed to refresh access token`, err));\n }\n if (!accessToken) {\n reject(\n new Error(\n `Failed to refresh access token, no access token received`,\n ),\n );\n }\n\n resolve({\n accessToken,\n refreshToken: newRefreshToken,\n params,\n });\n },\n );\n });\n }\n\n static async executeFetchUserProfileStrategy(\n providerStrategy: Strategy,\n accessToken: string,\n ): Promise<PassportProfile> {\n return new Promise((resolve, reject) => {\n const anyStrategy = providerStrategy as unknown as {\n userProfile(accessToken: string, callback: Function): void;\n };\n anyStrategy.userProfile(\n accessToken,\n (error: Error, rawProfile: PassportProfile) => {\n if (error) {\n reject(error);\n } else {\n resolve(rawProfile);\n }\n },\n );\n });\n }\n}\n"],"names":["decodeJwt","ForwardedError"],"mappings":";;;;;AAgCO,MAAM,eAAA,CAAgB;AAAA,EACnB,WAAA,GAAc;AAAA,EAAC;AAAA,EAEvB,OAAO,gBAAA,GAAmB,CACxB,OAAA,EACA,OAAA,KACgB;AAChB,IAAA,IAAI,KAAA,GAA4B,MAAA;AAChC,IAAA,IAAI,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,EAAG;AAC/C,MAAA,MAAM,CAAC,UAAU,CAAA,GAAI,OAAA,CAAQ,MAAA;AAC7B,MAAA,KAAA,GAAQ,UAAA,CAAW,KAAA;AAAA,IACrB,CAAA,MAAA,IAAW,QAAQ,KAAA,EAAO;AAExB,MAAA,KAAA,GAAQ,OAAA,CAAQ,KAAA;AAAA,IAClB;AAEA,IAAA,IAAI,OAAA,GAA8B,MAAA;AAClC,IAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,MAAA,OAAA,GAAU,OAAA,CAAQ,SAAA;AAAA,IACpB,WAAW,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,EAAG;AACtD,MAAA,MAAM,CAAC,UAAU,CAAA,GAAI,OAAA,CAAQ,MAAA;AAC7B,MAAA,OAAA,GAAU,UAAA,CAAW,KAAA;AAAA,IACvB,CAAA,MAAA,IAAW,QAAQ,KAAA,EAAO;AAExB,MAAA,OAAA,GAAU,OAAA,CAAQ,KAAA;AAAA,IACpB;AAEA,IAAA,IAAI,WAAA,GACF,OAAA,CAAQ,WAAA,IAAe,OAAA,CAAQ,YAAY,OAAA,CAAQ,EAAA;AAErD,IAAA,IAAA,CAAK,CAAC,KAAA,IAAS,CAAC,OAAA,IAAW,CAAC,gBAAgB,OAAA,EAAS;AACnD,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAUA,eAAU,OAAO,CAAA;AAKjC,QAAA,IAAI,CAAC,KAAA,IAAS,OAAA,CAAQ,KAAA,EAAO;AAC3B,UAAA,KAAA,GAAQ,OAAA,CAAQ,KAAA;AAAA,QAClB;AACA,QAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,OAAA,EAAS;AAC/B,UAAA,OAAA,GAAU,OAAA,CAAQ,OAAA;AAAA,QACpB;AACA,QAAA,IAAI,CAAC,WAAA,IAAe,OAAA,CAAQ,IAAA,EAAM;AAChC,UAAA,WAAA,GAAc,OAAA,CAAQ,IAAA;AAAA,QACxB;AAAA,MACF,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,IAAIC,qBAAA;AAAA,UACR,CAAA,6CAAA,CAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAA;AAAA,EAEA,aAAa,uBAAA,CACX,GAAA,EACA,gBAAA,EACA,OAAA,EAUC;AACD,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,gBAAgB,CAAA;AAC/C,MAAA,QAAA,CAAS,KAAA,GAAQ,CAAC,KAAA,KAAiB;AACjC,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,MAAM,OAAA,IAAW,EAAE,EAAE,CAAC,CAAA;AAAA,MACnE,CAAA;AACA,MAAA,QAAA,CAAS,QAAA,GAAW,CAAC,GAAA,EAAa,MAAA,KAAoB;AACpD,QAAA,OAAA,CAAQ,EAAE,GAAA,EAAK,MAAA,EAAQ,MAAA,IAAU,QAAW,CAAA;AAAA,MAC9C,CAAA;AAEA,MAAA,QAAA,CAAS,YAAA,CAAa,GAAA,EAAK,EAAE,GAAG,SAAS,CAAA;AAAA,IAC3C,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,aAAa,2BAAA,CACX,GAAA,EACA,gBAAA,EACA,OAAA,EACyD;AACzD,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,gBAAgB,CAAA;AAC/C,MAAA,QAAA,CAAS,OAAA,GAAU,CAAC,MAAA,EAAa,WAAA,KAAqB;AACpD,QAAA,OAAA,CAAQ,EAAE,MAAA,EAAQ,WAAA,EAAa,CAAA;AAAA,MACjC,CAAA;AACA,MAAA,QAAA,CAAS,IAAA,GAAO,CACd,IAAA,KAEG;AACH,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,KAAK,OAAA,IAAW,EAAE,EAAE,CAAC,CAAA;AAAA,MACpE,CAAA;AACA,MAAA,QAAA,CAAS,KAAA,GAAQ,CAAC,KAAA,KAA8B;AAC9C,QAAA,IAAI,OAAA,GAAU,CAAA,uBAAA,EAA0B,KAAA,CAAM,OAAO,CAAA,CAAA;AAErD,QAAA,IAAI,KAAA,CAAM,YAAY,IAAA,EAAM;AAC1B,UAAA,IAAI;AACF,YAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,WAAW,IAAI,CAAA;AAElD,YAAA,IAAI,UAAU,OAAA,EAAS;AACrB,cAAA,OAAA,IAAW,CAAA,GAAA,EAAM,UAAU,OAAO,CAAA,CAAA;AAAA,YACpC;AAAA,UACF,SAAS,UAAA,EAAY;AACnB,YAAA,OAAA,IAAW,CAAA,GAAA,EAAM,MAAM,UAAU,CAAA,CAAA;AAAA,UACnC;AAAA,QACF;AAEA,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAC,CAAA;AAAA,MAC3B,CAAA;AACA,MAAA,QAAA,CAAS,WAAW,MAAM;AACxB,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,qBAAqB,CAAC,CAAA;AAAA,MACzC,CAAA;AACA,MAAA,QAAA,CAAS,aAAa,GAAA,EAAK,EAAE,GAAI,OAAA,IAAW,IAAK,CAAA;AAAA,IACnD,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,aAAa,2BAAA,CACX,gBAAA,EACA,YAAA,EACA,KAAA,EAWC;AACD,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,WAAA,GAAc,gBAAA;AACpB,MAAA,MAAM,MAAA,GAAS,YAAY,OAAA,CAAQ,WAAA;AACnC,MAAA,MAAM,SAAS,IAAI,MAAA;AAAA,QACjB,YAAY,OAAA,CAAQ,SAAA;AAAA,QACpB,YAAY,OAAA,CAAQ,aAAA;AAAA,QACpB,YAAY,OAAA,CAAQ,SAAA;AAAA,QACpB,YAAY,OAAA,CAAQ,aAAA;AAAA,QACpB,WAAA,CAAY,WAAA,IAAe,WAAA,CAAY,OAAA,CAAQ,eAAA;AAAA,QAC/C,YAAY,OAAA,CAAQ;AAAA,OACtB;AAEA,MAAA,MAAA,CAAO,mBAAA;AAAA,QACL,YAAA;AAAA,QACA;AAAA,UACE,KAAA;AAAA,UACA,UAAA,EAAY;AAAA,SACd;AAAA,QACA,CACE,GAAA,EACA,WAAA,EACA,eAAA,EACA,MAAA,KACG;AACH,UAAA,IAAI,GAAA,EAAK;AACP,YAAA,MAAA,CAAO,IAAIA,qBAAA,CAAe,CAAA,8BAAA,CAAA,EAAkC,GAAG,CAAC,CAAA;AAAA,UAClE;AACA,UAAA,IAAI,CAAC,WAAA,EAAa;AAChB,YAAA,MAAA;AAAA,cACE,IAAI,KAAA;AAAA,gBACF,CAAA,wDAAA;AAAA;AACF,aACF;AAAA,UACF;AAEA,UAAA,OAAA,CAAQ;AAAA,YACN,WAAA;AAAA,YACA,YAAA,EAAc,eAAA;AAAA,YACd;AAAA,WACD,CAAA;AAAA,QACH;AAAA,OACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,aAAa,+BAAA,CACX,gBAAA,EACA,WAAA,EAC0B;AAC1B,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,WAAA,GAAc,gBAAA;AAGpB,MAAA,WAAA,CAAY,WAAA;AAAA,QACV,WAAA;AAAA,QACA,CAAC,OAAc,UAAA,KAAgC;AAC7C,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,MAAA,CAAO,KAAK,CAAA;AAAA,UACd,CAAA,MAAO;AACL,YAAA,OAAA,CAAQ,UAAU,CAAA;AAAA,UACpB;AAAA,QACF;AAAA,OACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"PassportHelpers.cjs.js","sources":["../../src/passport/PassportHelpers.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 { Request } from 'express';\nimport { decodeJwt } from 'jose';\nimport { Strategy } from 'passport';\nimport { PassportProfile } from './types';\nimport { ProfileInfo } from '../types';\nimport { ForwardedError } from '@backstage/errors';\n\n// Re-declared here to avoid direct dependency on passport-oauth2\n/** @internal */\ninterface InternalOAuthError extends Error {\n oauthError?: {\n data?: string;\n };\n}\n\n/** @public */\nexport class PassportHelpers {\n private constructor() {}\n\n static transformProfile = (\n profile: PassportProfile,\n idToken?: string,\n ): ProfileInfo => {\n const extendedProfile = profile as PassportProfile & {\n emails?: Array<{\n value: string;\n type?: string;\n verified?: unknown;\n }>;\n _json?: unknown;\n };\n\n let email: string | undefined = undefined;\n let emailWasRejected = false;\n\n if (\n Array.isArray(extendedProfile.emails) &&\n extendedProfile.emails.length > 0\n ) {\n const [firstEmail] = extendedProfile.emails;\n email = firstEmail.value;\n emailWasRejected = firstEmail.verified === false;\n } else if (profile.email) {\n // This is the case for Atlassian\n email = profile.email;\n }\n\n const rawProfileValue = extendedProfile._json;\n const rawProfile =\n typeof rawProfileValue === 'object' &&\n rawProfileValue !== null &&\n !Array.isArray(rawProfileValue)\n ? (rawProfileValue as Record<string, unknown>)\n : undefined;\n if (\n email &&\n rawProfile &&\n rawProfile.email === email &&\n rawProfile.email_verified === false\n ) {\n emailWasRejected = true;\n }\n\n let decoded:\n | {\n email?: string;\n email_verified?: unknown;\n name?: string;\n picture?: string;\n }\n | undefined;\n let decodeError: unknown;\n if (idToken) {\n try {\n decoded = decodeJwt(idToken);\n } catch (error) {\n decodeError = error;\n }\n }\n\n if (emailWasRejected) {\n email = undefined;\n }\n\n let picture: string | undefined = undefined;\n if (profile.avatarUrl) {\n picture = profile.avatarUrl;\n } else if (profile.photos && profile.photos.length > 0) {\n const [firstPhoto] = profile.photos;\n picture = firstPhoto.value;\n } else if (profile.photo) {\n // This is the case for Atlassian\n picture = profile.photo;\n }\n\n let displayName: string | undefined =\n profile.displayName ?? profile.username ?? profile.id;\n\n if (\n ((!email && !emailWasRejected) || !picture || !displayName) &&\n idToken\n ) {\n if (!decoded) {\n throw new ForwardedError(\n `Failed to parse id token and get profile info`,\n decodeError,\n );\n }\n\n if (\n !email &&\n !emailWasRejected &&\n decoded.email &&\n decoded.email_verified !== false\n ) {\n email = decoded.email;\n }\n if (!picture && decoded.picture) {\n picture = decoded.picture;\n }\n if (!displayName && decoded.name) {\n displayName = decoded.name;\n }\n }\n\n return {\n email,\n picture,\n displayName,\n };\n };\n\n static async executeRedirectStrategy(\n req: Request,\n providerStrategy: Strategy,\n options: Record<string, string>,\n ): Promise<{\n /**\n * URL to redirect to\n */\n url: string;\n /**\n * Status code to use for the redirect\n */\n status?: number;\n }> {\n return new Promise((resolve, reject) => {\n const strategy = Object.create(providerStrategy);\n strategy.error = (error: Error) => {\n reject(new Error(`Authentication failed, ${error.message ?? ''}`));\n };\n strategy.redirect = (url: string, status?: number) => {\n resolve({ url, status: status ?? undefined });\n };\n\n strategy.authenticate(req, { ...options });\n });\n }\n\n static async executeFrameHandlerStrategy<TResult, TPrivateInfo = never>(\n req: Request,\n providerStrategy: Strategy,\n options?: Record<string, string>,\n ): Promise<{ result: TResult; privateInfo: TPrivateInfo }> {\n return new Promise((resolve, reject) => {\n const strategy = Object.create(providerStrategy);\n strategy.success = (result: any, privateInfo: any) => {\n resolve({ result, privateInfo });\n };\n strategy.fail = (\n info: { type: 'success' | 'error'; message?: string },\n // _status: number,\n ) => {\n reject(new Error(`Authentication rejected, ${info.message ?? ''}`));\n };\n strategy.error = (error: InternalOAuthError) => {\n let message = `Authentication failed, ${error.message}`;\n\n if (error.oauthError?.data) {\n try {\n const errorData = JSON.parse(error.oauthError.data);\n\n if (errorData.message) {\n message += ` - ${errorData.message}`;\n }\n } catch (parseError) {\n message += ` - ${error.oauthError}`;\n }\n }\n\n reject(new Error(message));\n };\n strategy.redirect = () => {\n reject(new Error('Unexpected redirect'));\n };\n strategy.authenticate(req, { ...(options ?? {}) });\n });\n }\n\n static async executeRefreshTokenStrategy(\n providerStrategy: Strategy,\n refreshToken: string,\n scope: string,\n ): Promise<{\n /**\n * An access token issued for the signed in user.\n */\n accessToken: string;\n /**\n * Optionally, the server can issue a new Refresh Token for the user\n */\n refreshToken?: string;\n params: any;\n }> {\n return new Promise((resolve, reject) => {\n const anyStrategy = providerStrategy as any;\n const OAuth2 = anyStrategy._oauth2.constructor;\n const oauth2 = new OAuth2(\n anyStrategy._oauth2._clientId,\n anyStrategy._oauth2._clientSecret,\n anyStrategy._oauth2._baseSite,\n anyStrategy._oauth2._authorizeUrl,\n anyStrategy._refreshURL || anyStrategy._oauth2._accessTokenUrl,\n anyStrategy._oauth2._customHeaders,\n );\n\n oauth2.getOAuthAccessToken(\n refreshToken,\n {\n scope,\n grant_type: 'refresh_token',\n },\n (\n err: Error | null,\n accessToken: string,\n newRefreshToken: string,\n params: any,\n ) => {\n if (err) {\n reject(new ForwardedError(`Failed to refresh access token`, err));\n }\n if (!accessToken) {\n reject(\n new Error(\n `Failed to refresh access token, no access token received`,\n ),\n );\n }\n\n resolve({\n accessToken,\n refreshToken: newRefreshToken,\n params,\n });\n },\n );\n });\n }\n\n static async executeFetchUserProfileStrategy(\n providerStrategy: Strategy,\n accessToken: string,\n ): Promise<PassportProfile> {\n return new Promise((resolve, reject) => {\n const anyStrategy = providerStrategy as unknown as {\n userProfile(accessToken: string, callback: Function): void;\n };\n anyStrategy.userProfile(\n accessToken,\n (error: Error, rawProfile: PassportProfile) => {\n if (error) {\n reject(error);\n } else {\n resolve(rawProfile);\n }\n },\n );\n });\n }\n}\n"],"names":["decodeJwt","ForwardedError"],"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.7.5
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"backstage": {
|
|
5
5
|
"role": "node-library",
|
|
6
6
|
"pluginId": "auth",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"test": "backstage-cli package test"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@backstage/backend-plugin-api": "1.10.
|
|
42
|
-
"@backstage/catalog-client": "1.16.
|
|
43
|
-
"@backstage/catalog-model": "1.10.0",
|
|
44
|
-
"@backstage/config": "1.3.
|
|
45
|
-
"@backstage/errors": "1.3.1",
|
|
46
|
-
"@backstage/types": "1.2.2",
|
|
41
|
+
"@backstage/backend-plugin-api": "^1.10.0",
|
|
42
|
+
"@backstage/catalog-client": "^1.16.1",
|
|
43
|
+
"@backstage/catalog-model": "^1.10.0",
|
|
44
|
+
"@backstage/config": "^1.3.8",
|
|
45
|
+
"@backstage/errors": "^1.3.1",
|
|
46
|
+
"@backstage/types": "^1.2.2",
|
|
47
47
|
"@types/express": "^4.17.6",
|
|
48
48
|
"@types/passport": "^1.0.3",
|
|
49
49
|
"express": "^4.22.0",
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
"zod-validation-error": "^5.0.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@backstage/backend-defaults": "0.17.
|
|
59
|
-
"@backstage/backend-test-utils": "1.11.
|
|
60
|
-
"@backstage/cli": "0.36.
|
|
58
|
+
"@backstage/backend-defaults": "^0.17.8",
|
|
59
|
+
"@backstage/backend-test-utils": "^1.11.6",
|
|
60
|
+
"@backstage/cli": "^0.36.5",
|
|
61
61
|
"cookie-parser": "^1.4.6",
|
|
62
62
|
"express-promise-router": "^4.1.1",
|
|
63
63
|
"msw": "^2.0.0",
|