@backstage/plugin-auth-backend 0.24.5-next.2 → 0.25.0-next.0
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 +51 -0
- package/config.d.ts +3 -59
- package/dist/authPlugin.cjs.js +4 -8
- package/dist/authPlugin.cjs.js.map +1 -1
- package/dist/database/AuthDatabase.cjs.js +0 -16
- package/dist/database/AuthDatabase.cjs.js.map +1 -1
- package/dist/index.cjs.js +0 -26
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -850
- package/dist/lib/catalog/CatalogIdentityClient.cjs.js +11 -20
- package/dist/lib/catalog/CatalogIdentityClient.cjs.js.map +1 -1
- package/dist/lib/resolvers/CatalogAuthResolverContext.cjs.js +14 -17
- package/dist/lib/resolvers/CatalogAuthResolverContext.cjs.js.map +1 -1
- package/dist/providers/router.cjs.js +2 -9
- package/dist/providers/router.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +5 -16
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +11 -54
- package/dist/lib/flow/authFlowHelpers.cjs.js +0 -43
- package/dist/lib/flow/authFlowHelpers.cjs.js.map +0 -1
- package/dist/lib/legacy/adaptLegacyOAuthHandler.cjs.js +0 -20
- package/dist/lib/legacy/adaptLegacyOAuthHandler.cjs.js.map +0 -1
- package/dist/lib/legacy/adaptLegacyOAuthSignInResolver.cjs.js +0 -24
- package/dist/lib/legacy/adaptLegacyOAuthSignInResolver.cjs.js.map +0 -1
- package/dist/lib/legacy/adaptOAuthSignInResolverToLegacy.cjs.js +0 -29
- package/dist/lib/legacy/adaptOAuthSignInResolverToLegacy.cjs.js.map +0 -1
- package/dist/lib/oauth/OAuthAdapter.cjs.js +0 -220
- package/dist/lib/oauth/OAuthAdapter.cjs.js.map +0 -1
- package/dist/lib/oauth/OAuthEnvironmentHandler.cjs.js +0 -8
- package/dist/lib/oauth/OAuthEnvironmentHandler.cjs.js.map +0 -1
- package/dist/lib/oauth/helpers.cjs.js +0 -40
- package/dist/lib/oauth/helpers.cjs.js.map +0 -1
- package/dist/lib/passport/PassportStrategyHelper.cjs.js +0 -49
- package/dist/lib/passport/PassportStrategyHelper.cjs.js.map +0 -1
- package/dist/providers/atlassian/provider.cjs.js +0 -20
- package/dist/providers/atlassian/provider.cjs.js.map +0 -1
- package/dist/providers/auth0/provider.cjs.js +0 -20
- package/dist/providers/auth0/provider.cjs.js.map +0 -1
- package/dist/providers/aws-alb/provider.cjs.js +0 -18
- package/dist/providers/aws-alb/provider.cjs.js.map +0 -1
- package/dist/providers/azure-easyauth/provider.cjs.js +0 -18
- package/dist/providers/azure-easyauth/provider.cjs.js.map +0 -1
- package/dist/providers/bitbucket/provider.cjs.js +0 -25
- package/dist/providers/bitbucket/provider.cjs.js.map +0 -1
- package/dist/providers/bitbucketServer/provider.cjs.js +0 -46
- package/dist/providers/bitbucketServer/provider.cjs.js.map +0 -1
- package/dist/providers/cloudflare-access/provider.cjs.js +0 -22
- package/dist/providers/cloudflare-access/provider.cjs.js.map +0 -1
- package/dist/providers/createAuthProviderIntegration.cjs.js +0 -11
- package/dist/providers/createAuthProviderIntegration.cjs.js.map +0 -1
- package/dist/providers/gcp-iap/provider.cjs.js +0 -18
- package/dist/providers/gcp-iap/provider.cjs.js.map +0 -1
- package/dist/providers/github/provider.cjs.js +0 -61
- package/dist/providers/github/provider.cjs.js.map +0 -1
- package/dist/providers/gitlab/provider.cjs.js +0 -20
- package/dist/providers/gitlab/provider.cjs.js.map +0 -1
- package/dist/providers/google/provider.cjs.js +0 -26
- package/dist/providers/google/provider.cjs.js.map +0 -1
- package/dist/providers/microsoft/provider.cjs.js +0 -27
- package/dist/providers/microsoft/provider.cjs.js.map +0 -1
- package/dist/providers/oauth2/provider.cjs.js +0 -20
- package/dist/providers/oauth2/provider.cjs.js.map +0 -1
- package/dist/providers/oauth2-proxy/provider.cjs.js +0 -18
- package/dist/providers/oauth2-proxy/provider.cjs.js.map +0 -1
- package/dist/providers/oidc/provider.cjs.js +0 -37
- package/dist/providers/oidc/provider.cjs.js.map +0 -1
- package/dist/providers/okta/provider.cjs.js +0 -47
- package/dist/providers/okta/provider.cjs.js.map +0 -1
- package/dist/providers/onelogin/provider.cjs.js +0 -20
- package/dist/providers/onelogin/provider.cjs.js.map +0 -1
- package/dist/providers/prepareBackstageIdentityResponse.cjs.js +0 -8
- package/dist/providers/prepareBackstageIdentityResponse.cjs.js.map +0 -1
- package/dist/providers/providers.cjs.js +0 -62
- package/dist/providers/providers.cjs.js.map +0 -1
- package/dist/providers/resolvers.cjs.js +0 -27
- package/dist/providers/resolvers.cjs.js.map +0 -1
- package/dist/providers/saml/provider.cjs.js +0 -121
- package/dist/providers/saml/provider.cjs.js.map +0 -1
|
@@ -2,20 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
var errors = require('@backstage/errors');
|
|
4
4
|
var catalogModel = require('@backstage/catalog-model');
|
|
5
|
-
var backendCommon = require('@backstage/backend-common');
|
|
6
5
|
|
|
7
6
|
class CatalogIdentityClient {
|
|
8
|
-
|
|
7
|
+
catalog;
|
|
9
8
|
auth;
|
|
10
9
|
constructor(options) {
|
|
11
|
-
this.
|
|
12
|
-
|
|
13
|
-
auth: options.auth,
|
|
14
|
-
httpAuth: options.httpAuth,
|
|
15
|
-
discovery: options.discovery,
|
|
16
|
-
tokenManager: options.tokenManager
|
|
17
|
-
});
|
|
18
|
-
this.auth = auth;
|
|
10
|
+
this.catalog = options.catalog;
|
|
11
|
+
this.auth = options.auth;
|
|
19
12
|
}
|
|
20
13
|
/**
|
|
21
14
|
* Looks up a single user using a query.
|
|
@@ -29,11 +22,10 @@ class CatalogIdentityClient {
|
|
|
29
22
|
for (const [key, value] of Object.entries(query.annotations)) {
|
|
30
23
|
filter[`metadata.annotations.${key}`] = value;
|
|
31
24
|
}
|
|
32
|
-
const {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const { items } = await this.catalogApi.getEntities({ filter }, { token });
|
|
25
|
+
const { items } = await this.catalog.getEntities(
|
|
26
|
+
{ filter },
|
|
27
|
+
{ credentials: await this.auth.getOwnServiceCredentials() }
|
|
28
|
+
);
|
|
37
29
|
if (items.length !== 1) {
|
|
38
30
|
if (items.length > 1) {
|
|
39
31
|
throw new errors.ConflictError("User lookup resulted in multiple matches");
|
|
@@ -69,11 +61,10 @@ class CatalogIdentityClient {
|
|
|
69
61
|
"metadata.namespace": ref.namespace,
|
|
70
62
|
"metadata.name": ref.name
|
|
71
63
|
}));
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const entities = await this.catalogApi.getEntities({ filter }, { token }).then((r) => r.items);
|
|
64
|
+
const entities = await this.catalog.getEntities(
|
|
65
|
+
{ filter },
|
|
66
|
+
{ credentials: await this.auth.getOwnServiceCredentials() }
|
|
67
|
+
).then((r) => r.items);
|
|
77
68
|
if (entityRefs.length !== entities.length) {
|
|
78
69
|
const foundEntityNames = entities.map(catalogModel.stringifyEntityRef);
|
|
79
70
|
const missingEntityNames = resolvedEntityRefs.map(catalogModel.stringifyEntityRef).filter((s) => !foundEntityNames.includes(s));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogIdentityClient.cjs.js","sources":["../../../src/lib/catalog/CatalogIdentityClient.ts"],"sourcesContent":["/*\n * Copyright 2020 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 {
|
|
1
|
+
{"version":3,"file":"CatalogIdentityClient.cjs.js","sources":["../../../src/lib/catalog/CatalogIdentityClient.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { AuthService, LoggerService } from '@backstage/backend-plugin-api';\nimport { ConflictError, NotFoundError } from '@backstage/errors';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\nimport {\n CompoundEntityRef,\n parseEntityRef,\n RELATION_MEMBER_OF,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\n\n/**\n * A catalog client tailored for reading out identity data from the catalog.\n */\nexport class CatalogIdentityClient {\n private readonly catalog: CatalogService;\n private readonly auth: AuthService;\n\n constructor(options: { catalog: CatalogService; auth: AuthService }) {\n this.catalog = options.catalog;\n this.auth = options.auth;\n }\n\n /**\n * Looks up a single user using a query.\n *\n * Throws a NotFoundError or ConflictError if 0 or multiple users are found.\n */\n async findUser(query: {\n annotations: Record<string, string>;\n }): Promise<UserEntity> {\n const filter: Record<string, string> = {\n kind: 'user',\n };\n for (const [key, value] of Object.entries(query.annotations)) {\n filter[`metadata.annotations.${key}`] = value;\n }\n\n const { items } = await this.catalog.getEntities(\n { filter },\n { credentials: await this.auth.getOwnServiceCredentials() },\n );\n\n if (items.length !== 1) {\n if (items.length > 1) {\n throw new ConflictError('User lookup resulted in multiple matches');\n } else {\n throw new NotFoundError('User not found');\n }\n }\n\n return items[0] as UserEntity;\n }\n\n /**\n * Resolve additional entity claims from the catalog, using the passed-in entity names. Designed\n * to be used within a `signInResolver` where additional entity claims might be provided, but\n * group membership and transient group membership lean on imported catalog relations.\n *\n * Returns a superset of the entity names that can be passed directly to `issueToken` as `ent`.\n */\n async resolveCatalogMembership(query: {\n entityRefs: string[];\n logger?: LoggerService;\n }): Promise<string[]> {\n const { entityRefs, logger } = query;\n const resolvedEntityRefs = entityRefs\n .map((ref: string) => {\n try {\n const parsedRef = parseEntityRef(ref.toLocaleLowerCase('en-US'), {\n defaultKind: 'user',\n defaultNamespace: 'default',\n });\n return parsedRef;\n } catch {\n logger?.warn(`Failed to parse entityRef from ${ref}, ignoring`);\n return null;\n }\n })\n .filter((ref): ref is CompoundEntityRef => ref !== null);\n\n const filter = resolvedEntityRefs.map(ref => ({\n kind: ref.kind,\n 'metadata.namespace': ref.namespace,\n 'metadata.name': ref.name,\n }));\n\n const entities = await this.catalog\n .getEntities(\n { filter },\n { credentials: await this.auth.getOwnServiceCredentials() },\n )\n .then(r => r.items);\n\n if (entityRefs.length !== entities.length) {\n const foundEntityNames = entities.map(stringifyEntityRef);\n const missingEntityNames = resolvedEntityRefs\n .map(stringifyEntityRef)\n .filter(s => !foundEntityNames.includes(s));\n logger?.debug(`Entities not found for refs ${missingEntityNames.join()}`);\n }\n\n const memberOf = entities.flatMap(\n e =>\n e!.relations\n ?.filter(r => r.type === RELATION_MEMBER_OF)\n .map(r => r.targetRef) ?? [],\n );\n\n const newEntityRefs = [\n ...new Set(resolvedEntityRefs.map(stringifyEntityRef).concat(memberOf)),\n ];\n\n logger?.debug(`Found catalog membership: ${newEntityRefs.join()}`);\n return newEntityRefs;\n }\n}\n"],"names":["ConflictError","NotFoundError","parseEntityRef","stringifyEntityRef","RELATION_MEMBER_OF"],"mappings":"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"}
|
|
@@ -11,27 +11,24 @@ function getDefaultOwnershipEntityRefs(entity) {
|
|
|
11
11
|
return Array.from(/* @__PURE__ */ new Set([catalogModel.stringifyEntityRef(entity), ...membershipRefs]));
|
|
12
12
|
}
|
|
13
13
|
class CatalogAuthResolverContext {
|
|
14
|
-
constructor(logger, tokenIssuer, catalogIdentityClient,
|
|
14
|
+
constructor(logger, tokenIssuer, catalogIdentityClient, catalog, auth, ownershipResolver) {
|
|
15
15
|
this.logger = logger;
|
|
16
16
|
this.tokenIssuer = tokenIssuer;
|
|
17
17
|
this.catalogIdentityClient = catalogIdentityClient;
|
|
18
|
-
this.
|
|
18
|
+
this.catalog = catalog;
|
|
19
19
|
this.auth = auth;
|
|
20
20
|
this.ownershipResolver = ownershipResolver;
|
|
21
21
|
}
|
|
22
22
|
static create(options) {
|
|
23
23
|
const catalogIdentityClient = new CatalogIdentityClient.CatalogIdentityClient({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
discovery: options.discovery,
|
|
27
|
-
auth: options.auth,
|
|
28
|
-
httpAuth: options.httpAuth
|
|
24
|
+
catalog: options.catalog,
|
|
25
|
+
auth: options.auth
|
|
29
26
|
});
|
|
30
27
|
return new CatalogAuthResolverContext(
|
|
31
28
|
options.logger,
|
|
32
29
|
options.tokenIssuer,
|
|
33
30
|
catalogIdentityClient,
|
|
34
|
-
options.
|
|
31
|
+
options.catalog,
|
|
35
32
|
options.auth,
|
|
36
33
|
options.ownershipResolver
|
|
37
34
|
);
|
|
@@ -42,16 +39,14 @@ class CatalogAuthResolverContext {
|
|
|
42
39
|
}
|
|
43
40
|
async findCatalogUser(query) {
|
|
44
41
|
let result = void 0;
|
|
45
|
-
const { token } = await this.auth.getPluginRequestToken({
|
|
46
|
-
onBehalfOf: await this.auth.getOwnServiceCredentials(),
|
|
47
|
-
targetPluginId: "catalog"
|
|
48
|
-
});
|
|
49
42
|
if ("entityRef" in query) {
|
|
50
43
|
const entityRef = catalogModel.parseEntityRef(query.entityRef, {
|
|
51
44
|
defaultKind: "User",
|
|
52
45
|
defaultNamespace: catalogModel.DEFAULT_NAMESPACE
|
|
53
46
|
});
|
|
54
|
-
result = await this.
|
|
47
|
+
result = await this.catalog.getEntityByRef(entityRef, {
|
|
48
|
+
credentials: await this.auth.getOwnServiceCredentials()
|
|
49
|
+
});
|
|
55
50
|
} else if ("annotations" in query) {
|
|
56
51
|
const filter = {
|
|
57
52
|
kind: "user"
|
|
@@ -59,7 +54,10 @@ class CatalogAuthResolverContext {
|
|
|
59
54
|
for (const [key, value] of Object.entries(query.annotations)) {
|
|
60
55
|
filter[`metadata.annotations.${key}`] = value;
|
|
61
56
|
}
|
|
62
|
-
const res = await this.
|
|
57
|
+
const res = await this.catalog.getEntities(
|
|
58
|
+
{ filter },
|
|
59
|
+
{ credentials: await this.auth.getOwnServiceCredentials() }
|
|
60
|
+
);
|
|
63
61
|
result = res.items;
|
|
64
62
|
} else if ("filter" in query) {
|
|
65
63
|
const filter = [query.filter].flat().map((value) => {
|
|
@@ -73,9 +71,9 @@ class CatalogAuthResolverContext {
|
|
|
73
71
|
}
|
|
74
72
|
return value;
|
|
75
73
|
});
|
|
76
|
-
const res = await this.
|
|
74
|
+
const res = await this.catalog.getEntities(
|
|
77
75
|
{ filter },
|
|
78
|
-
{
|
|
76
|
+
{ credentials: await this.auth.getOwnServiceCredentials() }
|
|
79
77
|
);
|
|
80
78
|
result = res.items;
|
|
81
79
|
} else {
|
|
@@ -114,5 +112,4 @@ class CatalogAuthResolverContext {
|
|
|
114
112
|
}
|
|
115
113
|
|
|
116
114
|
exports.CatalogAuthResolverContext = CatalogAuthResolverContext;
|
|
117
|
-
exports.getDefaultOwnershipEntityRefs = getDefaultOwnershipEntityRefs;
|
|
118
115
|
//# sourceMappingURL=CatalogAuthResolverContext.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogAuthResolverContext.cjs.js","sources":["../../../src/lib/resolvers/CatalogAuthResolverContext.ts"],"sourcesContent":["/*\n * Copyright 2022 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 {
|
|
1
|
+
{"version":3,"file":"CatalogAuthResolverContext.cjs.js","sources":["../../../src/lib/resolvers/CatalogAuthResolverContext.ts"],"sourcesContent":["/*\n * Copyright 2022 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 {\n DEFAULT_NAMESPACE,\n Entity,\n parseEntityRef,\n RELATION_MEMBER_OF,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { ConflictError, InputError, NotFoundError } from '@backstage/errors';\nimport { AuthService, LoggerService } from '@backstage/backend-plugin-api';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\nimport { TokenIssuer } from '../../identity/types';\nimport {\n AuthOwnershipResolver,\n AuthResolverCatalogUserQuery,\n AuthResolverContext,\n TokenParams,\n} from '@backstage/plugin-auth-node';\nimport { CatalogIdentityClient } from '../catalog/CatalogIdentityClient';\n\nfunction getDefaultOwnershipEntityRefs(entity: Entity) {\n const membershipRefs =\n entity.relations\n ?.filter(\n r => r.type === RELATION_MEMBER_OF && r.targetRef.startsWith('group:'),\n )\n .map(r => r.targetRef) ?? [];\n\n return Array.from(new Set([stringifyEntityRef(entity), ...membershipRefs]));\n}\n\nexport class CatalogAuthResolverContext implements AuthResolverContext {\n static create(options: {\n logger: LoggerService;\n catalog: CatalogService;\n tokenIssuer: TokenIssuer;\n auth: AuthService;\n ownershipResolver?: AuthOwnershipResolver;\n }): CatalogAuthResolverContext {\n const catalogIdentityClient = new CatalogIdentityClient({\n catalog: options.catalog,\n auth: options.auth,\n });\n\n return new CatalogAuthResolverContext(\n options.logger,\n options.tokenIssuer,\n catalogIdentityClient,\n options.catalog,\n options.auth,\n options.ownershipResolver,\n );\n }\n\n private constructor(\n public readonly logger: LoggerService,\n public readonly tokenIssuer: TokenIssuer,\n public readonly catalogIdentityClient: CatalogIdentityClient,\n private readonly catalog: CatalogService,\n private readonly auth: AuthService,\n private readonly ownershipResolver?: AuthOwnershipResolver,\n ) {}\n\n async issueToken(params: TokenParams) {\n const token = await this.tokenIssuer.issueToken(params);\n return { token };\n }\n\n async findCatalogUser(query: AuthResolverCatalogUserQuery) {\n let result: Entity[] | Entity | undefined = undefined;\n\n if ('entityRef' in query) {\n const entityRef = parseEntityRef(query.entityRef, {\n defaultKind: 'User',\n defaultNamespace: DEFAULT_NAMESPACE,\n });\n result = await this.catalog.getEntityByRef(entityRef, {\n credentials: await this.auth.getOwnServiceCredentials(),\n });\n } else if ('annotations' in query) {\n const filter: Record<string, string> = {\n kind: 'user',\n };\n for (const [key, value] of Object.entries(query.annotations)) {\n filter[`metadata.annotations.${key}`] = value;\n }\n const res = await this.catalog.getEntities(\n { filter },\n { credentials: await this.auth.getOwnServiceCredentials() },\n );\n result = res.items;\n } else if ('filter' in query) {\n const filter = [query.filter].flat().map(value => {\n if (\n !Object.keys(value).some(\n key => key.toLocaleLowerCase('en-US') === 'kind',\n )\n ) {\n return {\n ...value,\n kind: 'user',\n };\n }\n return value;\n });\n const res = await this.catalog.getEntities(\n { filter: filter },\n { credentials: await this.auth.getOwnServiceCredentials() },\n );\n result = res.items;\n } else {\n throw new InputError('Invalid user lookup query');\n }\n\n if (Array.isArray(result)) {\n if (result.length > 1) {\n throw new ConflictError('User lookup resulted in multiple matches');\n }\n result = result[0];\n }\n if (!result) {\n throw new NotFoundError('User not found');\n }\n\n return { entity: result };\n }\n\n async signInWithCatalogUser(query: AuthResolverCatalogUserQuery) {\n const { entity } = await this.findCatalogUser(query);\n\n const { ownershipEntityRefs } = await this.resolveOwnershipEntityRefs(\n entity,\n );\n\n const token = await this.tokenIssuer.issueToken({\n claims: {\n sub: stringifyEntityRef(entity),\n ent: ownershipEntityRefs,\n },\n });\n return { token };\n }\n\n async resolveOwnershipEntityRefs(\n entity: Entity,\n ): Promise<{ ownershipEntityRefs: string[] }> {\n if (this.ownershipResolver) {\n return this.ownershipResolver.resolveOwnershipEntityRefs(entity);\n }\n return { ownershipEntityRefs: getDefaultOwnershipEntityRefs(entity) };\n }\n}\n"],"names":["RELATION_MEMBER_OF","stringifyEntityRef","CatalogIdentityClient","parseEntityRef","DEFAULT_NAMESPACE","InputError","ConflictError","NotFoundError"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var catalogClient = require('@backstage/catalog-client');
|
|
4
3
|
var errors = require('@backstage/errors');
|
|
5
4
|
var Router = require('express-promise-router');
|
|
6
5
|
var minimatch = require('minimatch');
|
|
@@ -17,12 +16,9 @@ function bindProviderRouters(targetRouter, options) {
|
|
|
17
16
|
baseUrl,
|
|
18
17
|
config,
|
|
19
18
|
logger,
|
|
20
|
-
discovery,
|
|
21
19
|
auth,
|
|
22
|
-
httpAuth,
|
|
23
|
-
tokenManager,
|
|
24
20
|
tokenIssuer,
|
|
25
|
-
|
|
21
|
+
catalog,
|
|
26
22
|
ownershipResolver
|
|
27
23
|
} = options;
|
|
28
24
|
const providersConfig = config.getOptionalConfig("auth.providers");
|
|
@@ -45,12 +41,9 @@ function bindProviderRouters(targetRouter, options) {
|
|
|
45
41
|
logger,
|
|
46
42
|
resolverContext: CatalogAuthResolverContext.CatalogAuthResolverContext.create({
|
|
47
43
|
logger,
|
|
48
|
-
|
|
44
|
+
catalog,
|
|
49
45
|
tokenIssuer,
|
|
50
|
-
tokenManager,
|
|
51
|
-
discovery,
|
|
52
46
|
auth,
|
|
53
|
-
httpAuth,
|
|
54
47
|
ownershipResolver
|
|
55
48
|
})
|
|
56
49
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.cjs.js","sources":["../../src/providers/router.ts"],"sourcesContent":["/*\n * Copyright 2024 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 {
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../../src/providers/router.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { AuthService, LoggerService } from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { assertError, NotFoundError } from '@backstage/errors';\nimport {\n AuthOwnershipResolver,\n AuthProviderFactory,\n} from '@backstage/plugin-auth-node';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Minimatch } from 'minimatch';\nimport { CatalogAuthResolverContext } from '../lib/resolvers/CatalogAuthResolverContext';\nimport { TokenIssuer } from '../identity/types';\n\nexport type ProviderFactories = { [s: string]: AuthProviderFactory };\n\nexport function bindProviderRouters(\n targetRouter: express.Router,\n options: {\n providers: ProviderFactories;\n appUrl: string;\n baseUrl: string;\n config: Config;\n logger: LoggerService;\n auth: AuthService;\n tokenIssuer: TokenIssuer;\n ownershipResolver?: AuthOwnershipResolver;\n catalog: CatalogService;\n },\n) {\n const {\n providers,\n appUrl,\n baseUrl,\n config,\n logger,\n auth,\n tokenIssuer,\n catalog,\n ownershipResolver,\n } = options;\n\n const providersConfig = config.getOptionalConfig('auth.providers');\n\n const isOriginAllowed = createOriginFilter(config);\n\n for (const [providerId, providerFactory] of Object.entries(providers)) {\n if (providersConfig?.has(providerId)) {\n logger.info(`Configuring auth provider: ${providerId}`);\n try {\n const provider = providerFactory({\n providerId,\n appUrl,\n baseUrl,\n isOriginAllowed,\n globalConfig: {\n baseUrl,\n appUrl,\n isOriginAllowed,\n },\n config: providersConfig.getConfig(providerId),\n logger,\n resolverContext: CatalogAuthResolverContext.create({\n logger,\n catalog,\n tokenIssuer,\n auth,\n ownershipResolver,\n }),\n });\n\n const r = Router();\n\n r.get('/start', provider.start.bind(provider));\n r.get('/handler/frame', provider.frameHandler.bind(provider));\n r.post('/handler/frame', provider.frameHandler.bind(provider));\n if (provider.logout) {\n r.post('/logout', provider.logout.bind(provider));\n }\n if (provider.refresh) {\n r.get('/refresh', provider.refresh.bind(provider));\n r.post('/refresh', provider.refresh.bind(provider));\n }\n\n targetRouter.use(`/${providerId}`, r);\n } catch (e) {\n assertError(e);\n if (process.env.NODE_ENV !== 'development') {\n throw new Error(\n `Failed to initialize ${providerId} auth provider, ${e.message}`,\n );\n }\n\n logger.warn(`Skipping ${providerId} auth provider, ${e.message}`);\n\n targetRouter.use(`/${providerId}`, () => {\n // If the user added the provider under auth.providers but the clientId and clientSecret etc. were not found.\n throw new NotFoundError(\n `Auth provider registered for '${providerId}' is misconfigured. This could mean the configs under ` +\n `auth.providers.${providerId} are missing or the environment variables used are not defined. ` +\n `Check the auth backend plugin logs when the backend starts to see more details.`,\n );\n });\n }\n } else {\n targetRouter.use(`/${providerId}`, () => {\n throw new NotFoundError(\n `No auth provider registered for '${providerId}'`,\n );\n });\n }\n }\n}\n\nexport function createOriginFilter(\n config: Config,\n): (origin: string) => boolean {\n const appUrl = config.getString('app.baseUrl');\n const { origin: appOrigin } = new URL(appUrl);\n\n const allowedOrigins = config.getOptionalStringArray(\n 'auth.experimentalExtraAllowedOrigins',\n );\n\n const allowedOriginPatterns =\n allowedOrigins?.map(\n pattern => new Minimatch(pattern, { nocase: true, noglobstar: true }),\n ) ?? [];\n\n return origin => {\n if (origin === appOrigin) {\n return true;\n }\n return allowedOriginPatterns.some(pattern => pattern.match(origin));\n };\n}\n"],"names":["CatalogAuthResolverContext","Router","assertError","NotFoundError","Minimatch"],"mappings":"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"}
|
|
@@ -3,16 +3,10 @@
|
|
|
3
3
|
var express = require('express');
|
|
4
4
|
var Router = require('express-promise-router');
|
|
5
5
|
var cookieParser = require('cookie-parser');
|
|
6
|
-
var providers = require('../providers/providers.cjs.js');
|
|
7
|
-
var router = require('../providers/router.cjs.js');
|
|
8
|
-
require('@backstage/plugin-auth-node');
|
|
9
|
-
var backendCommon = require('@backstage/backend-common');
|
|
10
6
|
var errors = require('@backstage/errors');
|
|
11
7
|
var router$1 = require('../identity/router.cjs.js');
|
|
12
|
-
var TokenFactory = require('../identity/TokenFactory.cjs.js');
|
|
13
|
-
require('luxon');
|
|
14
|
-
require('@google-cloud/firestore');
|
|
15
8
|
var KeyStores = require('../identity/KeyStores.cjs.js');
|
|
9
|
+
var TokenFactory = require('../identity/TokenFactory.cjs.js');
|
|
16
10
|
var UserInfoDatabaseHandler = require('../identity/UserInfoDatabaseHandler.cjs.js');
|
|
17
11
|
var session = require('express-session');
|
|
18
12
|
var connectSessionKnex = require('connect-session-knex');
|
|
@@ -21,6 +15,7 @@ var AuthDatabase = require('../database/AuthDatabase.cjs.js');
|
|
|
21
15
|
var readBackstageTokenExpiration = require('./readBackstageTokenExpiration.cjs.js');
|
|
22
16
|
var StaticTokenIssuer = require('../identity/StaticTokenIssuer.cjs.js');
|
|
23
17
|
var StaticKeyStore = require('../identity/StaticKeyStore.cjs.js');
|
|
18
|
+
var router = require('../providers/router.cjs.js');
|
|
24
19
|
|
|
25
20
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
26
21
|
|
|
@@ -40,7 +35,6 @@ async function createRouter(options) {
|
|
|
40
35
|
tokenFactoryAlgorithm,
|
|
41
36
|
providerFactories = {}
|
|
42
37
|
} = options;
|
|
43
|
-
const { auth, httpAuth } = backendCommon.createLegacyAuthAdapters(options);
|
|
44
38
|
const router$2 = Router__default.default();
|
|
45
39
|
const appUrl = config.getString("app.baseUrl");
|
|
46
40
|
const authUrl = await discovery.getExternalBaseUrl("auth");
|
|
@@ -97,21 +91,16 @@ async function createRouter(options) {
|
|
|
97
91
|
}
|
|
98
92
|
router$2.use(express__default.default.urlencoded({ extended: false }));
|
|
99
93
|
router$2.use(express__default.default.json());
|
|
100
|
-
const providers$1 = options.disableDefaultProviderFactories ? providerFactories : {
|
|
101
|
-
...providers.defaultAuthProviderFactories,
|
|
102
|
-
...providerFactories
|
|
103
|
-
};
|
|
104
94
|
router.bindProviderRouters(router$2, {
|
|
105
|
-
providers:
|
|
95
|
+
providers: providerFactories,
|
|
106
96
|
appUrl,
|
|
107
97
|
baseUrl: authUrl,
|
|
108
98
|
tokenIssuer,
|
|
109
99
|
...options,
|
|
110
|
-
auth
|
|
111
|
-
httpAuth
|
|
100
|
+
auth: options.auth
|
|
112
101
|
});
|
|
113
102
|
router$1.bindOidcRouter(router$2, {
|
|
114
|
-
auth,
|
|
103
|
+
auth: options.auth,
|
|
115
104
|
tokenIssuer,
|
|
116
105
|
baseUrl: authUrl,
|
|
117
106
|
userInfoDatabaseHandler
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2020 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 express from 'express';\nimport Router from 'express-promise-router';\nimport cookieParser from 'cookie-parser';\nimport {\n AuthService,\n DatabaseService,\n DiscoveryService,\n
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2020 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 express from 'express';\nimport Router from 'express-promise-router';\nimport cookieParser from 'cookie-parser';\nimport {\n AuthService,\n DatabaseService,\n DiscoveryService,\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { AuthOwnershipResolver } from '@backstage/plugin-auth-node';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\nimport { NotFoundError } from '@backstage/errors';\nimport { bindOidcRouter } from '../identity/router';\nimport { KeyStores } from '../identity/KeyStores';\nimport { TokenFactory } from '../identity/TokenFactory';\nimport { UserInfoDatabaseHandler } from '../identity/UserInfoDatabaseHandler';\nimport session from 'express-session';\nimport connectSessionKnex from 'connect-session-knex';\nimport passport from 'passport';\nimport { AuthDatabase } from '../database/AuthDatabase';\nimport { readBackstageTokenExpiration } from './readBackstageTokenExpiration';\nimport { TokenIssuer } from '../identity/types';\nimport { StaticTokenIssuer } from '../identity/StaticTokenIssuer';\nimport { StaticKeyStore } from '../identity/StaticKeyStore';\nimport { bindProviderRouters, ProviderFactories } from '../providers/router';\n\ninterface RouterOptions {\n logger: LoggerService;\n database: DatabaseService;\n config: RootConfigService;\n discovery: DiscoveryService;\n auth: AuthService;\n tokenFactoryAlgorithm?: string;\n providerFactories?: ProviderFactories;\n catalog: CatalogService;\n ownershipResolver?: AuthOwnershipResolver;\n}\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n logger,\n config,\n discovery,\n database,\n tokenFactoryAlgorithm,\n providerFactories = {},\n } = options;\n\n const router = Router();\n\n const appUrl = config.getString('app.baseUrl');\n const authUrl = await discovery.getExternalBaseUrl('auth');\n const backstageTokenExpiration = readBackstageTokenExpiration(config);\n const authDb = AuthDatabase.create(database);\n\n const keyStore = await KeyStores.fromConfig(config, {\n logger,\n database: authDb,\n });\n\n const userInfoDatabaseHandler = new UserInfoDatabaseHandler(\n await authDb.get(),\n );\n\n let tokenIssuer: TokenIssuer;\n if (keyStore instanceof StaticKeyStore) {\n tokenIssuer = new StaticTokenIssuer(\n {\n logger: logger.child({ component: 'token-factory' }),\n issuer: authUrl,\n sessionExpirationSeconds: backstageTokenExpiration,\n },\n keyStore as StaticKeyStore,\n );\n } else {\n tokenIssuer = new TokenFactory({\n issuer: authUrl,\n keyStore,\n keyDurationSeconds: backstageTokenExpiration,\n logger: logger.child({ component: 'token-factory' }),\n algorithm:\n tokenFactoryAlgorithm ??\n config.getOptionalString('auth.identityTokenAlgorithm'),\n userInfoDatabaseHandler,\n });\n }\n\n const secret = config.getOptionalString('auth.session.secret');\n if (secret) {\n router.use(cookieParser(secret));\n const enforceCookieSSL = authUrl.startsWith('https');\n const KnexSessionStore = connectSessionKnex(session);\n router.use(\n session({\n secret,\n saveUninitialized: false,\n resave: false,\n cookie: { secure: enforceCookieSSL ? 'auto' : false },\n store: new KnexSessionStore({\n createtable: false,\n knex: await authDb.get(),\n }),\n }),\n );\n router.use(passport.initialize());\n router.use(passport.session());\n } else {\n router.use(cookieParser());\n }\n\n router.use(express.urlencoded({ extended: false }));\n router.use(express.json());\n\n bindProviderRouters(router, {\n providers: providerFactories,\n appUrl,\n baseUrl: authUrl,\n tokenIssuer,\n ...options,\n auth: options.auth,\n });\n\n bindOidcRouter(router, {\n auth: options.auth,\n tokenIssuer,\n baseUrl: authUrl,\n userInfoDatabaseHandler,\n });\n\n // Gives a more helpful error message than a plain 404\n router.use('/:provider/', req => {\n const { provider } = req.params;\n throw new NotFoundError(`Unknown auth provider '${provider}'`);\n });\n\n return router;\n}\n"],"names":["router","Router","readBackstageTokenExpiration","AuthDatabase","KeyStores","UserInfoDatabaseHandler","StaticKeyStore","StaticTokenIssuer","TokenFactory","cookieParser","connectSessionKnex","session","passport","express","bindProviderRouters","bindOidcRouter","NotFoundError"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-auth-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0-next.0",
|
|
4
4
|
"description": "A Backstage backend plugin that handles authentication",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "backend-plugin",
|
|
@@ -46,79 +46,36 @@
|
|
|
46
46
|
"test": "backstage-cli package test"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@backstage/backend-
|
|
50
|
-
"@backstage/backend-plugin-api": "1.2.1",
|
|
51
|
-
"@backstage/catalog-client": "1.9.1",
|
|
49
|
+
"@backstage/backend-plugin-api": "1.3.1-next.0",
|
|
52
50
|
"@backstage/catalog-model": "1.7.3",
|
|
53
51
|
"@backstage/config": "1.3.2",
|
|
54
52
|
"@backstage/errors": "1.2.7",
|
|
55
|
-
"@backstage/plugin-auth-
|
|
56
|
-
"@backstage/plugin-
|
|
57
|
-
"@backstage/plugin-auth-backend-module-aws-alb-provider": "0.4.2-next.2",
|
|
58
|
-
"@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.2.6",
|
|
59
|
-
"@backstage/plugin-auth-backend-module-bitbucket-provider": "0.3.2-next.0",
|
|
60
|
-
"@backstage/plugin-auth-backend-module-bitbucket-server-provider": "0.2.1",
|
|
61
|
-
"@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.4.1",
|
|
62
|
-
"@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.4.1",
|
|
63
|
-
"@backstage/plugin-auth-backend-module-github-provider": "0.3.1",
|
|
64
|
-
"@backstage/plugin-auth-backend-module-gitlab-provider": "0.3.1",
|
|
65
|
-
"@backstage/plugin-auth-backend-module-google-provider": "0.3.1",
|
|
66
|
-
"@backstage/plugin-auth-backend-module-microsoft-provider": "0.3.1",
|
|
67
|
-
"@backstage/plugin-auth-backend-module-oauth2-provider": "0.4.1",
|
|
68
|
-
"@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.2.6",
|
|
69
|
-
"@backstage/plugin-auth-backend-module-oidc-provider": "0.4.2-next.2",
|
|
70
|
-
"@backstage/plugin-auth-backend-module-okta-provider": "0.2.1",
|
|
71
|
-
"@backstage/plugin-auth-backend-module-onelogin-provider": "0.3.1",
|
|
72
|
-
"@backstage/plugin-auth-node": "0.6.1",
|
|
73
|
-
"@backstage/plugin-catalog-node": "1.16.3-next.0",
|
|
53
|
+
"@backstage/plugin-auth-node": "0.6.3-next.0",
|
|
54
|
+
"@backstage/plugin-catalog-node": "1.17.0-next.0",
|
|
74
55
|
"@backstage/types": "1.2.1",
|
|
75
56
|
"@google-cloud/firestore": "^7.0.0",
|
|
76
|
-
"@node-saml/passport-saml": "^5.0.0",
|
|
77
|
-
"@types/express": "^4.17.6",
|
|
78
|
-
"@types/passport": "^1.0.3",
|
|
79
|
-
"compression": "^1.7.4",
|
|
80
57
|
"connect-session-knex": "^4.0.0",
|
|
81
58
|
"cookie-parser": "^1.4.5",
|
|
82
|
-
"cors": "^2.8.5",
|
|
83
59
|
"express": "^4.17.1",
|
|
84
60
|
"express-promise-router": "^4.1.0",
|
|
85
61
|
"express-session": "^1.17.1",
|
|
86
|
-
"fs-extra": "^11.2.0",
|
|
87
|
-
"google-auth-library": "^9.0.0",
|
|
88
62
|
"jose": "^5.0.0",
|
|
89
63
|
"knex": "^3.0.0",
|
|
90
64
|
"lodash": "^4.17.21",
|
|
91
65
|
"luxon": "^3.0.0",
|
|
92
66
|
"minimatch": "^9.0.0",
|
|
93
|
-
"morgan": "^1.10.0",
|
|
94
|
-
"node-cache": "^5.1.2",
|
|
95
|
-
"openid-client": "^5.2.1",
|
|
96
67
|
"passport": "^0.7.0",
|
|
97
|
-
"
|
|
98
|
-
"passport-github2": "^0.1.12",
|
|
99
|
-
"passport-google-oauth20": "^2.0.0",
|
|
100
|
-
"passport-microsoft": "^1.0.0",
|
|
101
|
-
"passport-oauth2": "^1.6.1",
|
|
102
|
-
"passport-onelogin-oauth": "^0.0.1",
|
|
103
|
-
"uuid": "^11.0.0",
|
|
104
|
-
"winston": "^3.2.1",
|
|
105
|
-
"yn": "^4.0.0"
|
|
68
|
+
"uuid": "^11.0.0"
|
|
106
69
|
},
|
|
107
70
|
"devDependencies": {
|
|
108
|
-
"@backstage/backend-defaults": "0.9.
|
|
109
|
-
"@backstage/backend-test-utils": "1.
|
|
110
|
-
"@backstage/cli": "0.32.
|
|
111
|
-
"@
|
|
71
|
+
"@backstage/backend-defaults": "0.9.1-next.0",
|
|
72
|
+
"@backstage/backend-test-utils": "1.5.0-next.0",
|
|
73
|
+
"@backstage/cli": "0.32.1-next.0",
|
|
74
|
+
"@backstage/plugin-auth-backend-module-google-provider": "0.3.3-next.0",
|
|
112
75
|
"@types/cookie-parser": "^1.4.2",
|
|
76
|
+
"@types/express": "^4.17.6",
|
|
113
77
|
"@types/express-session": "^1.17.2",
|
|
114
|
-
"@types/passport
|
|
115
|
-
"@types/passport-github2": "^1.2.4",
|
|
116
|
-
"@types/passport-google-oauth20": "^2.0.3",
|
|
117
|
-
"@types/passport-microsoft": "^1.0.0",
|
|
118
|
-
"@types/passport-saml": "^1.1.3",
|
|
119
|
-
"@types/passport-strategy": "^0.2.35",
|
|
120
|
-
"@types/xml2js": "^0.4.7",
|
|
121
|
-
"msw": "^1.0.0",
|
|
78
|
+
"@types/passport": "^1.0.3",
|
|
122
79
|
"supertest": "^7.0.0"
|
|
123
80
|
},
|
|
124
81
|
"configSchema": "config.d.ts",
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var crypto = require('crypto');
|
|
4
|
-
|
|
5
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
6
|
-
|
|
7
|
-
var crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto);
|
|
8
|
-
|
|
9
|
-
const safelyEncodeURIComponent = (value) => {
|
|
10
|
-
return encodeURIComponent(value).replace(/'/g, "%27");
|
|
11
|
-
};
|
|
12
|
-
const postMessageResponse = (res, appOrigin, response) => {
|
|
13
|
-
const jsonData = JSON.stringify(response);
|
|
14
|
-
const base64Data = safelyEncodeURIComponent(jsonData);
|
|
15
|
-
const base64Origin = safelyEncodeURIComponent(appOrigin);
|
|
16
|
-
const script = `
|
|
17
|
-
var authResponse = decodeURIComponent('${base64Data}');
|
|
18
|
-
var origin = decodeURIComponent('${base64Origin}');
|
|
19
|
-
var originInfo = {'type': 'config_info', 'targetOrigin': origin};
|
|
20
|
-
(window.opener || window.parent).postMessage(originInfo, '*');
|
|
21
|
-
(window.opener || window.parent).postMessage(JSON.parse(authResponse), origin);
|
|
22
|
-
setTimeout(() => {
|
|
23
|
-
window.close();
|
|
24
|
-
}, 100); // same as the interval of the core-app-api lib/loginPopup.ts (to address race conditions)
|
|
25
|
-
`;
|
|
26
|
-
const hash = crypto__default.default.createHash("sha256").update(script).digest("base64");
|
|
27
|
-
res.setHeader("Content-Type", "text/html");
|
|
28
|
-
res.setHeader("X-Frame-Options", "sameorigin");
|
|
29
|
-
res.setHeader("Content-Security-Policy", `script-src 'sha256-${hash}'`);
|
|
30
|
-
res.end(`<html><body><script>${script}<\/script></body></html>`);
|
|
31
|
-
};
|
|
32
|
-
const ensuresXRequestedWith = (req) => {
|
|
33
|
-
const requiredHeader = req.header("X-Requested-With");
|
|
34
|
-
if (!requiredHeader || requiredHeader !== "XMLHttpRequest") {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
return true;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
exports.ensuresXRequestedWith = ensuresXRequestedWith;
|
|
41
|
-
exports.postMessageResponse = postMessageResponse;
|
|
42
|
-
exports.safelyEncodeURIComponent = safelyEncodeURIComponent;
|
|
43
|
-
//# sourceMappingURL=authFlowHelpers.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authFlowHelpers.cjs.js","sources":["../../../src/lib/flow/authFlowHelpers.ts"],"sourcesContent":["/*\n * Copyright 2020 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 express from 'express';\nimport crypto from 'crypto';\nimport { WebMessageResponse } from './types';\n\nexport const safelyEncodeURIComponent = (value: string) => {\n // Note the g at the end of the regex; all occurrences of single quotes must\n // be replaced, which encodeURIComponent does not do itself by default\n return encodeURIComponent(value).replace(/'/g, '%27');\n};\n\n/**\n * @public\n * @deprecated Use `sendWebMessageResponse` from `@backstage/plugin-auth-node` instead\n */\nexport const postMessageResponse = (\n res: express.Response,\n appOrigin: string,\n response: WebMessageResponse,\n) => {\n const jsonData = JSON.stringify(response);\n const base64Data = safelyEncodeURIComponent(jsonData);\n const base64Origin = safelyEncodeURIComponent(appOrigin);\n\n // NOTE: It is absolutely imperative that we use the safe encoder above, to\n // be sure that the js code below does not allow the injection of malicious\n // data.\n\n // TODO: Make target app origin configurable globally\n\n //\n // postMessage fails silently if the targetOrigin is disallowed.\n // So 2 postMessages are sent from the popup to the parent window.\n // First, the origin being used to post the actual authorization response is\n // shared with the parent window with a postMessage with targetOrigin '*'.\n // Second, the actual authorization response is sent with the app origin\n // as the targetOrigin.\n // If the first message was received but the actual auth response was\n // never received, the event listener can conclude that targetOrigin\n // was disallowed, indicating potential misconfiguration.\n //\n const script = `\n var authResponse = decodeURIComponent('${base64Data}');\n var origin = decodeURIComponent('${base64Origin}');\n var originInfo = {'type': 'config_info', 'targetOrigin': origin};\n (window.opener || window.parent).postMessage(originInfo, '*');\n (window.opener || window.parent).postMessage(JSON.parse(authResponse), origin);\n setTimeout(() => {\n window.close();\n }, 100); // same as the interval of the core-app-api lib/loginPopup.ts (to address race conditions)\n `;\n const hash = crypto.createHash('sha256').update(script).digest('base64');\n\n res.setHeader('Content-Type', 'text/html');\n res.setHeader('X-Frame-Options', 'sameorigin');\n res.setHeader('Content-Security-Policy', `script-src 'sha256-${hash}'`);\n res.end(`<html><body><script>${script}</script></body></html>`);\n};\n\n/**\n * @public\n * @deprecated Use inline logic to check that the `X-Requested-With` header is set to `'XMLHttpRequest'` instead.\n */\nexport const ensuresXRequestedWith = (req: express.Request) => {\n const requiredHeader = req.header('X-Requested-With');\n if (!requiredHeader || requiredHeader !== 'XMLHttpRequest') {\n return false;\n }\n return true;\n};\n"],"names":["crypto"],"mappings":";;;;;;;;AAoBa,MAAA,wBAAA,GAA2B,CAAC,KAAkB,KAAA;AAGzD,EAAA,OAAO,kBAAmB,CAAA,KAAK,CAAE,CAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AACtD;AAMO,MAAM,mBAAsB,GAAA,CACjC,GACA,EAAA,SAAA,EACA,QACG,KAAA;AACH,EAAM,MAAA,QAAA,GAAW,IAAK,CAAA,SAAA,CAAU,QAAQ,CAAA;AACxC,EAAM,MAAA,UAAA,GAAa,yBAAyB,QAAQ,CAAA;AACpD,EAAM,MAAA,YAAA,GAAe,yBAAyB,SAAS,CAAA;AAmBvD,EAAA,MAAM,MAAS,GAAA;AAAA,2CAAA,EAC4B,UAAU,CAAA;AAAA,qCAAA,EAChB,YAAY,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAAA;AAQjD,EAAM,MAAA,IAAA,GAAOA,wBAAO,UAAW,CAAA,QAAQ,EAAE,MAAO,CAAA,MAAM,CAAE,CAAA,MAAA,CAAO,QAAQ,CAAA;AAEvE,EAAI,GAAA,CAAA,SAAA,CAAU,gBAAgB,WAAW,CAAA;AACzC,EAAI,GAAA,CAAA,SAAA,CAAU,mBAAmB,YAAY,CAAA;AAC7C,EAAA,GAAA,CAAI,SAAU,CAAA,yBAAA,EAA2B,CAAsB,mBAAA,EAAA,IAAI,CAAG,CAAA,CAAA,CAAA;AACtE,EAAI,GAAA,CAAA,GAAA,CAAI,CAAuB,oBAAA,EAAA,MAAM,CAAyB,wBAAA,CAAA,CAAA;AAChE;AAMa,MAAA,qBAAA,GAAwB,CAAC,GAAyB,KAAA;AAC7D,EAAM,MAAA,cAAA,GAAiB,GAAI,CAAA,MAAA,CAAO,kBAAkB,CAAA;AACpD,EAAI,IAAA,CAAC,cAAkB,IAAA,cAAA,KAAmB,gBAAkB,EAAA;AAC1D,IAAO,OAAA,KAAA;AAAA;AAET,EAAO,OAAA,IAAA;AACT;;;;;;"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function adaptLegacyOAuthHandler(authHandler) {
|
|
4
|
-
return authHandler && (async (result, ctx) => authHandler(
|
|
5
|
-
{
|
|
6
|
-
fullProfile: result.fullProfile,
|
|
7
|
-
accessToken: result.session.accessToken,
|
|
8
|
-
params: {
|
|
9
|
-
scope: result.session.scope,
|
|
10
|
-
id_token: result.session.idToken,
|
|
11
|
-
token_type: result.session.tokenType,
|
|
12
|
-
expires_in: result.session.expiresInSeconds
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
ctx
|
|
16
|
-
));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
exports.adaptLegacyOAuthHandler = adaptLegacyOAuthHandler;
|
|
20
|
-
//# sourceMappingURL=adaptLegacyOAuthHandler.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adaptLegacyOAuthHandler.cjs.js","sources":["../../../src/lib/legacy/adaptLegacyOAuthHandler.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 {\n OAuthAuthenticatorResult,\n ProfileTransform,\n} from '@backstage/plugin-auth-node';\nimport { AuthHandler } from '../../providers';\nimport { OAuthResult } from '../oauth';\nimport { PassportProfile } from '../passport/types';\n\n/** @internal */\nexport function adaptLegacyOAuthHandler(\n authHandler?: AuthHandler<OAuthResult>,\n): ProfileTransform<OAuthAuthenticatorResult<PassportProfile>> | undefined {\n return (\n authHandler &&\n (async (result, ctx) =>\n authHandler(\n {\n fullProfile: result.fullProfile,\n accessToken: result.session.accessToken,\n params: {\n scope: result.session.scope,\n id_token: result.session.idToken,\n token_type: result.session.tokenType,\n expires_in: result.session.expiresInSeconds!,\n },\n },\n ctx,\n ))\n );\n}\n"],"names":[],"mappings":";;AAyBO,SAAS,wBACd,WACyE,EAAA;AACzE,EACE,OAAA,WAAA,KACC,OAAO,MAAA,EAAQ,GACd,KAAA,WAAA;AAAA,IACE;AAAA,MACE,aAAa,MAAO,CAAA,WAAA;AAAA,MACpB,WAAA,EAAa,OAAO,OAAQ,CAAA,WAAA;AAAA,MAC5B,MAAQ,EAAA;AAAA,QACN,KAAA,EAAO,OAAO,OAAQ,CAAA,KAAA;AAAA,QACtB,QAAA,EAAU,OAAO,OAAQ,CAAA,OAAA;AAAA,QACzB,UAAA,EAAY,OAAO,OAAQ,CAAA,SAAA;AAAA,QAC3B,UAAA,EAAY,OAAO,OAAQ,CAAA;AAAA;AAC7B,KACF;AAAA,IACA;AAAA,GACF,CAAA;AAEN;;;;"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function adaptLegacyOAuthSignInResolver(signInResolver) {
|
|
4
|
-
return signInResolver && (async (input, ctx) => signInResolver(
|
|
5
|
-
{
|
|
6
|
-
profile: input.profile,
|
|
7
|
-
result: {
|
|
8
|
-
fullProfile: input.result.fullProfile,
|
|
9
|
-
accessToken: input.result.session.accessToken,
|
|
10
|
-
refreshToken: input.result.session.refreshToken,
|
|
11
|
-
params: {
|
|
12
|
-
scope: input.result.session.scope,
|
|
13
|
-
id_token: input.result.session.idToken,
|
|
14
|
-
token_type: input.result.session.tokenType,
|
|
15
|
-
expires_in: input.result.session.expiresInSeconds
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
ctx
|
|
20
|
-
));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
exports.adaptLegacyOAuthSignInResolver = adaptLegacyOAuthSignInResolver;
|
|
24
|
-
//# sourceMappingURL=adaptLegacyOAuthSignInResolver.cjs.js.map
|