@backstage/backend-defaults 0.5.1-next.1 → 0.5.1-next.2
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 +25 -0
- package/auth/package.json +1 -1
- package/cache/package.json +1 -1
- package/database/package.json +1 -1
- package/discovery/package.json +1 -1
- package/dist/CreateBackend.cjs.js +49 -0
- package/dist/CreateBackend.cjs.js.map +1 -0
- package/dist/PackageDiscoveryService.cjs.js +109 -0
- package/dist/PackageDiscoveryService.cjs.js.map +1 -0
- package/dist/auth.cjs.js +2 -996
- package/dist/auth.cjs.js.map +1 -1
- package/dist/cache.cjs.js +4 -204
- package/dist/cache.cjs.js.map +1 -1
- package/dist/database.cjs.js +4 -957
- package/dist/database.cjs.js.map +1 -1
- package/dist/database.d.ts +4 -1
- package/dist/discovery.cjs.js +4 -92
- package/dist/discovery.cjs.js.map +1 -1
- package/dist/discoveryFeatureLoader.cjs.js +19 -0
- package/dist/discoveryFeatureLoader.cjs.js.map +1 -0
- package/dist/entrypoints/auth/DefaultAuthService.cjs.js +130 -0
- package/dist/entrypoints/auth/DefaultAuthService.cjs.js.map +1 -0
- package/dist/entrypoints/auth/JwksClient.cjs.js +49 -0
- package/dist/entrypoints/auth/JwksClient.cjs.js.map +1 -0
- package/dist/entrypoints/auth/authServiceFactory.cjs.js +57 -0
- package/dist/entrypoints/auth/authServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/ExternalTokenHandler.cjs.js +78 -0
- package/dist/entrypoints/auth/external/ExternalTokenHandler.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/helpers.cjs.js +92 -0
- package/dist/entrypoints/auth/external/helpers.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/jwks.cjs.js +63 -0
- package/dist/entrypoints/auth/external/jwks.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/legacy.cjs.js +73 -0
- package/dist/entrypoints/auth/external/legacy.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/static.cjs.js +33 -0
- package/dist/entrypoints/auth/external/static.cjs.js.map +1 -0
- package/dist/{cjs/helpers-D2f1CG0o.cjs.js → entrypoints/auth/helpers.cjs.js} +1 -1
- package/dist/entrypoints/auth/helpers.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/PluginTokenHandler.cjs.js +147 -0
- package/dist/entrypoints/auth/plugin/PluginTokenHandler.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/keys/DatabaseKeyStore.cjs.js +73 -0
- package/dist/entrypoints/auth/plugin/keys/DatabaseKeyStore.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/keys/DatabasePluginKeySource.cjs.js +75 -0
- package/dist/entrypoints/auth/plugin/keys/DatabasePluginKeySource.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.cjs.js +91 -0
- package/dist/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/keys/createPluginKeySource.cjs.js +29 -0
- package/dist/entrypoints/auth/plugin/keys/createPluginKeySource.cjs.js.map +1 -0
- package/dist/entrypoints/auth/user/UserTokenHandler.cjs.js +110 -0
- package/dist/entrypoints/auth/user/UserTokenHandler.cjs.js.map +1 -0
- package/dist/entrypoints/cache/CacheClient.cjs.js +50 -0
- package/dist/entrypoints/cache/CacheClient.cjs.js.map +1 -0
- package/dist/entrypoints/cache/CacheManager.cjs.js +147 -0
- package/dist/entrypoints/cache/CacheManager.cjs.js.map +1 -0
- package/dist/entrypoints/cache/cacheServiceFactory.cjs.js +22 -0
- package/dist/entrypoints/cache/cacheServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/cache/types.cjs.js +10 -0
- package/dist/entrypoints/cache/types.cjs.js.map +1 -0
- package/dist/entrypoints/database/DatabaseManager.cjs.js +173 -0
- package/dist/entrypoints/database/DatabaseManager.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/defaultNameOverride.cjs.js +14 -0
- package/dist/entrypoints/database/connectors/defaultNameOverride.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/defaultSchemaOverride.cjs.js +12 -0
- package/dist/entrypoints/database/connectors/defaultSchemaOverride.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/mergeDatabaseConfig.cjs.js +10 -0
- package/dist/entrypoints/database/connectors/mergeDatabaseConfig.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/mysql.cjs.js +278 -0
- package/dist/entrypoints/database/connectors/mysql.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/postgres.cjs.js +304 -0
- package/dist/entrypoints/database/connectors/postgres.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/sqlite3.cjs.js +251 -0
- package/dist/entrypoints/database/connectors/sqlite3.cjs.js.map +1 -0
- package/dist/entrypoints/database/databaseServiceFactory.cjs.js +36 -0
- package/dist/entrypoints/database/databaseServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/discovery/HostDiscovery.cjs.js +86 -0
- package/dist/entrypoints/discovery/HostDiscovery.cjs.js.map +1 -0
- package/dist/entrypoints/discovery/discoveryServiceFactory.cjs.js +17 -0
- package/dist/entrypoints/discovery/discoveryServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/httpAuth/httpAuthServiceFactory.cjs.js +192 -0
- package/dist/entrypoints/httpAuth/httpAuthServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/createAuthIntegrationRouter.cjs.js +19 -0
- package/dist/entrypoints/httpRouter/createAuthIntegrationRouter.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.cjs.js +26 -0
- package/dist/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/createCredentialsBarrier.cjs.js +63 -0
- package/dist/entrypoints/httpRouter/createCredentialsBarrier.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/createLifecycleMiddleware.cjs.js +52 -0
- package/dist/entrypoints/httpRouter/createLifecycleMiddleware.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/httpRouterServiceFactory.cjs.js +48 -0
- package/dist/entrypoints/httpRouter/httpRouterServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/lifecycle/lifecycleServiceFactory.cjs.js +88 -0
- package/dist/entrypoints/lifecycle/lifecycleServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/logger/loggerServiceFactory.cjs.js +17 -0
- package/dist/entrypoints/logger/loggerServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/permissions/permissionsServiceFactory.cjs.js +22 -0
- package/dist/entrypoints/permissions/permissionsServiceFactory.cjs.js.map +1 -0
- package/dist/{cjs/createConfigSecretEnumerator-DShyoWWL.cjs.js → entrypoints/rootConfig/createConfigSecretEnumerator.cjs.js} +1 -1
- package/dist/entrypoints/rootConfig/createConfigSecretEnumerator.cjs.js.map +1 -0
- package/dist/entrypoints/rootConfig/rootConfigServiceFactory.cjs.js +26 -0
- package/dist/entrypoints/rootConfig/rootConfigServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootHealth/rootHealthServiceFactory.cjs.js +41 -0
- package/dist/entrypoints/rootHealth/rootHealthServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/DefaultRootHttpRouter.cjs.js +77 -0
- package/dist/entrypoints/rootHttpRouter/DefaultRootHttpRouter.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/createHealthRouter.cjs.js +29 -0
- package/dist/entrypoints/rootHttpRouter/createHealthRouter.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/MiddlewareFactory.cjs.js +187 -0
- package/dist/entrypoints/rootHttpRouter/http/MiddlewareFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.cjs.js +28 -0
- package/dist/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.cjs.js.map +1 -0
- package/dist/{cjs/config-BDOwXIyo.cjs.js → entrypoints/rootHttpRouter/http/config.cjs.js} +1 -1
- package/dist/entrypoints/rootHttpRouter/http/config.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/createHttpServer.cjs.js +88 -0
- package/dist/entrypoints/rootHttpRouter/http/createHttpServer.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/getGeneratedCertificate.cjs.js +130 -0
- package/dist/entrypoints/rootHttpRouter/http/getGeneratedCertificate.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/readCorsOptions.cjs.js +51 -0
- package/dist/entrypoints/rootHttpRouter/http/readCorsOptions.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/readHelmetOptions.cjs.js +62 -0
- package/dist/entrypoints/rootHttpRouter/http/readHelmetOptions.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.cjs.js +73 -0
- package/dist/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootLifecycle/rootLifecycleServiceFactory.cjs.js +76 -0
- package/dist/entrypoints/rootLifecycle/rootLifecycleServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootLogger/WinstonLogger.cjs.js +114 -0
- package/dist/entrypoints/rootLogger/WinstonLogger.cjs.js.map +1 -0
- package/dist/entrypoints/rootLogger/rootLoggerServiceFactory.cjs.js +30 -0
- package/dist/entrypoints/rootLogger/rootLoggerServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/database/migrateBackendTasks.cjs.js +18 -0
- package/dist/entrypoints/scheduler/database/migrateBackendTasks.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/database/tables.cjs.js +8 -0
- package/dist/entrypoints/scheduler/database/tables.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/DefaultSchedulerService.cjs.js +37 -0
- package/dist/entrypoints/scheduler/lib/DefaultSchedulerService.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/LocalTaskWorker.cjs.js +105 -0
- package/dist/entrypoints/scheduler/lib/LocalTaskWorker.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.cjs.js +138 -0
- package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.cjs.js +59 -0
- package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/TaskWorker.cjs.js +275 -0
- package/dist/entrypoints/scheduler/lib/TaskWorker.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/types.cjs.js +60 -0
- package/dist/entrypoints/scheduler/lib/types.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/util.cjs.js +66 -0
- package/dist/entrypoints/scheduler/lib/util.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/schedulerServiceFactory.cjs.js +19 -0
- package/dist/entrypoints/scheduler/schedulerServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.cjs.js +274 -0
- package/dist/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js +261 -0
- package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/AzureUrlReader.cjs.js +148 -0
- package/dist/entrypoints/urlReader/lib/AzureUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/BitbucketCloudUrlReader.cjs.js +174 -0
- package/dist/entrypoints/urlReader/lib/BitbucketCloudUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/BitbucketServerUrlReader.cjs.js +170 -0
- package/dist/entrypoints/urlReader/lib/BitbucketServerUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/BitbucketUrlReader.cjs.js +182 -0
- package/dist/entrypoints/urlReader/lib/BitbucketUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/FetchUrlReader.cjs.js +132 -0
- package/dist/entrypoints/urlReader/lib/FetchUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GerritUrlReader.cjs.js +147 -0
- package/dist/entrypoints/urlReader/lib/GerritUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GiteaUrlReader.cjs.js +122 -0
- package/dist/entrypoints/urlReader/lib/GiteaUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GithubUrlReader.cjs.js +226 -0
- package/dist/entrypoints/urlReader/lib/GithubUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GitlabUrlReader.cjs.js +277 -0
- package/dist/entrypoints/urlReader/lib/GitlabUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GoogleGcsUrlReader.cjs.js +129 -0
- package/dist/entrypoints/urlReader/lib/GoogleGcsUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/HarnessUrlReader.cjs.js +120 -0
- package/dist/entrypoints/urlReader/lib/HarnessUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/ReadUrlResponseFactory.cjs.js +49 -0
- package/dist/entrypoints/urlReader/lib/ReadUrlResponseFactory.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/UrlReaderPredicateMux.cjs.js +46 -0
- package/dist/entrypoints/urlReader/lib/UrlReaderPredicateMux.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/UrlReaders.cjs.js +68 -0
- package/dist/entrypoints/urlReader/lib/UrlReaders.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.cjs.js +46 -0
- package/dist/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/ReadableArrayResponse.cjs.js +78 -0
- package/dist/entrypoints/urlReader/lib/tree/ReadableArrayResponse.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/TarArchiveResponse.cjs.js +147 -0
- package/dist/entrypoints/urlReader/lib/tree/TarArchiveResponse.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/ZipArchiveResponse.cjs.js +161 -0
- package/dist/entrypoints/urlReader/lib/tree/ZipArchiveResponse.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/util.cjs.js +28 -0
- package/dist/entrypoints/urlReader/lib/tree/util.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/util.cjs.js +11 -0
- package/dist/entrypoints/urlReader/lib/util.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/urlReaderServiceFactory.cjs.js +29 -0
- package/dist/entrypoints/urlReader/urlReaderServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/userInfo/DefaultUserInfoService.cjs.js +59 -0
- package/dist/entrypoints/userInfo/DefaultUserInfoService.cjs.js.map +1 -0
- package/dist/entrypoints/userInfo/userInfoServiceFactory.cjs.js +17 -0
- package/dist/entrypoints/userInfo/userInfoServiceFactory.cjs.js.map +1 -0
- package/dist/httpAuth.cjs.js +3 -187
- package/dist/httpAuth.cjs.js.map +1 -1
- package/dist/httpRouter.cjs.js +2 -166
- package/dist/httpRouter.cjs.js.map +1 -1
- package/dist/index.cjs.js +4 -160
- package/dist/index.cjs.js.map +1 -1
- package/dist/lib/escapeRegExp.cjs.js +8 -0
- package/dist/lib/escapeRegExp.cjs.js.map +1 -0
- package/dist/lifecycle.cjs.js +3 -58
- package/dist/lifecycle.cjs.js.map +1 -1
- package/dist/logger.cjs.js +3 -12
- package/dist/logger.cjs.js.map +1 -1
- package/dist/package.json.cjs.js +252 -0
- package/dist/package.json.cjs.js.map +1 -0
- package/dist/permissions.cjs.js +3 -17
- package/dist/permissions.cjs.js.map +1 -1
- package/dist/rootConfig.cjs.js +4 -22
- package/dist/rootConfig.cjs.js.map +1 -1
- package/dist/rootHealth.cjs.js +3 -35
- package/dist/rootHealth.cjs.js.map +1 -1
- package/dist/rootHttpRouter.cjs.js +15 -651
- package/dist/rootHttpRouter.cjs.js.map +1 -1
- package/dist/rootLifecycle.cjs.js +3 -70
- package/dist/rootLifecycle.cjs.js.map +1 -1
- package/dist/rootLogger.cjs.js +4 -137
- package/dist/rootLogger.cjs.js.map +1 -1
- package/dist/scheduler.cjs.js +4 -693
- package/dist/scheduler.cjs.js.map +1 -1
- package/dist/scheduler.d.ts +2 -1
- package/dist/urlReader.cjs.js +32 -2962
- package/dist/urlReader.cjs.js.map +1 -1
- package/dist/userInfo.cjs.js +2 -64
- package/dist/userInfo.cjs.js.map +1 -1
- package/httpAuth/package.json +1 -1
- package/httpRouter/package.json +1 -1
- package/lifecycle/package.json +1 -1
- package/logger/package.json +1 -1
- package/package.json +13 -13
- package/permissions/package.json +1 -1
- package/rootConfig/package.json +1 -1
- package/rootHealth/package.json +1 -1
- package/rootHttpRouter/package.json +1 -1
- package/rootLifecycle/package.json +1 -1
- package/rootLogger/package.json +1 -1
- package/scheduler/package.json +1 -1
- package/urlReader/package.json +1 -1
- package/userInfo/package.json +1 -1
- package/dist/cjs/config-BDOwXIyo.cjs.js.map +0 -1
- package/dist/cjs/createConfigSecretEnumerator-DShyoWWL.cjs.js.map +0 -1
- package/dist/cjs/helpers-D2f1CG0o.cjs.js.map +0 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
var errors = require('@backstage/errors');
|
|
5
|
+
var cookie = require('cookie');
|
|
6
|
+
|
|
7
|
+
const FIVE_MINUTES_MS = 5 * 60 * 1e3;
|
|
8
|
+
const BACKSTAGE_AUTH_COOKIE = "backstage-auth";
|
|
9
|
+
function getTokenFromRequest(req) {
|
|
10
|
+
const authHeader = req.headers.authorization;
|
|
11
|
+
if (typeof authHeader === "string") {
|
|
12
|
+
const matches = authHeader.match(/^Bearer[ ]+(\S+)$/i);
|
|
13
|
+
const token = matches?.[1];
|
|
14
|
+
if (token) {
|
|
15
|
+
return token;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
function getCookieFromRequest(req) {
|
|
21
|
+
const cookieHeader = req.headers.cookie;
|
|
22
|
+
if (cookieHeader) {
|
|
23
|
+
const cookies = cookie.parse(cookieHeader);
|
|
24
|
+
const token = cookies[BACKSTAGE_AUTH_COOKIE];
|
|
25
|
+
if (token) {
|
|
26
|
+
return token;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return void 0;
|
|
30
|
+
}
|
|
31
|
+
function willExpireSoon(expiresAt) {
|
|
32
|
+
return Date.now() + FIVE_MINUTES_MS > expiresAt.getTime();
|
|
33
|
+
}
|
|
34
|
+
const credentialsSymbol = Symbol("backstage-credentials");
|
|
35
|
+
const limitedCredentialsSymbol = Symbol("backstage-limited-credentials");
|
|
36
|
+
class DefaultHttpAuthService {
|
|
37
|
+
#auth;
|
|
38
|
+
#discovery;
|
|
39
|
+
#pluginId;
|
|
40
|
+
constructor(auth, discovery, pluginId) {
|
|
41
|
+
this.#auth = auth;
|
|
42
|
+
this.#discovery = discovery;
|
|
43
|
+
this.#pluginId = pluginId;
|
|
44
|
+
}
|
|
45
|
+
async #extractCredentialsFromRequest(req) {
|
|
46
|
+
const token = getTokenFromRequest(req);
|
|
47
|
+
if (!token) {
|
|
48
|
+
return await this.#auth.getNoneCredentials();
|
|
49
|
+
}
|
|
50
|
+
return await this.#auth.authenticate(token);
|
|
51
|
+
}
|
|
52
|
+
async #extractLimitedCredentialsFromRequest(req) {
|
|
53
|
+
const token = getTokenFromRequest(req);
|
|
54
|
+
if (token) {
|
|
55
|
+
return await this.#auth.authenticate(token, {
|
|
56
|
+
allowLimitedAccess: true
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const cookie = getCookieFromRequest(req);
|
|
60
|
+
if (cookie) {
|
|
61
|
+
return await this.#auth.authenticate(cookie, {
|
|
62
|
+
allowLimitedAccess: true
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return await this.#auth.getNoneCredentials();
|
|
66
|
+
}
|
|
67
|
+
async #getCredentials(req) {
|
|
68
|
+
return req[credentialsSymbol] ??= this.#extractCredentialsFromRequest(req);
|
|
69
|
+
}
|
|
70
|
+
async #getLimitedCredentials(req) {
|
|
71
|
+
return req[limitedCredentialsSymbol] ??= this.#extractLimitedCredentialsFromRequest(req);
|
|
72
|
+
}
|
|
73
|
+
async credentials(req, options) {
|
|
74
|
+
const credentials = options?.allowLimitedAccess ? await this.#getLimitedCredentials(req) : await this.#getCredentials(req);
|
|
75
|
+
const allowed = options?.allow;
|
|
76
|
+
if (!allowed) {
|
|
77
|
+
return credentials;
|
|
78
|
+
}
|
|
79
|
+
if (this.#auth.isPrincipal(credentials, "none")) {
|
|
80
|
+
if (allowed.includes("none")) {
|
|
81
|
+
return credentials;
|
|
82
|
+
}
|
|
83
|
+
throw new errors.AuthenticationError("Missing credentials");
|
|
84
|
+
} else if (this.#auth.isPrincipal(credentials, "user")) {
|
|
85
|
+
if (allowed.includes("user")) {
|
|
86
|
+
return credentials;
|
|
87
|
+
}
|
|
88
|
+
throw new errors.NotAllowedError(
|
|
89
|
+
`This endpoint does not allow 'user' credentials`
|
|
90
|
+
);
|
|
91
|
+
} else if (this.#auth.isPrincipal(credentials, "service")) {
|
|
92
|
+
if (allowed.includes("service")) {
|
|
93
|
+
return credentials;
|
|
94
|
+
}
|
|
95
|
+
throw new errors.NotAllowedError(
|
|
96
|
+
`This endpoint does not allow 'service' credentials`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
throw new errors.NotAllowedError(
|
|
100
|
+
"Unknown principal type, this should never happen"
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
async issueUserCookie(res, options) {
|
|
104
|
+
if (res.headersSent) {
|
|
105
|
+
throw new Error("Failed to issue user cookie, headers were already sent");
|
|
106
|
+
}
|
|
107
|
+
let credentials;
|
|
108
|
+
if (options?.credentials) {
|
|
109
|
+
if (this.#auth.isPrincipal(options.credentials, "none")) {
|
|
110
|
+
res.clearCookie(
|
|
111
|
+
BACKSTAGE_AUTH_COOKIE,
|
|
112
|
+
await this.#getCookieOptions(res.req)
|
|
113
|
+
);
|
|
114
|
+
return { expiresAt: /* @__PURE__ */ new Date() };
|
|
115
|
+
}
|
|
116
|
+
if (!this.#auth.isPrincipal(options.credentials, "user")) {
|
|
117
|
+
throw new errors.AuthenticationError(
|
|
118
|
+
"Refused to issue cookie for non-user principal"
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
credentials = options.credentials;
|
|
122
|
+
} else {
|
|
123
|
+
credentials = await this.credentials(res.req, { allow: ["user"] });
|
|
124
|
+
}
|
|
125
|
+
const existingExpiresAt = await this.#existingCookieExpiration(res.req);
|
|
126
|
+
if (existingExpiresAt && !willExpireSoon(existingExpiresAt)) {
|
|
127
|
+
return { expiresAt: existingExpiresAt };
|
|
128
|
+
}
|
|
129
|
+
const { token, expiresAt } = await this.#auth.getLimitedUserToken(
|
|
130
|
+
credentials
|
|
131
|
+
);
|
|
132
|
+
if (!token) {
|
|
133
|
+
throw new Error("User credentials is unexpectedly missing token");
|
|
134
|
+
}
|
|
135
|
+
res.cookie(BACKSTAGE_AUTH_COOKIE, token, {
|
|
136
|
+
...await this.#getCookieOptions(res.req),
|
|
137
|
+
expires: expiresAt
|
|
138
|
+
});
|
|
139
|
+
return { expiresAt };
|
|
140
|
+
}
|
|
141
|
+
async #getCookieOptions(_req) {
|
|
142
|
+
const externalBaseUrlStr = await this.#discovery.getExternalBaseUrl(
|
|
143
|
+
this.#pluginId
|
|
144
|
+
);
|
|
145
|
+
const externalBaseUrl = new URL(externalBaseUrlStr);
|
|
146
|
+
const secure = externalBaseUrl.protocol === "https:" || externalBaseUrl.hostname === "localhost";
|
|
147
|
+
return {
|
|
148
|
+
domain: externalBaseUrl.hostname,
|
|
149
|
+
httpOnly: true,
|
|
150
|
+
secure,
|
|
151
|
+
priority: "high",
|
|
152
|
+
sameSite: secure ? "none" : "lax"
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
async #existingCookieExpiration(req) {
|
|
156
|
+
const existingCookie = getCookieFromRequest(req);
|
|
157
|
+
if (!existingCookie) {
|
|
158
|
+
return void 0;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
const existingCredentials = await this.#auth.authenticate(
|
|
162
|
+
existingCookie,
|
|
163
|
+
{
|
|
164
|
+
allowLimitedAccess: true
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
if (!this.#auth.isPrincipal(existingCredentials, "user")) {
|
|
168
|
+
return void 0;
|
|
169
|
+
}
|
|
170
|
+
return existingCredentials.expiresAt;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
if (error.name === "AuthenticationError") {
|
|
173
|
+
return void 0;
|
|
174
|
+
}
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const httpAuthServiceFactory = backendPluginApi.createServiceFactory({
|
|
180
|
+
service: backendPluginApi.coreServices.httpAuth,
|
|
181
|
+
deps: {
|
|
182
|
+
auth: backendPluginApi.coreServices.auth,
|
|
183
|
+
discovery: backendPluginApi.coreServices.discovery,
|
|
184
|
+
plugin: backendPluginApi.coreServices.pluginMetadata
|
|
185
|
+
},
|
|
186
|
+
async factory({ auth, discovery, plugin }) {
|
|
187
|
+
return new DefaultHttpAuthService(auth, discovery, plugin.getId());
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
exports.httpAuthServiceFactory = httpAuthServiceFactory;
|
|
192
|
+
//# sourceMappingURL=httpAuthServiceFactory.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpAuthServiceFactory.cjs.js","sources":["../../../src/entrypoints/httpAuth/httpAuthServiceFactory.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 {\n AuthService,\n BackstageCredentials,\n BackstagePrincipalTypes,\n BackstageUserPrincipal,\n DiscoveryService,\n HttpAuthService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { AuthenticationError, NotAllowedError } from '@backstage/errors';\nimport { parse as parseCookie } from 'cookie';\nimport { Request, Response } from 'express';\n\nconst FIVE_MINUTES_MS = 5 * 60 * 1000;\n\nconst BACKSTAGE_AUTH_COOKIE = 'backstage-auth';\n\nfunction getTokenFromRequest(req: Request) {\n // TODO: support multiple auth headers (iterate rawHeaders)\n const authHeader = req.headers.authorization;\n if (typeof authHeader === 'string') {\n const matches = authHeader.match(/^Bearer[ ]+(\\S+)$/i);\n const token = matches?.[1];\n if (token) {\n return token;\n }\n }\n\n return undefined;\n}\n\nfunction getCookieFromRequest(req: Request) {\n const cookieHeader = req.headers.cookie;\n if (cookieHeader) {\n const cookies = parseCookie(cookieHeader);\n const token = cookies[BACKSTAGE_AUTH_COOKIE];\n if (token) {\n return token;\n }\n }\n\n return undefined;\n}\n\nfunction willExpireSoon(expiresAt: Date) {\n return Date.now() + FIVE_MINUTES_MS > expiresAt.getTime();\n}\n\nconst credentialsSymbol = Symbol('backstage-credentials');\nconst limitedCredentialsSymbol = Symbol('backstage-limited-credentials');\n\ntype RequestWithCredentials = Request & {\n [credentialsSymbol]?: Promise<BackstageCredentials>;\n [limitedCredentialsSymbol]?: Promise<BackstageCredentials>;\n};\n\nclass DefaultHttpAuthService implements HttpAuthService {\n readonly #auth: AuthService;\n readonly #discovery: DiscoveryService;\n readonly #pluginId: string;\n\n constructor(\n auth: AuthService,\n discovery: DiscoveryService,\n pluginId: string,\n ) {\n this.#auth = auth;\n this.#discovery = discovery;\n this.#pluginId = pluginId;\n }\n\n async #extractCredentialsFromRequest(req: Request) {\n const token = getTokenFromRequest(req);\n if (!token) {\n return await this.#auth.getNoneCredentials();\n }\n\n return await this.#auth.authenticate(token);\n }\n\n async #extractLimitedCredentialsFromRequest(req: Request) {\n const token = getTokenFromRequest(req);\n if (token) {\n return await this.#auth.authenticate(token, {\n allowLimitedAccess: true,\n });\n }\n\n const cookie = getCookieFromRequest(req);\n if (cookie) {\n return await this.#auth.authenticate(cookie, {\n allowLimitedAccess: true,\n });\n }\n\n return await this.#auth.getNoneCredentials();\n }\n\n async #getCredentials(req: RequestWithCredentials) {\n return (req[credentialsSymbol] ??=\n this.#extractCredentialsFromRequest(req));\n }\n\n async #getLimitedCredentials(req: RequestWithCredentials) {\n return (req[limitedCredentialsSymbol] ??=\n this.#extractLimitedCredentialsFromRequest(req));\n }\n\n async credentials<TAllowed extends keyof BackstagePrincipalTypes = 'unknown'>(\n req: Request,\n options?: {\n allow?: Array<TAllowed>;\n allowLimitedAccess?: boolean;\n },\n ): Promise<BackstageCredentials<BackstagePrincipalTypes[TAllowed]>> {\n // Limited and full credentials are treated as two separate cases, this lets\n // us avoid internal dependencies between the AuthService and\n // HttpAuthService implementations\n const credentials = options?.allowLimitedAccess\n ? await this.#getLimitedCredentials(req)\n : await this.#getCredentials(req);\n\n const allowed = options?.allow;\n if (!allowed) {\n return credentials as any;\n }\n\n if (this.#auth.isPrincipal(credentials, 'none')) {\n if (allowed.includes('none' as TAllowed)) {\n return credentials as any;\n }\n\n throw new AuthenticationError('Missing credentials');\n } else if (this.#auth.isPrincipal(credentials, 'user')) {\n if (allowed.includes('user' as TAllowed)) {\n return credentials as any;\n }\n\n throw new NotAllowedError(\n `This endpoint does not allow 'user' credentials`,\n );\n } else if (this.#auth.isPrincipal(credentials, 'service')) {\n if (allowed.includes('service' as TAllowed)) {\n return credentials as any;\n }\n\n throw new NotAllowedError(\n `This endpoint does not allow 'service' credentials`,\n );\n }\n\n throw new NotAllowedError(\n 'Unknown principal type, this should never happen',\n );\n }\n\n async issueUserCookie(\n res: Response,\n options?: { credentials?: BackstageCredentials },\n ): Promise<{ expiresAt: Date }> {\n if (res.headersSent) {\n throw new Error('Failed to issue user cookie, headers were already sent');\n }\n\n let credentials: BackstageCredentials<BackstageUserPrincipal>;\n if (options?.credentials) {\n if (this.#auth.isPrincipal(options.credentials, 'none')) {\n res.clearCookie(\n BACKSTAGE_AUTH_COOKIE,\n await this.#getCookieOptions(res.req),\n );\n return { expiresAt: new Date() };\n }\n if (!this.#auth.isPrincipal(options.credentials, 'user')) {\n throw new AuthenticationError(\n 'Refused to issue cookie for non-user principal',\n );\n }\n credentials = options.credentials;\n } else {\n credentials = await this.credentials(res.req, { allow: ['user'] });\n }\n\n const existingExpiresAt = await this.#existingCookieExpiration(res.req);\n if (existingExpiresAt && !willExpireSoon(existingExpiresAt)) {\n return { expiresAt: existingExpiresAt };\n }\n\n const { token, expiresAt } = await this.#auth.getLimitedUserToken(\n credentials,\n );\n if (!token) {\n throw new Error('User credentials is unexpectedly missing token');\n }\n\n res.cookie(BACKSTAGE_AUTH_COOKIE, token, {\n ...(await this.#getCookieOptions(res.req)),\n expires: expiresAt,\n });\n\n return { expiresAt };\n }\n\n async #getCookieOptions(_req: Request): Promise<{\n domain: string;\n httpOnly: true;\n secure: boolean;\n priority: 'high';\n sameSite: 'none' | 'lax';\n }> {\n // TODO: eventually we should read from `${req.protocol}://${req.hostname}`\n // once https://github.com/backstage/backstage/issues/24169 has landed\n const externalBaseUrlStr = await this.#discovery.getExternalBaseUrl(\n this.#pluginId,\n );\n const externalBaseUrl = new URL(externalBaseUrlStr);\n\n const secure =\n externalBaseUrl.protocol === 'https:' ||\n externalBaseUrl.hostname === 'localhost';\n\n return {\n domain: externalBaseUrl.hostname,\n httpOnly: true,\n secure,\n priority: 'high',\n sameSite: secure ? 'none' : 'lax',\n };\n }\n\n async #existingCookieExpiration(req: Request): Promise<Date | undefined> {\n const existingCookie = getCookieFromRequest(req);\n if (!existingCookie) {\n return undefined;\n }\n\n try {\n const existingCredentials = await this.#auth.authenticate(\n existingCookie,\n {\n allowLimitedAccess: true,\n },\n );\n if (!this.#auth.isPrincipal(existingCredentials, 'user')) {\n return undefined;\n }\n\n return existingCredentials.expiresAt;\n } catch (error) {\n if (error.name === 'AuthenticationError') {\n return undefined;\n }\n throw error;\n }\n }\n}\n\n/**\n * Authentication of HTTP requests.\n *\n * See {@link @backstage/code-plugin-api#HttpAuthService}\n * and {@link https://backstage.io/docs/backend-system/core-services/http-auth | the service docs}\n * for more information.\n *\n * @public\n */\nexport const httpAuthServiceFactory = createServiceFactory({\n service: coreServices.httpAuth,\n deps: {\n auth: coreServices.auth,\n discovery: coreServices.discovery,\n plugin: coreServices.pluginMetadata,\n },\n async factory({ auth, discovery, plugin }) {\n return new DefaultHttpAuthService(auth, discovery, plugin.getId());\n },\n});\n"],"names":["parseCookie","AuthenticationError","NotAllowedError","createServiceFactory","coreServices"],"mappings":";;;;;;AA8BA,MAAM,eAAA,GAAkB,IAAI,EAAK,GAAA,GAAA,CAAA;AAEjC,MAAM,qBAAwB,GAAA,gBAAA,CAAA;AAE9B,SAAS,oBAAoB,GAAc,EAAA;AAEzC,EAAM,MAAA,UAAA,GAAa,IAAI,OAAQ,CAAA,aAAA,CAAA;AAC/B,EAAI,IAAA,OAAO,eAAe,QAAU,EAAA;AAClC,IAAM,MAAA,OAAA,GAAU,UAAW,CAAA,KAAA,CAAM,oBAAoB,CAAA,CAAA;AACrD,IAAM,MAAA,KAAA,GAAQ,UAAU,CAAC,CAAA,CAAA;AACzB,IAAA,IAAI,KAAO,EAAA;AACT,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAAA,GACF;AAEA,EAAO,OAAA,KAAA,CAAA,CAAA;AACT,CAAA;AAEA,SAAS,qBAAqB,GAAc,EAAA;AAC1C,EAAM,MAAA,YAAA,GAAe,IAAI,OAAQ,CAAA,MAAA,CAAA;AACjC,EAAA,IAAI,YAAc,EAAA;AAChB,IAAM,MAAA,OAAA,GAAUA,aAAY,YAAY,CAAA,CAAA;AACxC,IAAM,MAAA,KAAA,GAAQ,QAAQ,qBAAqB,CAAA,CAAA;AAC3C,IAAA,IAAI,KAAO,EAAA;AACT,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAAA,GACF;AAEA,EAAO,OAAA,KAAA,CAAA,CAAA;AACT,CAAA;AAEA,SAAS,eAAe,SAAiB,EAAA;AACvC,EAAA,OAAO,IAAK,CAAA,GAAA,EAAQ,GAAA,eAAA,GAAkB,UAAU,OAAQ,EAAA,CAAA;AAC1D,CAAA;AAEA,MAAM,iBAAA,GAAoB,OAAO,uBAAuB,CAAA,CAAA;AACxD,MAAM,wBAAA,GAA2B,OAAO,+BAA+B,CAAA,CAAA;AAOvE,MAAM,sBAAkD,CAAA;AAAA,EAC7C,KAAA,CAAA;AAAA,EACA,UAAA,CAAA;AAAA,EACA,SAAA,CAAA;AAAA,EAET,WAAA,CACE,IACA,EAAA,SAAA,EACA,QACA,EAAA;AACA,IAAA,IAAA,CAAK,KAAQ,GAAA,IAAA,CAAA;AACb,IAAA,IAAA,CAAK,UAAa,GAAA,SAAA,CAAA;AAClB,IAAA,IAAA,CAAK,SAAY,GAAA,QAAA,CAAA;AAAA,GACnB;AAAA,EAEA,MAAM,+BAA+B,GAAc,EAAA;AACjD,IAAM,MAAA,KAAA,GAAQ,oBAAoB,GAAG,CAAA,CAAA;AACrC,IAAA,IAAI,CAAC,KAAO,EAAA;AACV,MAAO,OAAA,MAAM,IAAK,CAAA,KAAA,CAAM,kBAAmB,EAAA,CAAA;AAAA,KAC7C;AAEA,IAAA,OAAO,MAAM,IAAA,CAAK,KAAM,CAAA,YAAA,CAAa,KAAK,CAAA,CAAA;AAAA,GAC5C;AAAA,EAEA,MAAM,sCAAsC,GAAc,EAAA;AACxD,IAAM,MAAA,KAAA,GAAQ,oBAAoB,GAAG,CAAA,CAAA;AACrC,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,OAAO,MAAM,IAAA,CAAK,KAAM,CAAA,YAAA,CAAa,KAAO,EAAA;AAAA,QAC1C,kBAAoB,EAAA,IAAA;AAAA,OACrB,CAAA,CAAA;AAAA,KACH;AAEA,IAAM,MAAA,MAAA,GAAS,qBAAqB,GAAG,CAAA,CAAA;AACvC,IAAA,IAAI,MAAQ,EAAA;AACV,MAAA,OAAO,MAAM,IAAA,CAAK,KAAM,CAAA,YAAA,CAAa,MAAQ,EAAA;AAAA,QAC3C,kBAAoB,EAAA,IAAA;AAAA,OACrB,CAAA,CAAA;AAAA,KACH;AAEA,IAAO,OAAA,MAAM,IAAK,CAAA,KAAA,CAAM,kBAAmB,EAAA,CAAA;AAAA,GAC7C;AAAA,EAEA,MAAM,gBAAgB,GAA6B,EAAA;AACjD,IAAA,OAAQ,GAAI,CAAA,iBAAiB,CAC3B,KAAA,IAAA,CAAK,+BAA+B,GAAG,CAAA,CAAA;AAAA,GAC3C;AAAA,EAEA,MAAM,uBAAuB,GAA6B,EAAA;AACxD,IAAA,OAAQ,GAAI,CAAA,wBAAwB,CAClC,KAAA,IAAA,CAAK,sCAAsC,GAAG,CAAA,CAAA;AAAA,GAClD;AAAA,EAEA,MAAM,WACJ,CAAA,GAAA,EACA,OAIkE,EAAA;AAIlE,IAAM,MAAA,WAAA,GAAc,OAAS,EAAA,kBAAA,GACzB,MAAM,IAAA,CAAK,sBAAuB,CAAA,GAAG,CACrC,GAAA,MAAM,IAAK,CAAA,eAAA,CAAgB,GAAG,CAAA,CAAA;AAElC,IAAA,MAAM,UAAU,OAAS,EAAA,KAAA,CAAA;AACzB,IAAA,IAAI,CAAC,OAAS,EAAA;AACZ,MAAO,OAAA,WAAA,CAAA;AAAA,KACT;AAEA,IAAA,IAAI,IAAK,CAAA,KAAA,CAAM,WAAY,CAAA,WAAA,EAAa,MAAM,CAAG,EAAA;AAC/C,MAAI,IAAA,OAAA,CAAQ,QAAS,CAAA,MAAkB,CAAG,EAAA;AACxC,QAAO,OAAA,WAAA,CAAA;AAAA,OACT;AAEA,MAAM,MAAA,IAAIC,2BAAoB,qBAAqB,CAAA,CAAA;AAAA,eAC1C,IAAK,CAAA,KAAA,CAAM,WAAY,CAAA,WAAA,EAAa,MAAM,CAAG,EAAA;AACtD,MAAI,IAAA,OAAA,CAAQ,QAAS,CAAA,MAAkB,CAAG,EAAA;AACxC,QAAO,OAAA,WAAA,CAAA;AAAA,OACT;AAEA,MAAA,MAAM,IAAIC,sBAAA;AAAA,QACR,CAAA,+CAAA,CAAA;AAAA,OACF,CAAA;AAAA,eACS,IAAK,CAAA,KAAA,CAAM,WAAY,CAAA,WAAA,EAAa,SAAS,CAAG,EAAA;AACzD,MAAI,IAAA,OAAA,CAAQ,QAAS,CAAA,SAAqB,CAAG,EAAA;AAC3C,QAAO,OAAA,WAAA,CAAA;AAAA,OACT;AAEA,MAAA,MAAM,IAAIA,sBAAA;AAAA,QACR,CAAA,kDAAA,CAAA;AAAA,OACF,CAAA;AAAA,KACF;AAEA,IAAA,MAAM,IAAIA,sBAAA;AAAA,MACR,kDAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,MAAM,eACJ,CAAA,GAAA,EACA,OAC8B,EAAA;AAC9B,IAAA,IAAI,IAAI,WAAa,EAAA;AACnB,MAAM,MAAA,IAAI,MAAM,wDAAwD,CAAA,CAAA;AAAA,KAC1E;AAEA,IAAI,IAAA,WAAA,CAAA;AACJ,IAAA,IAAI,SAAS,WAAa,EAAA;AACxB,MAAA,IAAI,KAAK,KAAM,CAAA,WAAA,CAAY,OAAQ,CAAA,WAAA,EAAa,MAAM,CAAG,EAAA;AACvD,QAAI,GAAA,CAAA,WAAA;AAAA,UACF,qBAAA;AAAA,UACA,MAAM,IAAA,CAAK,iBAAkB,CAAA,GAAA,CAAI,GAAG,CAAA;AAAA,SACtC,CAAA;AACA,QAAA,OAAO,EAAE,SAAA,kBAAe,IAAA,IAAA,EAAO,EAAA,CAAA;AAAA,OACjC;AACA,MAAA,IAAI,CAAC,IAAK,CAAA,KAAA,CAAM,YAAY,OAAQ,CAAA,WAAA,EAAa,MAAM,CAAG,EAAA;AACxD,QAAA,MAAM,IAAID,0BAAA;AAAA,UACR,gDAAA;AAAA,SACF,CAAA;AAAA,OACF;AACA,MAAA,WAAA,GAAc,OAAQ,CAAA,WAAA,CAAA;AAAA,KACjB,MAAA;AACL,MAAc,WAAA,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,GAAI,CAAA,GAAA,EAAK,EAAE,KAAO,EAAA,CAAC,MAAM,CAAA,EAAG,CAAA,CAAA;AAAA,KACnE;AAEA,IAAA,MAAM,iBAAoB,GAAA,MAAM,IAAK,CAAA,yBAAA,CAA0B,IAAI,GAAG,CAAA,CAAA;AACtE,IAAA,IAAI,iBAAqB,IAAA,CAAC,cAAe,CAAA,iBAAiB,CAAG,EAAA;AAC3D,MAAO,OAAA,EAAE,WAAW,iBAAkB,EAAA,CAAA;AAAA,KACxC;AAEA,IAAA,MAAM,EAAE,KAAO,EAAA,SAAA,EAAc,GAAA,MAAM,KAAK,KAAM,CAAA,mBAAA;AAAA,MAC5C,WAAA;AAAA,KACF,CAAA;AACA,IAAA,IAAI,CAAC,KAAO,EAAA;AACV,MAAM,MAAA,IAAI,MAAM,gDAAgD,CAAA,CAAA;AAAA,KAClE;AAEA,IAAI,GAAA,CAAA,MAAA,CAAO,uBAAuB,KAAO,EAAA;AAAA,MACvC,GAAI,MAAM,IAAK,CAAA,iBAAA,CAAkB,IAAI,GAAG,CAAA;AAAA,MACxC,OAAS,EAAA,SAAA;AAAA,KACV,CAAA,CAAA;AAED,IAAA,OAAO,EAAE,SAAU,EAAA,CAAA;AAAA,GACrB;AAAA,EAEA,MAAM,kBAAkB,IAMrB,EAAA;AAGD,IAAM,MAAA,kBAAA,GAAqB,MAAM,IAAA,CAAK,UAAW,CAAA,kBAAA;AAAA,MAC/C,IAAK,CAAA,SAAA;AAAA,KACP,CAAA;AACA,IAAM,MAAA,eAAA,GAAkB,IAAI,GAAA,CAAI,kBAAkB,CAAA,CAAA;AAElD,IAAA,MAAM,MACJ,GAAA,eAAA,CAAgB,QAAa,KAAA,QAAA,IAC7B,gBAAgB,QAAa,KAAA,WAAA,CAAA;AAE/B,IAAO,OAAA;AAAA,MACL,QAAQ,eAAgB,CAAA,QAAA;AAAA,MACxB,QAAU,EAAA,IAAA;AAAA,MACV,MAAA;AAAA,MACA,QAAU,EAAA,MAAA;AAAA,MACV,QAAA,EAAU,SAAS,MAAS,GAAA,KAAA;AAAA,KAC9B,CAAA;AAAA,GACF;AAAA,EAEA,MAAM,0BAA0B,GAAyC,EAAA;AACvE,IAAM,MAAA,cAAA,GAAiB,qBAAqB,GAAG,CAAA,CAAA;AAC/C,IAAA,IAAI,CAAC,cAAgB,EAAA;AACnB,MAAO,OAAA,KAAA,CAAA,CAAA;AAAA,KACT;AAEA,IAAI,IAAA;AACF,MAAM,MAAA,mBAAA,GAAsB,MAAM,IAAA,CAAK,KAAM,CAAA,YAAA;AAAA,QAC3C,cAAA;AAAA,QACA;AAAA,UACE,kBAAoB,EAAA,IAAA;AAAA,SACtB;AAAA,OACF,CAAA;AACA,MAAA,IAAI,CAAC,IAAK,CAAA,KAAA,CAAM,WAAY,CAAA,mBAAA,EAAqB,MAAM,CAAG,EAAA;AACxD,QAAO,OAAA,KAAA,CAAA,CAAA;AAAA,OACT;AAEA,MAAA,OAAO,mBAAoB,CAAA,SAAA,CAAA;AAAA,aACpB,KAAO,EAAA;AACd,MAAI,IAAA,KAAA,CAAM,SAAS,qBAAuB,EAAA;AACxC,QAAO,OAAA,KAAA,CAAA,CAAA;AAAA,OACT;AACA,MAAM,MAAA,KAAA,CAAA;AAAA,KACR;AAAA,GACF;AACF,CAAA;AAWO,MAAM,yBAAyBE,qCAAqB,CAAA;AAAA,EACzD,SAASC,6BAAa,CAAA,QAAA;AAAA,EACtB,IAAM,EAAA;AAAA,IACJ,MAAMA,6BAAa,CAAA,IAAA;AAAA,IACnB,WAAWA,6BAAa,CAAA,SAAA;AAAA,IACxB,QAAQA,6BAAa,CAAA,cAAA;AAAA,GACvB;AAAA,EACA,MAAM,OAAQ,CAAA,EAAE,IAAM,EAAA,SAAA,EAAW,QAAU,EAAA;AACzC,IAAA,OAAO,IAAI,sBAAuB,CAAA,IAAA,EAAM,SAAW,EAAA,MAAA,CAAO,OAAO,CAAA,CAAA;AAAA,GACnE;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Router = require('express-promise-router');
|
|
4
|
+
|
|
5
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
8
|
+
|
|
9
|
+
function createAuthIntegrationRouter(options) {
|
|
10
|
+
const router = Router__default.default();
|
|
11
|
+
router.get("/.backstage/auth/v1/jwks.json", async (_req, res) => {
|
|
12
|
+
const { keys } = await options.auth.listPublicServiceKeys();
|
|
13
|
+
res.json({ keys });
|
|
14
|
+
});
|
|
15
|
+
return router;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.createAuthIntegrationRouter = createAuthIntegrationRouter;
|
|
19
|
+
//# sourceMappingURL=createAuthIntegrationRouter.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createAuthIntegrationRouter.cjs.js","sources":["../../../src/entrypoints/httpRouter/createAuthIntegrationRouter.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 } from '@backstage/backend-plugin-api';\nimport express from 'express';\nimport Router from 'express-promise-router';\n\nexport function createAuthIntegrationRouter(options: {\n auth: AuthService;\n}): express.Router {\n const router = Router();\n\n router.get('/.backstage/auth/v1/jwks.json', async (_req, res) => {\n const { keys } = await options.auth.listPublicServiceKeys();\n\n res.json({ keys });\n });\n\n return router;\n}\n"],"names":["Router"],"mappings":";;;;;;;;AAoBO,SAAS,4BAA4B,OAEzB,EAAA;AACjB,EAAA,MAAM,SAASA,uBAAO,EAAA,CAAA;AAEtB,EAAA,MAAA,CAAO,GAAI,CAAA,+BAAA,EAAiC,OAAO,IAAA,EAAM,GAAQ,KAAA;AAC/D,IAAA,MAAM,EAAE,IAAK,EAAA,GAAI,MAAM,OAAA,CAAQ,KAAK,qBAAsB,EAAA,CAAA;AAE1D,IAAI,GAAA,CAAA,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,CAAA;AAAA,GAClB,CAAA,CAAA;AAED,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Router = require('express-promise-router');
|
|
4
|
+
|
|
5
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
8
|
+
|
|
9
|
+
const WELL_KNOWN_COOKIE_PATH_V1 = "/.backstage/auth/v1/cookie";
|
|
10
|
+
function createCookieAuthRefreshMiddleware(options) {
|
|
11
|
+
const { auth, httpAuth } = options;
|
|
12
|
+
const router = Router__default.default();
|
|
13
|
+
router.get(WELL_KNOWN_COOKIE_PATH_V1, async (_, res) => {
|
|
14
|
+
const { expiresAt } = await httpAuth.issueUserCookie(res);
|
|
15
|
+
res.json({ expiresAt: expiresAt.toISOString() });
|
|
16
|
+
});
|
|
17
|
+
router.delete(WELL_KNOWN_COOKIE_PATH_V1, async (_, res) => {
|
|
18
|
+
const credentials = await auth.getNoneCredentials();
|
|
19
|
+
await httpAuth.issueUserCookie(res, { credentials });
|
|
20
|
+
res.status(204).end();
|
|
21
|
+
});
|
|
22
|
+
return router;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.createCookieAuthRefreshMiddleware = createCookieAuthRefreshMiddleware;
|
|
26
|
+
//# sourceMappingURL=createCookieAuthRefreshMiddleware.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createCookieAuthRefreshMiddleware.cjs.js","sources":["../../../src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.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, HttpAuthService } from '@backstage/backend-plugin-api';\nimport Router from 'express-promise-router';\n\nconst WELL_KNOWN_COOKIE_PATH_V1 = '/.backstage/auth/v1/cookie';\n\n/**\n * @public\n * Creates a middleware that can be used to refresh the cookie for the user.\n */\nexport function createCookieAuthRefreshMiddleware(options: {\n auth: AuthService;\n httpAuth: HttpAuthService;\n}) {\n const { auth, httpAuth } = options;\n const router = Router();\n\n // Endpoint that sets the cookie for the user\n router.get(WELL_KNOWN_COOKIE_PATH_V1, async (_, res) => {\n const { expiresAt } = await httpAuth.issueUserCookie(res);\n res.json({ expiresAt: expiresAt.toISOString() });\n });\n\n // Endpoint that removes the cookie for the user\n router.delete(WELL_KNOWN_COOKIE_PATH_V1, async (_, res) => {\n const credentials = await auth.getNoneCredentials();\n await httpAuth.issueUserCookie(res, { credentials });\n res.status(204).end();\n });\n\n return router;\n}\n"],"names":["Router"],"mappings":";;;;;;;;AAmBA,MAAM,yBAA4B,GAAA,4BAAA,CAAA;AAM3B,SAAS,kCAAkC,OAG/C,EAAA;AACD,EAAM,MAAA,EAAE,IAAM,EAAA,QAAA,EAAa,GAAA,OAAA,CAAA;AAC3B,EAAA,MAAM,SAASA,uBAAO,EAAA,CAAA;AAGtB,EAAA,MAAA,CAAO,GAAI,CAAA,yBAAA,EAA2B,OAAO,CAAA,EAAG,GAAQ,KAAA;AACtD,IAAA,MAAM,EAAE,SAAU,EAAA,GAAI,MAAM,QAAA,CAAS,gBAAgB,GAAG,CAAA,CAAA;AACxD,IAAA,GAAA,CAAI,KAAK,EAAE,SAAA,EAAW,SAAU,CAAA,WAAA,IAAe,CAAA,CAAA;AAAA,GAChD,CAAA,CAAA;AAGD,EAAA,MAAA,CAAO,MAAO,CAAA,yBAAA,EAA2B,OAAO,CAAA,EAAG,GAAQ,KAAA;AACzD,IAAM,MAAA,WAAA,GAAc,MAAM,IAAA,CAAK,kBAAmB,EAAA,CAAA;AAClD,IAAA,MAAM,QAAS,CAAA,eAAA,CAAgB,GAAK,EAAA,EAAE,aAAa,CAAA,CAAA;AACnD,IAAI,GAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,GAAI,EAAA,CAAA;AAAA,GACrB,CAAA,CAAA;AAED,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pathToRegexp = require('path-to-regexp');
|
|
4
|
+
|
|
5
|
+
function createPathPolicyPredicate(policyPath) {
|
|
6
|
+
if (policyPath === "/" || policyPath === "*") {
|
|
7
|
+
return () => true;
|
|
8
|
+
}
|
|
9
|
+
const { regexp: pathRegex } = pathToRegexp.pathToRegexp(policyPath, {
|
|
10
|
+
end: false
|
|
11
|
+
});
|
|
12
|
+
return (path) => {
|
|
13
|
+
return pathRegex.test(path);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function createCredentialsBarrier(options) {
|
|
17
|
+
const { httpAuth, config } = options;
|
|
18
|
+
const disableDefaultAuthPolicy = config.getOptionalBoolean(
|
|
19
|
+
"backend.auth.dangerouslyDisableDefaultAuthPolicy"
|
|
20
|
+
);
|
|
21
|
+
if (disableDefaultAuthPolicy) {
|
|
22
|
+
return {
|
|
23
|
+
middleware: (_req, _res, next) => next(),
|
|
24
|
+
addAuthPolicy: () => {
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const unauthenticatedPredicates = new Array();
|
|
29
|
+
const cookiePredicates = new Array();
|
|
30
|
+
const middleware = (req, _, next) => {
|
|
31
|
+
const allowsUnauthenticated = unauthenticatedPredicates.some(
|
|
32
|
+
(predicate) => predicate(req.path)
|
|
33
|
+
);
|
|
34
|
+
if (allowsUnauthenticated) {
|
|
35
|
+
next();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const allowsCookie = cookiePredicates.some(
|
|
39
|
+
(predicate) => predicate(req.path)
|
|
40
|
+
);
|
|
41
|
+
httpAuth.credentials(req, {
|
|
42
|
+
allow: ["user", "service"],
|
|
43
|
+
allowLimitedAccess: allowsCookie
|
|
44
|
+
}).then(
|
|
45
|
+
() => next(),
|
|
46
|
+
(err) => next(err)
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
const addAuthPolicy = (policy) => {
|
|
50
|
+
if (policy.allow === "unauthenticated") {
|
|
51
|
+
unauthenticatedPredicates.push(createPathPolicyPredicate(policy.path));
|
|
52
|
+
} else if (policy.allow === "user-cookie") {
|
|
53
|
+
cookiePredicates.push(createPathPolicyPredicate(policy.path));
|
|
54
|
+
} else {
|
|
55
|
+
throw new Error("Invalid auth policy");
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
return { middleware, addAuthPolicy };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
exports.createCredentialsBarrier = createCredentialsBarrier;
|
|
62
|
+
exports.createPathPolicyPredicate = createPathPolicyPredicate;
|
|
63
|
+
//# sourceMappingURL=createCredentialsBarrier.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createCredentialsBarrier.cjs.js","sources":["../../../src/entrypoints/httpRouter/createCredentialsBarrier.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 {\n HttpAuthService,\n HttpRouterServiceAuthPolicy,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { RequestHandler } from 'express';\nimport { pathToRegexp } from 'path-to-regexp';\n\nexport function createPathPolicyPredicate(policyPath: string) {\n if (policyPath === '/' || policyPath === '*') {\n return () => true;\n }\n\n const { regexp: pathRegex } = pathToRegexp(policyPath, {\n end: false,\n });\n\n return (path: string): boolean => {\n return pathRegex.test(path);\n };\n}\n\nexport function createCredentialsBarrier(options: {\n httpAuth: HttpAuthService;\n config: RootConfigService;\n}): {\n middleware: RequestHandler;\n addAuthPolicy: (policy: HttpRouterServiceAuthPolicy) => void;\n} {\n const { httpAuth, config } = options;\n\n const disableDefaultAuthPolicy = config.getOptionalBoolean(\n 'backend.auth.dangerouslyDisableDefaultAuthPolicy',\n );\n\n if (disableDefaultAuthPolicy) {\n return {\n middleware: (_req, _res, next) => next(),\n addAuthPolicy: () => {},\n };\n }\n\n const unauthenticatedPredicates = new Array<(path: string) => boolean>();\n const cookiePredicates = new Array<(path: string) => boolean>();\n\n const middleware: RequestHandler = (req, _, next) => {\n const allowsUnauthenticated = unauthenticatedPredicates.some(predicate =>\n predicate(req.path),\n );\n\n if (allowsUnauthenticated) {\n next();\n return;\n }\n\n const allowsCookie = cookiePredicates.some(predicate =>\n predicate(req.path),\n );\n\n httpAuth\n .credentials(req, {\n allow: ['user', 'service'],\n allowLimitedAccess: allowsCookie,\n })\n .then(\n () => next(),\n err => next(err),\n );\n };\n\n const addAuthPolicy = (policy: HttpRouterServiceAuthPolicy) => {\n if (policy.allow === 'unauthenticated') {\n unauthenticatedPredicates.push(createPathPolicyPredicate(policy.path));\n } else if (policy.allow === 'user-cookie') {\n cookiePredicates.push(createPathPolicyPredicate(policy.path));\n } else {\n throw new Error('Invalid auth policy');\n }\n };\n\n return { middleware, addAuthPolicy };\n}\n"],"names":["pathToRegexp"],"mappings":";;;;AAwBO,SAAS,0BAA0B,UAAoB,EAAA;AAC5D,EAAI,IAAA,UAAA,KAAe,GAAO,IAAA,UAAA,KAAe,GAAK,EAAA;AAC5C,IAAA,OAAO,MAAM,IAAA,CAAA;AAAA,GACf;AAEA,EAAA,MAAM,EAAE,MAAA,EAAQ,SAAU,EAAA,GAAIA,0BAAa,UAAY,EAAA;AAAA,IACrD,GAAK,EAAA,KAAA;AAAA,GACN,CAAA,CAAA;AAED,EAAA,OAAO,CAAC,IAA0B,KAAA;AAChC,IAAO,OAAA,SAAA,CAAU,KAAK,IAAI,CAAA,CAAA;AAAA,GAC5B,CAAA;AACF,CAAA;AAEO,SAAS,yBAAyB,OAMvC,EAAA;AACA,EAAM,MAAA,EAAE,QAAU,EAAA,MAAA,EAAW,GAAA,OAAA,CAAA;AAE7B,EAAA,MAAM,2BAA2B,MAAO,CAAA,kBAAA;AAAA,IACtC,kDAAA;AAAA,GACF,CAAA;AAEA,EAAA,IAAI,wBAA0B,EAAA;AAC5B,IAAO,OAAA;AAAA,MACL,UAAY,EAAA,CAAC,IAAM,EAAA,IAAA,EAAM,SAAS,IAAK,EAAA;AAAA,MACvC,eAAe,MAAM;AAAA,OAAC;AAAA,KACxB,CAAA;AAAA,GACF;AAEA,EAAM,MAAA,yBAAA,GAA4B,IAAI,KAAiC,EAAA,CAAA;AACvE,EAAM,MAAA,gBAAA,GAAmB,IAAI,KAAiC,EAAA,CAAA;AAE9D,EAAA,MAAM,UAA6B,GAAA,CAAC,GAAK,EAAA,CAAA,EAAG,IAAS,KAAA;AACnD,IAAA,MAAM,wBAAwB,yBAA0B,CAAA,IAAA;AAAA,MAAK,CAAA,SAAA,KAC3D,SAAU,CAAA,GAAA,CAAI,IAAI,CAAA;AAAA,KACpB,CAAA;AAEA,IAAA,IAAI,qBAAuB,EAAA;AACzB,MAAK,IAAA,EAAA,CAAA;AACL,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,MAAM,eAAe,gBAAiB,CAAA,IAAA;AAAA,MAAK,CAAA,SAAA,KACzC,SAAU,CAAA,GAAA,CAAI,IAAI,CAAA;AAAA,KACpB,CAAA;AAEA,IAAA,QAAA,CACG,YAAY,GAAK,EAAA;AAAA,MAChB,KAAA,EAAO,CAAC,MAAA,EAAQ,SAAS,CAAA;AAAA,MACzB,kBAAoB,EAAA,YAAA;AAAA,KACrB,CACA,CAAA,IAAA;AAAA,MACC,MAAM,IAAK,EAAA;AAAA,MACX,CAAA,GAAA,KAAO,KAAK,GAAG,CAAA;AAAA,KACjB,CAAA;AAAA,GACJ,CAAA;AAEA,EAAM,MAAA,aAAA,GAAgB,CAAC,MAAwC,KAAA;AAC7D,IAAI,IAAA,MAAA,CAAO,UAAU,iBAAmB,EAAA;AACtC,MAAA,yBAAA,CAA0B,IAAK,CAAA,yBAAA,CAA0B,MAAO,CAAA,IAAI,CAAC,CAAA,CAAA;AAAA,KACvE,MAAA,IAAW,MAAO,CAAA,KAAA,KAAU,aAAe,EAAA;AACzC,MAAA,gBAAA,CAAiB,IAAK,CAAA,yBAAA,CAA0B,MAAO,CAAA,IAAI,CAAC,CAAA,CAAA;AAAA,KACvD,MAAA;AACL,MAAM,MAAA,IAAI,MAAM,qBAAqB,CAAA,CAAA;AAAA,KACvC;AAAA,GACF,CAAA;AAEA,EAAO,OAAA,EAAE,YAAY,aAAc,EAAA,CAAA;AACrC;;;;;"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var errors = require('@backstage/errors');
|
|
4
|
+
var types = require('@backstage/types');
|
|
5
|
+
|
|
6
|
+
const DEFAULT_TIMEOUT = { seconds: 5 };
|
|
7
|
+
function createLifecycleMiddleware(options) {
|
|
8
|
+
const { lifecycle, startupRequestPauseTimeout = DEFAULT_TIMEOUT } = options;
|
|
9
|
+
let state = "init";
|
|
10
|
+
const waiting = /* @__PURE__ */ new Set();
|
|
11
|
+
lifecycle.addStartupHook(async () => {
|
|
12
|
+
if (state === "init") {
|
|
13
|
+
state = "up";
|
|
14
|
+
for (const item of waiting) {
|
|
15
|
+
clearTimeout(item.timeout);
|
|
16
|
+
item.next();
|
|
17
|
+
}
|
|
18
|
+
waiting.clear();
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
lifecycle.addShutdownHook(async () => {
|
|
22
|
+
state = "down";
|
|
23
|
+
for (const item of waiting) {
|
|
24
|
+
clearTimeout(item.timeout);
|
|
25
|
+
item.next(new errors.ServiceUnavailableError("Service is shutting down"));
|
|
26
|
+
}
|
|
27
|
+
waiting.clear();
|
|
28
|
+
});
|
|
29
|
+
const timeoutMs = types.durationToMilliseconds(startupRequestPauseTimeout);
|
|
30
|
+
return (_req, _res, next) => {
|
|
31
|
+
if (state === "up") {
|
|
32
|
+
next();
|
|
33
|
+
return;
|
|
34
|
+
} else if (state === "down") {
|
|
35
|
+
next(new errors.ServiceUnavailableError("Service is shutting down"));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const item = {
|
|
39
|
+
next,
|
|
40
|
+
timeout: setTimeout(() => {
|
|
41
|
+
if (waiting.delete(item)) {
|
|
42
|
+
next(new errors.ServiceUnavailableError("Service has not started up yet"));
|
|
43
|
+
}
|
|
44
|
+
}, timeoutMs)
|
|
45
|
+
};
|
|
46
|
+
waiting.add(item);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
exports.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
|
|
51
|
+
exports.createLifecycleMiddleware = createLifecycleMiddleware;
|
|
52
|
+
//# sourceMappingURL=createLifecycleMiddleware.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createLifecycleMiddleware.cjs.js","sources":["../../../src/entrypoints/httpRouter/createLifecycleMiddleware.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 { LifecycleService } from '@backstage/backend-plugin-api';\nimport { ServiceUnavailableError } from '@backstage/errors';\nimport { HumanDuration, durationToMilliseconds } from '@backstage/types';\nimport { RequestHandler } from 'express';\n\nexport const DEFAULT_TIMEOUT = { seconds: 5 };\n\n/**\n * Options for {@link createLifecycleMiddleware}.\n * @internal\n */\nexport interface LifecycleMiddlewareOptions {\n lifecycle: LifecycleService;\n /**\n * The maximum time that paused requests will wait for the service to start, before returning an error.\n *\n * Defaults to 5 seconds.\n */\n startupRequestPauseTimeout?: HumanDuration;\n}\n\n/**\n * Creates a middleware that pauses requests until the service has started.\n *\n * @remarks\n *\n * Requests that arrive before the service has started will be paused until startup is complete.\n * If the service does not start within the provided timeout, the request will be rejected with a\n * {@link @backstage/errors#ServiceUnavailableError}.\n *\n * If the service is shutting down, all requests will be rejected with a\n * {@link @backstage/errors#ServiceUnavailableError}.\n *\n * @internal\n */\nexport function createLifecycleMiddleware(\n options: LifecycleMiddlewareOptions,\n): RequestHandler {\n const { lifecycle, startupRequestPauseTimeout = DEFAULT_TIMEOUT } = options;\n\n let state: 'init' | 'up' | 'down' = 'init';\n const waiting = new Set<{\n next: (err?: Error) => void;\n timeout: NodeJS.Timeout;\n }>();\n\n lifecycle.addStartupHook(async () => {\n if (state === 'init') {\n state = 'up';\n for (const item of waiting) {\n clearTimeout(item.timeout);\n item.next();\n }\n waiting.clear();\n }\n });\n\n lifecycle.addShutdownHook(async () => {\n state = 'down';\n\n for (const item of waiting) {\n clearTimeout(item.timeout);\n item.next(new ServiceUnavailableError('Service is shutting down'));\n }\n waiting.clear();\n });\n\n const timeoutMs = durationToMilliseconds(startupRequestPauseTimeout);\n\n return (_req, _res, next) => {\n if (state === 'up') {\n next();\n return;\n } else if (state === 'down') {\n next(new ServiceUnavailableError('Service is shutting down'));\n return;\n }\n\n const item = {\n next,\n timeout: setTimeout(() => {\n if (waiting.delete(item)) {\n next(new ServiceUnavailableError('Service has not started up yet'));\n }\n }, timeoutMs),\n };\n\n waiting.add(item);\n };\n}\n"],"names":["ServiceUnavailableError","durationToMilliseconds"],"mappings":";;;;;AAqBa,MAAA,eAAA,GAAkB,EAAE,OAAA,EAAS,CAAE,GAAA;AA8BrC,SAAS,0BACd,OACgB,EAAA;AAChB,EAAA,MAAM,EAAE,SAAA,EAAW,0BAA6B,GAAA,eAAA,EAAoB,GAAA,OAAA,CAAA;AAEpE,EAAA,IAAI,KAAgC,GAAA,MAAA,CAAA;AACpC,EAAM,MAAA,OAAA,uBAAc,GAGjB,EAAA,CAAA;AAEH,EAAA,SAAA,CAAU,eAAe,YAAY;AACnC,IAAA,IAAI,UAAU,MAAQ,EAAA;AACpB,MAAQ,KAAA,GAAA,IAAA,CAAA;AACR,MAAA,KAAA,MAAW,QAAQ,OAAS,EAAA;AAC1B,QAAA,YAAA,CAAa,KAAK,OAAO,CAAA,CAAA;AACzB,QAAA,IAAA,CAAK,IAAK,EAAA,CAAA;AAAA,OACZ;AACA,MAAA,OAAA,CAAQ,KAAM,EAAA,CAAA;AAAA,KAChB;AAAA,GACD,CAAA,CAAA;AAED,EAAA,SAAA,CAAU,gBAAgB,YAAY;AACpC,IAAQ,KAAA,GAAA,MAAA,CAAA;AAER,IAAA,KAAA,MAAW,QAAQ,OAAS,EAAA;AAC1B,MAAA,YAAA,CAAa,KAAK,OAAO,CAAA,CAAA;AACzB,MAAA,IAAA,CAAK,IAAK,CAAA,IAAIA,8BAAwB,CAAA,0BAA0B,CAAC,CAAA,CAAA;AAAA,KACnE;AACA,IAAA,OAAA,CAAQ,KAAM,EAAA,CAAA;AAAA,GACf,CAAA,CAAA;AAED,EAAM,MAAA,SAAA,GAAYC,6BAAuB,0BAA0B,CAAA,CAAA;AAEnE,EAAO,OAAA,CAAC,IAAM,EAAA,IAAA,EAAM,IAAS,KAAA;AAC3B,IAAA,IAAI,UAAU,IAAM,EAAA;AAClB,MAAK,IAAA,EAAA,CAAA;AACL,MAAA,OAAA;AAAA,KACF,MAAA,IAAW,UAAU,MAAQ,EAAA;AAC3B,MAAK,IAAA,CAAA,IAAID,8BAAwB,CAAA,0BAA0B,CAAC,CAAA,CAAA;AAC5D,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,MAAM,IAAO,GAAA;AAAA,MACX,IAAA;AAAA,MACA,OAAA,EAAS,WAAW,MAAM;AACxB,QAAI,IAAA,OAAA,CAAQ,MAAO,CAAA,IAAI,CAAG,EAAA;AACxB,UAAK,IAAA,CAAA,IAAIA,8BAAwB,CAAA,gCAAgC,CAAC,CAAA,CAAA;AAAA,SACpE;AAAA,SACC,SAAS,CAAA;AAAA,KACd,CAAA;AAEA,IAAA,OAAA,CAAQ,IAAI,IAAI,CAAA,CAAA;AAAA,GAClB,CAAA;AACF;;;;;"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Router = require('express-promise-router');
|
|
4
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
5
|
+
var createLifecycleMiddleware = require('./createLifecycleMiddleware.cjs.js');
|
|
6
|
+
var createCredentialsBarrier = require('./createCredentialsBarrier.cjs.js');
|
|
7
|
+
var createAuthIntegrationRouter = require('./createAuthIntegrationRouter.cjs.js');
|
|
8
|
+
var createCookieAuthRefreshMiddleware = require('./createCookieAuthRefreshMiddleware.cjs.js');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
13
|
+
|
|
14
|
+
const httpRouterServiceFactory = backendPluginApi.createServiceFactory({
|
|
15
|
+
service: backendPluginApi.coreServices.httpRouter,
|
|
16
|
+
initialization: "always",
|
|
17
|
+
deps: {
|
|
18
|
+
plugin: backendPluginApi.coreServices.pluginMetadata,
|
|
19
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
20
|
+
lifecycle: backendPluginApi.coreServices.lifecycle,
|
|
21
|
+
rootHttpRouter: backendPluginApi.coreServices.rootHttpRouter,
|
|
22
|
+
auth: backendPluginApi.coreServices.auth,
|
|
23
|
+
httpAuth: backendPluginApi.coreServices.httpAuth
|
|
24
|
+
},
|
|
25
|
+
async factory({ auth, httpAuth, config, plugin, rootHttpRouter, lifecycle }) {
|
|
26
|
+
const router = Router__default.default();
|
|
27
|
+
rootHttpRouter.use(`/api/${plugin.getId()}`, router);
|
|
28
|
+
const credentialsBarrier = createCredentialsBarrier.createCredentialsBarrier({
|
|
29
|
+
httpAuth,
|
|
30
|
+
config
|
|
31
|
+
});
|
|
32
|
+
router.use(createAuthIntegrationRouter.createAuthIntegrationRouter({ auth }));
|
|
33
|
+
router.use(createLifecycleMiddleware.createLifecycleMiddleware({ lifecycle }));
|
|
34
|
+
router.use(credentialsBarrier.middleware);
|
|
35
|
+
router.use(createCookieAuthRefreshMiddleware.createCookieAuthRefreshMiddleware({ auth, httpAuth }));
|
|
36
|
+
return {
|
|
37
|
+
use(handler) {
|
|
38
|
+
router.use(handler);
|
|
39
|
+
},
|
|
40
|
+
addAuthPolicy(policy) {
|
|
41
|
+
credentialsBarrier.addAuthPolicy(policy);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
exports.httpRouterServiceFactory = httpRouterServiceFactory;
|
|
48
|
+
//# sourceMappingURL=httpRouterServiceFactory.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpRouterServiceFactory.cjs.js","sources":["../../../src/entrypoints/httpRouter/httpRouterServiceFactory.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 { Handler } from 'express';\nimport PromiseRouter from 'express-promise-router';\nimport {\n coreServices,\n createServiceFactory,\n HttpRouterServiceAuthPolicy,\n} from '@backstage/backend-plugin-api';\nimport { createLifecycleMiddleware } from './createLifecycleMiddleware';\nimport { createCredentialsBarrier } from './createCredentialsBarrier';\nimport { createAuthIntegrationRouter } from './createAuthIntegrationRouter';\nimport { createCookieAuthRefreshMiddleware } from './createCookieAuthRefreshMiddleware';\n\n/**\n * HTTP route registration for plugins.\n *\n * See {@link @backstage/code-plugin-api#HttpRouterService}\n * and {@link https://backstage.io/docs/backend-system/core-services/http-router | the service docs}\n * for more information.\n *\n * @public\n */\nexport const httpRouterServiceFactory = createServiceFactory({\n service: coreServices.httpRouter,\n initialization: 'always',\n deps: {\n plugin: coreServices.pluginMetadata,\n config: coreServices.rootConfig,\n lifecycle: coreServices.lifecycle,\n rootHttpRouter: coreServices.rootHttpRouter,\n auth: coreServices.auth,\n httpAuth: coreServices.httpAuth,\n },\n async factory({ auth, httpAuth, config, plugin, rootHttpRouter, lifecycle }) {\n const router = PromiseRouter();\n\n rootHttpRouter.use(`/api/${plugin.getId()}`, router);\n\n const credentialsBarrier = createCredentialsBarrier({\n httpAuth,\n config,\n });\n\n router.use(createAuthIntegrationRouter({ auth }));\n router.use(createLifecycleMiddleware({ lifecycle }));\n router.use(credentialsBarrier.middleware);\n router.use(createCookieAuthRefreshMiddleware({ auth, httpAuth }));\n\n return {\n use(handler: Handler): void {\n router.use(handler);\n },\n addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void {\n credentialsBarrier.addAuthPolicy(policy);\n },\n };\n },\n});\n"],"names":["createServiceFactory","coreServices","PromiseRouter","createCredentialsBarrier","createAuthIntegrationRouter","createLifecycleMiddleware","createCookieAuthRefreshMiddleware"],"mappings":";;;;;;;;;;;;;AAqCO,MAAM,2BAA2BA,qCAAqB,CAAA;AAAA,EAC3D,SAASC,6BAAa,CAAA,UAAA;AAAA,EACtB,cAAgB,EAAA,QAAA;AAAA,EAChB,IAAM,EAAA;AAAA,IACJ,QAAQA,6BAAa,CAAA,cAAA;AAAA,IACrB,QAAQA,6BAAa,CAAA,UAAA;AAAA,IACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,IACxB,gBAAgBA,6BAAa,CAAA,cAAA;AAAA,IAC7B,MAAMA,6BAAa,CAAA,IAAA;AAAA,IACnB,UAAUA,6BAAa,CAAA,QAAA;AAAA,GACzB;AAAA,EACA,MAAM,QAAQ,EAAE,IAAA,EAAM,UAAU,MAAQ,EAAA,MAAA,EAAQ,cAAgB,EAAA,SAAA,EAAa,EAAA;AAC3E,IAAA,MAAM,SAASC,uBAAc,EAAA,CAAA;AAE7B,IAAA,cAAA,CAAe,IAAI,CAAQ,KAAA,EAAA,MAAA,CAAO,KAAM,EAAC,IAAI,MAAM,CAAA,CAAA;AAEnD,IAAA,MAAM,qBAAqBC,iDAAyB,CAAA;AAAA,MAClD,QAAA;AAAA,MACA,MAAA;AAAA,KACD,CAAA,CAAA;AAED,IAAA,MAAA,CAAO,GAAI,CAAAC,uDAAA,CAA4B,EAAE,IAAA,EAAM,CAAC,CAAA,CAAA;AAChD,IAAA,MAAA,CAAO,GAAI,CAAAC,mDAAA,CAA0B,EAAE,SAAA,EAAW,CAAC,CAAA,CAAA;AACnD,IAAO,MAAA,CAAA,GAAA,CAAI,mBAAmB,UAAU,CAAA,CAAA;AACxC,IAAA,MAAA,CAAO,IAAIC,mEAAkC,CAAA,EAAE,IAAM,EAAA,QAAA,EAAU,CAAC,CAAA,CAAA;AAEhE,IAAO,OAAA;AAAA,MACL,IAAI,OAAwB,EAAA;AAC1B,QAAA,MAAA,CAAO,IAAI,OAAO,CAAA,CAAA;AAAA,OACpB;AAAA,MACA,cAAc,MAA2C,EAAA;AACvD,QAAA,kBAAA,CAAmB,cAAc,MAAM,CAAA,CAAA;AAAA,OACzC;AAAA,KACF,CAAA;AAAA,GACF;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
|
|
5
|
+
class BackendPluginLifecycleImpl {
|
|
6
|
+
constructor(logger, pluginMetadata) {
|
|
7
|
+
this.logger = logger;
|
|
8
|
+
this.pluginMetadata = pluginMetadata;
|
|
9
|
+
}
|
|
10
|
+
#hasStarted = false;
|
|
11
|
+
#hasShutdown = false;
|
|
12
|
+
#startupTasks = [];
|
|
13
|
+
#shutdownTasks = [];
|
|
14
|
+
addStartupHook(hook, options) {
|
|
15
|
+
if (this.#hasStarted) {
|
|
16
|
+
throw new Error("Attempted to add startup hook after startup");
|
|
17
|
+
}
|
|
18
|
+
this.#startupTasks.push({ hook, options });
|
|
19
|
+
}
|
|
20
|
+
async startup() {
|
|
21
|
+
if (this.#hasStarted) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
this.#hasStarted = true;
|
|
25
|
+
this.logger.debug(
|
|
26
|
+
`Running ${this.#startupTasks.length} plugin startup tasks...`
|
|
27
|
+
);
|
|
28
|
+
await Promise.all(
|
|
29
|
+
this.#startupTasks.map(async ({ hook, options }) => {
|
|
30
|
+
const logger = options?.logger ?? this.logger;
|
|
31
|
+
try {
|
|
32
|
+
await hook();
|
|
33
|
+
logger.debug(`Plugin startup hook succeeded`);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
logger.error(`Plugin startup hook failed, ${error}`);
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
addShutdownHook(hook, options) {
|
|
41
|
+
if (this.#hasShutdown) {
|
|
42
|
+
throw new Error("Attempted to add shutdown hook after shutdown");
|
|
43
|
+
}
|
|
44
|
+
const plugin = this.pluginMetadata.getId();
|
|
45
|
+
const logger = options?.logger?.child({ plugin }) ?? this.logger;
|
|
46
|
+
this.#shutdownTasks.push({
|
|
47
|
+
hook,
|
|
48
|
+
options: {
|
|
49
|
+
...options,
|
|
50
|
+
logger
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async shutdown() {
|
|
55
|
+
if (this.#hasShutdown) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.#hasShutdown = true;
|
|
59
|
+
this.logger.debug(
|
|
60
|
+
`Running ${this.#shutdownTasks.length} plugin shutdown tasks...`
|
|
61
|
+
);
|
|
62
|
+
await Promise.all(
|
|
63
|
+
this.#shutdownTasks.map(async ({ hook, options }) => {
|
|
64
|
+
const logger = options?.logger ?? this.logger;
|
|
65
|
+
try {
|
|
66
|
+
await hook();
|
|
67
|
+
logger.debug(`Plugin shutdown hook succeeded`);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
logger.error("Plugin shutdown hook failed", error);
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const lifecycleServiceFactory = backendPluginApi.createServiceFactory({
|
|
76
|
+
service: backendPluginApi.coreServices.lifecycle,
|
|
77
|
+
deps: {
|
|
78
|
+
logger: backendPluginApi.coreServices.logger,
|
|
79
|
+
pluginMetadata: backendPluginApi.coreServices.pluginMetadata
|
|
80
|
+
},
|
|
81
|
+
async factory({ logger, pluginMetadata }) {
|
|
82
|
+
return new BackendPluginLifecycleImpl(logger, pluginMetadata);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
exports.BackendPluginLifecycleImpl = BackendPluginLifecycleImpl;
|
|
87
|
+
exports.lifecycleServiceFactory = lifecycleServiceFactory;
|
|
88
|
+
//# sourceMappingURL=lifecycleServiceFactory.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycleServiceFactory.cjs.js","sources":["../../../src/entrypoints/lifecycle/lifecycleServiceFactory.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 LifecycleService,\n LifecycleServiceShutdownHook,\n LifecycleServiceShutdownOptions,\n LifecycleServiceStartupHook,\n LifecycleServiceStartupOptions,\n LoggerService,\n PluginMetadataService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\n\n/** @internal */\nexport class BackendPluginLifecycleImpl implements LifecycleService {\n constructor(\n private readonly logger: LoggerService,\n private readonly pluginMetadata: PluginMetadataService,\n ) {}\n\n #hasStarted = false;\n #hasShutdown = false;\n #startupTasks: Array<{\n hook: LifecycleServiceStartupHook;\n options?: LifecycleServiceStartupOptions;\n }> = [];\n #shutdownTasks: Array<{\n hook: LifecycleServiceShutdownHook;\n options?: LifecycleServiceShutdownOptions;\n }> = [];\n\n addStartupHook(\n hook: LifecycleServiceStartupHook,\n options?: LifecycleServiceStartupOptions,\n ): void {\n if (this.#hasStarted) {\n throw new Error('Attempted to add startup hook after startup');\n }\n this.#startupTasks.push({ hook, options });\n }\n\n async startup(): Promise<void> {\n if (this.#hasStarted) {\n return;\n }\n this.#hasStarted = true;\n\n this.logger.debug(\n `Running ${this.#startupTasks.length} plugin startup tasks...`,\n );\n await Promise.all(\n this.#startupTasks.map(async ({ hook, options }) => {\n const logger = options?.logger ?? this.logger;\n try {\n await hook();\n logger.debug(`Plugin startup hook succeeded`);\n } catch (error) {\n logger.error(`Plugin startup hook failed, ${error}`);\n }\n }),\n );\n }\n\n addShutdownHook(\n hook: LifecycleServiceShutdownHook,\n options?: LifecycleServiceShutdownOptions,\n ): void {\n if (this.#hasShutdown) {\n throw new Error('Attempted to add shutdown hook after shutdown');\n }\n const plugin = this.pluginMetadata.getId();\n const logger = options?.logger?.child({ plugin }) ?? this.logger;\n this.#shutdownTasks.push({\n hook,\n options: {\n ...options,\n logger,\n },\n });\n }\n\n async shutdown(): Promise<void> {\n if (this.#hasShutdown) {\n return;\n }\n this.#hasShutdown = true;\n\n this.logger.debug(\n `Running ${this.#shutdownTasks.length} plugin shutdown tasks...`,\n );\n\n await Promise.all(\n this.#shutdownTasks.map(async ({ hook, options }) => {\n const logger = options?.logger ?? this.logger;\n try {\n await hook();\n logger.debug(`Plugin shutdown hook succeeded`);\n } catch (error) {\n logger.error('Plugin shutdown hook failed', error);\n }\n }),\n );\n }\n}\n\n/**\n * Registration of plugin startup and shutdown lifecycle hooks.\n *\n * See {@link @backstage/code-plugin-api#LifecycleService}\n * and {@link https://backstage.io/docs/backend-system/core-services/lifecycle | the service docs}\n * for more information.\n *\n * @public\n */\nexport const lifecycleServiceFactory = createServiceFactory({\n service: coreServices.lifecycle,\n deps: {\n logger: coreServices.logger,\n pluginMetadata: coreServices.pluginMetadata,\n },\n async factory({ logger, pluginMetadata }) {\n return new BackendPluginLifecycleImpl(logger, pluginMetadata);\n },\n});\n"],"names":["createServiceFactory","coreServices"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
|
|
5
|
+
const loggerServiceFactory = backendPluginApi.createServiceFactory({
|
|
6
|
+
service: backendPluginApi.coreServices.logger,
|
|
7
|
+
deps: {
|
|
8
|
+
rootLogger: backendPluginApi.coreServices.rootLogger,
|
|
9
|
+
plugin: backendPluginApi.coreServices.pluginMetadata
|
|
10
|
+
},
|
|
11
|
+
factory({ rootLogger, plugin }) {
|
|
12
|
+
return rootLogger.child({ plugin: plugin.getId() });
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
exports.loggerServiceFactory = loggerServiceFactory;
|
|
17
|
+
//# sourceMappingURL=loggerServiceFactory.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loggerServiceFactory.cjs.js","sources":["../../../src/entrypoints/logger/loggerServiceFactory.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 createServiceFactory,\n coreServices,\n} from '@backstage/backend-plugin-api';\n\n/**\n * Plugin-level logging.\n *\n * See {@link @backstage/code-plugin-api#LoggerService}\n * and {@link https://backstage.io/docs/backend-system/core-services/logger | the service docs}\n * for more information.\n *\n * @public\n */\nexport const loggerServiceFactory = createServiceFactory({\n service: coreServices.logger,\n deps: {\n rootLogger: coreServices.rootLogger,\n plugin: coreServices.pluginMetadata,\n },\n factory({ rootLogger, plugin }) {\n return rootLogger.child({ plugin: plugin.getId() });\n },\n});\n"],"names":["createServiceFactory","coreServices"],"mappings":";;;;AA8BO,MAAM,uBAAuBA,qCAAqB,CAAA;AAAA,EACvD,SAASC,6BAAa,CAAA,MAAA;AAAA,EACtB,IAAM,EAAA;AAAA,IACJ,YAAYA,6BAAa,CAAA,UAAA;AAAA,IACzB,QAAQA,6BAAa,CAAA,cAAA;AAAA,GACvB;AAAA,EACA,OAAQ,CAAA,EAAE,UAAY,EAAA,MAAA,EAAU,EAAA;AAC9B,IAAA,OAAO,WAAW,KAAM,CAAA,EAAE,QAAQ,MAAO,CAAA,KAAA,IAAS,CAAA,CAAA;AAAA,GACpD;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
5
|
+
|
|
6
|
+
const permissionsServiceFactory = backendPluginApi.createServiceFactory({
|
|
7
|
+
service: backendPluginApi.coreServices.permissions,
|
|
8
|
+
deps: {
|
|
9
|
+
auth: backendPluginApi.coreServices.auth,
|
|
10
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
11
|
+
discovery: backendPluginApi.coreServices.discovery
|
|
12
|
+
},
|
|
13
|
+
async factory({ auth, config, discovery }) {
|
|
14
|
+
return pluginPermissionNode.ServerPermissionClient.fromConfig(config, {
|
|
15
|
+
auth,
|
|
16
|
+
discovery
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
exports.permissionsServiceFactory = permissionsServiceFactory;
|
|
22
|
+
//# sourceMappingURL=permissionsServiceFactory.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissionsServiceFactory.cjs.js","sources":["../../../src/entrypoints/permissions/permissionsServiceFactory.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 coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ServerPermissionClient } from '@backstage/plugin-permission-node';\n\n/**\n * Permission system integration for authorization of user actions.\n *\n * See {@link @backstage/code-plugin-api#PermissionsService}\n * and {@link https://backstage.io/docs/backend-system/core-services/permissions | the service docs}\n * for more information.\n *\n * @public\n */\nexport const permissionsServiceFactory = createServiceFactory({\n service: coreServices.permissions,\n deps: {\n auth: coreServices.auth,\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n },\n async factory({ auth, config, discovery }) {\n return ServerPermissionClient.fromConfig(config, {\n auth,\n discovery,\n });\n },\n});\n"],"names":["createServiceFactory","coreServices","ServerPermissionClient"],"mappings":";;;;;AA+BO,MAAM,4BAA4BA,qCAAqB,CAAA;AAAA,EAC5D,SAASC,6BAAa,CAAA,WAAA;AAAA,EACtB,IAAM,EAAA;AAAA,IACJ,MAAMA,6BAAa,CAAA,IAAA;AAAA,IACnB,QAAQA,6BAAa,CAAA,UAAA;AAAA,IACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,GAC1B;AAAA,EACA,MAAM,OAAQ,CAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,WAAa,EAAA;AACzC,IAAO,OAAAC,2CAAA,CAAuB,WAAW,MAAQ,EAAA;AAAA,MAC/C,IAAA;AAAA,MACA,SAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
|