@solo.io/platform-portal-backstage-plugin-backend 0.0.19 → 0.0.21

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/README.md CHANGED
@@ -17,7 +17,7 @@ This plugin will create the following Backstage catalog entities and relate them
17
17
  yarn add --cwd ./packages/backend @solo.io/platform-portal-backstage-plugin-backend
18
18
  ```
19
19
 
20
- 2. Update your backend plugin in `packages/backend/src/plugins/catalog.ts` with the following code. The parts that you will need to update should similar to what is described in the Backstage docs [here](https://backstage.io/docs/features/software-catalog/external-integrations/#installing-the-provider). Make sure to add the code above and below the `await processingEngine.start();` lines:
20
+ 2. Update your backend plugin in `packages/backend/src/plugins/catalog.ts` with the following code. The parts that you will need to update should similar to what is described in the Backstage docs [here](https://backstage.io/docs/features/software-catalog/external-integrations/#installing-the-provider). **Make sure to add the code above and below the `await processingEngine.start();` lines**:
21
21
 
22
22
  ```ts
23
23
  // ...
@@ -54,26 +54,25 @@ export default async function createPlugin(
54
54
 
55
55
  ```yaml
56
56
  glooPlatformPortal:
57
- portalServerUrl: http://localhost:31080/v1
58
- clientId: // Update with your client id
59
- clientSecret: // Update with your client secret
60
- tokenEndpoint: // Update with your token endpoint
61
- serviceAccountUsername: // The username of the service account that can access your APIs.
62
- serviceAccountPassword: // The password of the service account that can access your APIs.
63
- // This is optional. Defaults to false.
64
- debugLogging: false
65
- // This is optional.
66
- syncFrequency:
67
- hours: 0
68
- minutes: 1
69
- seconds: 0
70
- milliseconds: 0
71
- // This is optional.
72
- syncTimeout:
73
- hours: 0
74
- minutes: 0
75
- seconds: 10
76
- milliseconds: 0
57
+ backend:
58
+ portalServerUrl: http://localhost:31080/v1
59
+ clientId: // Update with your client id
60
+ clientSecret: // Update with your client secret
61
+ tokenEndpoint: // Update with your token endpoint
62
+ // This is optional. Defaults to false.
63
+ debugLogging: false
64
+ // This is optional.
65
+ syncFrequency:
66
+ hours: 0
67
+ minutes: 1
68
+ seconds: 0
69
+ milliseconds: 0
70
+ // This is optional.
71
+ syncTimeout:
72
+ hours: 0
73
+ minutes: 0
74
+ seconds: 10
75
+ milliseconds: 0
77
76
  ```
78
77
 
79
78
  ## Demo Image
@@ -105,8 +104,6 @@ docker run \
105
104
  -e CLIENT_ID= # replace \
106
105
  -e CLIENT_SECRET= # replace \
107
106
  -e TOKEN_ENDPOINT=.../realms/master/protocol/openid-connect/token # replace \
108
- -e PORTAL_SERVICE_ACCOUNT_USERNAME= # replace \
109
- -e PORTAL_SERVICE_ACCOUNT_PASSWORD= # replace \
110
107
  -e POSTGRES_USER=postgres \
111
108
  -e POSTGRES_PASSWORD=password \
112
109
  -e POSTGRES_HOST=host.docker.internal \
@@ -125,21 +122,20 @@ backend:
125
122
  user: ${POSTGRES_USER}
126
123
  password: ${POSTGRES_PASSWORD}
127
124
  glooPlatformPortal:
128
- portalServerUrl: ${PORTAL_SERVER_URL}
129
- clientId: ${CLIENT_ID}
130
- clientSecret: ${CLIENT_SECRET}
131
- tokenEndpoint: ${TOKEN_ENDPOINT}
132
- serviceAccountUsername: ${PORTAL_SERVICE_ACCOUNT_USERNAME}
133
- serviceAccountPassword: ${PORTAL_SERVICE_ACCOUNT_PASSWORD}
134
- debugLogging: ${PORTAL_DEBUG_LOGGING}
135
- syncTimeout:
136
- hours: ${PORTAL_SYNC_TIMEOUT_HOURS}
137
- minutes: ${PORTAL_SYNC_TIMEOUT_MINUTES}
138
- seconds: ${PORTAL_SYNC_TIMEOUT_SECONDS}
139
- milliseconds: ${PORTAL_SYNC_TIMEOUT_MILLISECONDS}
140
- syncFrequency:
141
- hours: ${PORTAL_SYNC_FREQUENCY_HOURS}
142
- minutes: ${PORTAL_SYNC_FREQUENCY_MINUTES}
143
- seconds: ${PORTAL_SYNC_FREQUENCY_SECONDS}
144
- milliseconds: ${PORTAL_SYNC_FREQUENCY_MILLISECONDS}
125
+ backend:
126
+ portalServerUrl: ${PORTAL_SERVER_URL}
127
+ clientId: ${CLIENT_ID}
128
+ clientSecret: ${CLIENT_SECRET}
129
+ tokenEndpoint: ${TOKEN_ENDPOINT}
130
+ debugLogging: ${PORTAL_DEBUG_LOGGING}
131
+ syncTimeout:
132
+ hours: ${PORTAL_SYNC_TIMEOUT_HOURS}
133
+ minutes: ${PORTAL_SYNC_TIMEOUT_MINUTES}
134
+ seconds: ${PORTAL_SYNC_TIMEOUT_SECONDS}
135
+ milliseconds: ${PORTAL_SYNC_TIMEOUT_MILLISECONDS}
136
+ syncFrequency:
137
+ hours: ${PORTAL_SYNC_FREQUENCY_HOURS}
138
+ minutes: ${PORTAL_SYNC_FREQUENCY_MINUTES}
139
+ seconds: ${PORTAL_SYNC_FREQUENCY_SECONDS}
140
+ milliseconds: ${PORTAL_SYNC_FREQUENCY_MILLISECONDS}
145
141
  ```
package/config.d.ts CHANGED
@@ -1,76 +1,64 @@
1
1
  export interface Config {
2
2
  glooPlatformPortal: {
3
- /**
4
- * Optionally enable extra debug-logging. This defaults to false.
5
- * @visibility frontend
6
- */
7
- debugLogging: boolean;
3
+ backend: {
4
+ /**
5
+ * Optionally enable extra debug-logging. This defaults to false.
6
+ * @visibility backend
7
+ */
8
+ debugLogging: boolean;
8
9
 
9
- /**
10
- * @visibility frontend
11
- */
12
- portalServerUrl: string;
10
+ /**
11
+ * @visibility backend
12
+ */
13
+ portalServerUrl: string;
13
14
 
14
- /**
15
- * The oauth client id.
16
- * In keycloak, this is shown in the client settings
17
- * of your keycloak instances UI.
18
- * @visibility frontend
19
- */
20
- clientId: string;
15
+ /**
16
+ * The oauth client id.
17
+ * In keycloak, this is shown in the client settings
18
+ * of your keycloak instances UI.
19
+ * @visibility backend
20
+ */
21
+ clientId: string;
21
22
 
22
- /**
23
- * This is the endpoint to get the oauth token.
24
- * In keycloak, this is the `token_endpoint` property from:
25
- * <your-keycloak-url>/realms/<your-realm>/.well-known/openid-configuration
26
- * @visibility frontend
27
- */
28
- tokenEndpoint: string;
23
+ /**
24
+ * This is the endpoint to get the oauth token.
25
+ * In keycloak, this is the `token_endpoint` property from:
26
+ * <your-keycloak-url>/realms/<your-realm>/.well-known/openid-configuration
27
+ * @visibility backend
28
+ */
29
+ tokenEndpoint: string;
29
30
 
30
- /**
31
- * The oauth client secret.
32
- * In keycloak, this is shown in the client settings
33
- * of your keycloak instances UI.
34
- * @visibility backend
35
- */
36
- clientSecret: string;
31
+ /**
32
+ * The oauth client secret.
33
+ * In keycloak, this is shown in the client settings
34
+ * of your keycloak instances UI.
35
+ * @visibility backend
36
+ */
37
+ clientSecret: string;
37
38
 
38
- /**
39
- * The username of the service account account which can access the
40
- * APIs that will be synced with Backstage.
41
- * @visibility backend
42
- */
43
- serviceAccountUsername: string;
39
+ /**
40
+ * The frequency to make the requests to sync the Gloo Platform Portal
41
+ * APIs with the Backstage catalog.
42
+ * @visibility backend
43
+ */
44
+ syncFrequency: {
45
+ hours: number;
46
+ minutes: number;
47
+ seconds: number;
48
+ milliseconds: number;
49
+ };
44
50
 
45
- /**
46
- * The password of the service account account which can access the
47
- * APIs that will be synced with Backstage.
48
- * @visibility backend
49
- */
50
- serviceAccountPassword: string;
51
-
52
- /**
53
- * The frequency to make the requests to sync the Gloo Platform Portal
54
- * APIs with the Backstage catalog.
55
- * @visibility backend
56
- */
57
- syncFrequency: {
58
- hours: number;
59
- minutes: number;
60
- seconds: number;
61
- milliseconds: number;
62
- };
63
-
64
- /**
65
- * The timeout duration for the requests to sync the Gloo Platform Portal
66
- * APIs with the Backstage catalog.
67
- * @visibility backend
68
- */
69
- syncTimeout: {
70
- hours: number;
71
- minutes: number;
72
- seconds: number;
73
- milliseconds: number;
51
+ /**
52
+ * The timeout duration for the requests to sync the Gloo Platform Portal
53
+ * APIs with the Backstage catalog.
54
+ * @visibility backend
55
+ */
56
+ syncTimeout: {
57
+ hours: number;
58
+ minutes: number;
59
+ seconds: number;
60
+ milliseconds: number;
61
+ };
74
62
  };
75
63
  };
76
64
  }
package/dist/index.cjs.js CHANGED
@@ -8,55 +8,57 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
8
8
 
9
9
  var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
10
10
 
11
- const getPortalServerUrl = (_, config) => {
12
- let value = config.getOptionalString("glooPlatformPortal.portalServerUrl");
11
+ const getPortalServerUrl = (logErr, _, config) => {
12
+ if (!config) {
13
+ logErr("No backstage config found when getting portal server url.");
14
+ return "";
15
+ }
16
+ let value = config.getOptionalString(
17
+ "glooPlatformPortal.backend.portalServerUrl"
18
+ );
13
19
  if (!!value && value.at(-1) === "/")
14
20
  value = value.substring(0, value.length - 1);
15
21
  return value != null ? value : "http://localhost:31080/v1";
16
22
  };
17
- const getClientSecret = (logWarning, config) => {
18
- const value = config.getOptionalString("glooPlatformPortal.clientSecret");
23
+ const getClientSecret = (logErr, logWarning, config) => {
24
+ if (!config) {
25
+ logErr("No backstage config found when getting client secret.");
26
+ return "";
27
+ }
28
+ const value = config.getOptionalString(
29
+ "glooPlatformPortal.backend.clientSecret"
30
+ );
19
31
  if (!value) {
20
32
  logWarning(
21
- "No glooPlatformPortal.clientSecret found in app-config.local.yaml"
33
+ "No glooPlatformPortal.backend.clientSecret found in app-config.local.yaml"
22
34
  );
23
35
  }
24
36
  return value != null ? value : "";
25
37
  };
26
- const getClientId = (logWarning, config) => {
27
- const value = config.getOptionalString("glooPlatformPortal.clientId");
28
- if (!value) {
29
- logWarning("No glooPlatformPortal.clientId found in app-config.local.yaml");
38
+ const getClientId = (logErr, logWarning, config) => {
39
+ if (!config) {
40
+ logErr("No backstage config found when getting client id.");
41
+ return "";
30
42
  }
31
- return value != null ? value : "";
32
- };
33
- const getTokenEndpoint = (logWarning, config) => {
34
- const value = config.getOptionalString("glooPlatformPortal.tokenEndpoint");
43
+ const value = config.getOptionalString("glooPlatformPortal.backend.clientId");
35
44
  if (!value) {
36
45
  logWarning(
37
- "No glooPlatformPortal.tokenEndpoint found in app-config.local.yaml"
46
+ "No glooPlatformPortal.backend.clientId found in app-config.local.yaml"
38
47
  );
39
48
  }
40
49
  return value != null ? value : "";
41
50
  };
42
- const getServiceAccountPassword = (logWarning, config) => {
43
- const value = config.getOptionalString(
44
- "glooPlatformPortal.serviceAccountPassword"
45
- );
46
- if (!value) {
47
- logWarning(
48
- "No glooPlatformPortal.serviceAccountPassword found in app-config.local.yaml"
49
- );
51
+ const getTokenEndpoint = (logErr, logWarning, config) => {
52
+ if (!config) {
53
+ logErr("No backstage config found when getting token endpoint.");
54
+ return "";
50
55
  }
51
- return value != null ? value : "";
52
- };
53
- const getServiceAccountUsername = (logWarning, config) => {
54
56
  const value = config.getOptionalString(
55
- "glooPlatformPortal.serviceAccountUsername"
57
+ "glooPlatformPortal.backend.tokenEndpoint"
56
58
  );
57
59
  if (!value) {
58
60
  logWarning(
59
- "No glooPlatformPortal.serviceAccountUsername found in app-config.local.yaml"
61
+ "No glooPlatformPortal.backend.tokenEndpoint found in app-config.local.yaml"
60
62
  );
61
63
  }
62
64
  return value != null ? value : "";
@@ -84,7 +86,7 @@ function objectToUrlFormEncodedPayload(requestJSON) {
84
86
  const formBodyString = formBodyPieces.join("&");
85
87
  return formBodyString;
86
88
  }
87
- async function doAccessTokenRequest(grantType, tokenEndpoint, clientId, clientSecret, username, password, refreshToken) {
89
+ async function doAccessTokenRequest(grantType, tokenEndpoint, clientId, clientSecret, refreshToken) {
88
90
  const formData = {};
89
91
  formData.grant_type = grantType;
90
92
  formData.client_id = clientId;
@@ -95,10 +97,6 @@ async function doAccessTokenRequest(grantType, tokenEndpoint, clientId, clientSe
95
97
  }
96
98
  formData.refresh_token = refreshToken;
97
99
  }
98
- if (grantType === "password") {
99
- formData.username = username;
100
- formData.password = password;
101
- }
102
100
  const rawRes = await fetch__default["default"](tokenEndpoint, {
103
101
  headers: {
104
102
  "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
@@ -125,6 +123,27 @@ async function doAccessTokenRequest(grantType, tokenEndpoint, clientId, clientSe
125
123
  }
126
124
  return resJSON;
127
125
  }
126
+ const sanitizeRegex = {
127
+ // Each tag must be sequences of [a-z0-9:+#] separated by -, at most 63 characters in total
128
+ tag: /[a-z]|[0-9]|\:|\+|\#|\-/,
129
+ // Strings of length at least 1, and at most 63
130
+ // Must consist of sequences of [a-z0-9A-Z] possibly separated by one of [-_.].
131
+ name: /[a-z]|[0-9]|[A-Z]|\-|\_|\./,
132
+ // Namespaces must be sequences of [a-zA-Z0-9], possibly separated by -, at most 63 characters in total.
133
+ namespace: /[a-z]|[0-9]|[A-Z]|\-/
134
+ };
135
+ const sanitizeStringForEntity = (propertyType, propertyValue) => {
136
+ return propertyValue.split("").map((ch) => !sanitizeRegex[propertyType].test(ch) ? "-" : ch).reduce(
137
+ (prev, cur) => (
138
+ // Don't go over 63 characters.
139
+ prev.length >= 62 ? prev : (
140
+ // Don't repeat "-"
141
+ prev.at(-1) === "-" && cur === "-" ? prev : prev + cur
142
+ )
143
+ ),
144
+ ""
145
+ );
146
+ };
128
147
 
129
148
  var __defProp = Object.defineProperty;
130
149
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -151,7 +170,7 @@ class GlooPlatformPortalProvider {
151
170
  this.logger = logger;
152
171
  this.config = config;
153
172
  this.debugLogging = !!config.getOptionalBoolean(
154
- "glooPlatformPortal.debugLogging"
173
+ "glooPlatformPortal.backend.debugLogging"
155
174
  );
156
175
  this.log("Initializing GlooPlatformPortalProvider.");
157
176
  this.startTokensRequests();
@@ -166,36 +185,27 @@ class GlooPlatformPortalProvider {
166
185
  if (this.debugLogging) {
167
186
  this.log("Making the initial access_token request.");
168
187
  }
188
+ if (!this.config) {
189
+ this.error(
190
+ "Backstage config object not found when doing access token request."
191
+ );
192
+ return;
193
+ }
169
194
  const res = await doAccessTokenRequest(
170
- "password",
171
- getTokenEndpoint(this.warn, this.config),
172
- getClientId(this.warn, this.config),
173
- getClientSecret(this.warn, this.config),
174
- getServiceAccountUsername(this.warn, this.config),
175
- getServiceAccountPassword(this.warn, this.config)
195
+ "client_credentials",
196
+ getTokenEndpoint(this.error, this.warn, this.config),
197
+ getClientId(this.error, this.warn, this.config),
198
+ getClientSecret(this.error, this.warn, this.config)
176
199
  );
177
200
  this.latestTokensResponse = res;
178
- if (this.debugLogging) {
179
- this.log("Got the initial access_token. ");
180
- }
181
- this.refreshTheToken();
182
- }
183
- /**
184
- *
185
- * 3. Get refresh_tokens.
186
- *
187
- * Calling this will refresh the access_token when it is expiring soon,
188
- * using the refresh_token in the access tokens response.
189
- * */
190
- async refreshTheToken() {
191
- const restartAccessTokenRequests = () => {
192
- this.warn("No latest access token. Re-requesting the access_token.");
193
- setTimeout(this.startTokensRequests, 5e3);
194
- };
195
201
  if (!this.latestTokensResponse) {
196
- restartAccessTokenRequests();
202
+ this.warn("No latest access token. Re-requesting the access_token.");
203
+ setTimeout(this.startTokensRequests.bind(this), 5e3);
197
204
  return;
198
205
  }
206
+ if (this.debugLogging) {
207
+ this.log("Got the access_token.");
208
+ }
199
209
  const parsedToken = parseJwt(this.latestTokensResponse.access_token);
200
210
  if (!parsedToken.exp) {
201
211
  this.warn("No `exp` property found in the access_token JWT.");
@@ -209,38 +219,10 @@ class GlooPlatformPortalProvider {
209
219
  return;
210
220
  }
211
221
  if (this.debugLogging) {
212
- this.log("Setting a timeout to refresh the token.");
222
+ this.log("Setting a timeout to get the next access token.");
213
223
  }
214
224
  setTimeout(
215
- async () => {
216
- if (!this.latestTokensResponse) {
217
- restartAccessTokenRequests();
218
- return;
219
- }
220
- try {
221
- if (this.debugLogging) {
222
- this.log("Making a refresh_token request.");
223
- }
224
- const res = await doAccessTokenRequest(
225
- "refresh_token",
226
- getTokenEndpoint(this.warn, this.config),
227
- getClientId(this.warn, this.config),
228
- getClientSecret(this.warn, this.config),
229
- getServiceAccountUsername(this.warn, this.config),
230
- getServiceAccountPassword(this.warn, this.config),
231
- this.latestTokensResponse.refresh_token
232
- );
233
- this.latestTokensResponse = res;
234
- if (this.debugLogging) {
235
- this.log("Got a new refresh_token.");
236
- }
237
- this.refreshTheToken();
238
- } catch (e) {
239
- if (!!e && typeof e === "string") {
240
- this.warn(e);
241
- }
242
- }
243
- },
225
+ this.startTokensRequests.bind(this),
244
226
  // Don't make this request more than once a second,
245
227
  // and do the refresh 5 seconds early.
246
228
  Math.max(1e3, millisUntilExpires - 5e3)
@@ -248,17 +230,17 @@ class GlooPlatformPortalProvider {
248
230
  }
249
231
  /**
250
232
  *
251
- * 4. Schedule sync.
233
+ * 3. Schedule sync.
252
234
  *
253
235
  * This is called during setup, and passes the user config into the
254
236
  * Backstage plugin task scheduler.
255
237
  * */
256
238
  async startScheduler(scheduler) {
257
239
  const frequency = this.config.getOptionalConfig(
258
- "glooPlatformPortal.syncFrequency"
240
+ "glooPlatformPortal.backend.syncFrequency"
259
241
  );
260
242
  const timeout = this.config.getOptionalConfig(
261
- "glooPlatformPortal.syncTimeout"
243
+ "glooPlatformPortal.backend.syncTimeout"
262
244
  );
263
245
  await scheduler.scheduleTask({
264
246
  id: "run_gloo_platform_portal_refresh",
@@ -298,7 +280,11 @@ class GlooPlatformPortalProvider {
298
280
  const bsGroupName = "solo-io-service-accounts";
299
281
  const bsServiceAccountName = "gloo-platform-portal-service-account";
300
282
  const bsSystemName = "gloo-platform-portal-apis";
301
- const portalServerUrl = getPortalServerUrl(this.warn, this.config);
283
+ const portalServerUrl = getPortalServerUrl(
284
+ this.error,
285
+ this.warn,
286
+ this.config
287
+ );
302
288
  const apisEndpoint = `${portalServerUrl}/apis`;
303
289
  try {
304
290
  const res = await fetch__default["default"](apisEndpoint + "?includeSchema=true", {
@@ -364,10 +350,10 @@ class GlooPlatformPortalProvider {
364
350
  tags: [
365
351
  "gloo-platform",
366
352
  ...!!apiVersion.apiVersion ? [
367
- "api-version-" + apiVersion.apiVersion.replaceAll(" ", "-").replaceAll(".", "-").replaceAll(",", "-")
353
+ "api-version-" + sanitizeStringForEntity("tag", apiVersion.apiVersion)
368
354
  ] : []
369
355
  ],
370
- name: apiVersion.apiId,
356
+ name: sanitizeStringForEntity("name", apiVersion.apiId),
371
357
  title: apiVersion.apiId,
372
358
  description: apiVersion.description,
373
359
  annotations: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/provider/configHelpers.ts","../src/provider/utility.ts","../src/provider/GlooPlatformPortalProvider.ts"],"sourcesContent":["import { Config } from '@backstage/config';\n\ntype logFn = (s: string) => any;\n\nexport const getPortalServerUrl = (_: logFn, config: Config) => {\n let value = config.getOptionalString('glooPlatformPortal.portalServerUrl');\n // Remove trailing slash if supplied.\n if (!!value && value.at(-1) === '/')\n value = value.substring(0, value.length - 1);\n return value ?? 'http://localhost:31080/v1';\n};\n\nexport const getClientSecret = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.clientSecret');\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.clientSecret found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getClientId = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.clientId');\n if (!value) {\n logWarning('No glooPlatformPortal.clientId found in app-config.local.yaml');\n }\n return value ?? '';\n};\n\nexport const getTokenEndpoint = (logWarning: logFn, config: Config) => {\n const value = config.getOptionalString('glooPlatformPortal.tokenEndpoint');\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.tokenEndpoint found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getServiceAccountPassword = (\n logWarning: logFn,\n config: Config,\n) => {\n const value = config.getOptionalString(\n 'glooPlatformPortal.serviceAccountPassword',\n );\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.serviceAccountPassword found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getServiceAccountUsername = (\n logWarning: logFn,\n config: Config,\n) => {\n const value = config.getOptionalString(\n 'glooPlatformPortal.serviceAccountUsername',\n );\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.serviceAccountUsername found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n","import fetch from 'node-fetch';\nimport { AccessTokensResponse } from './api-types';\n\nexport function parseJwt(token: string) {\n const base64Url = token.split('.')[1];\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)\n .join(''),\n );\n return JSON.parse(jsonPayload);\n}\n\nexport function objectToUrlFormEncodedPayload(\n requestJSON: Record<string, string>,\n) {\n const formBodyPieces = [] as string[];\n for (const property in requestJSON) {\n if (!requestJSON.hasOwnProperty(property)) continue;\n const encodedKey = encodeURIComponent(property);\n const encodedValue = encodeURIComponent(\n requestJSON[property as keyof typeof requestJSON],\n );\n formBodyPieces.push(`${encodedKey}=${encodedValue}`);\n }\n const formBodyString = formBodyPieces.join('&');\n return formBodyString;\n}\n\nexport async function doAccessTokenRequest(\n grantType: 'refresh_token' | 'password',\n tokenEndpoint: string,\n clientId: string,\n clientSecret: string,\n username: string,\n password: string,\n refreshToken?: string,\n) {\n const formData = {} as Record<string, string>;\n //\n // Build the request payload for a new oauth access token.\n //\n formData.grant_type = grantType;\n formData.client_id = clientId;\n formData.client_secret = clientSecret;\n if (grantType === 'refresh_token') {\n if (!refreshToken) {\n return undefined;\n }\n formData.refresh_token = refreshToken;\n }\n if (grantType === 'password') {\n formData.username = username;\n formData.password = password;\n }\n //\n // Make the request\n //\n const rawRes = await fetch(tokenEndpoint, {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',\n },\n method: 'POST',\n body: objectToUrlFormEncodedPayload(formData),\n });\n let resJSON: any;\n try {\n resJSON = await rawRes.json();\n } catch {\n throw new Error('Error parsing oauth response.');\n }\n if (!!resJSON.error_description) {\n throw new Error(resJSON.error_description);\n }\n if (!!resJSON.error) {\n throw new Error(resJSON.error);\n }\n //\n // Check for the access token in the response.\n //\n if (!resJSON.access_token) {\n throw new Error(\n \"No 'access_token' property was found in the oauth response body.\",\n );\n }\n return resJSON as AccessTokensResponse;\n}\n","import { Entity, EntityMeta } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\n\nimport { PluginTaskScheduler } from '@backstage/backend-tasks';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport fetch from 'node-fetch';\nimport * as winston from 'winston';\nimport { API, APIProduct, APISchema, AccessTokensResponse } from './api-types';\nimport {\n getClientId,\n getClientSecret,\n getPortalServerUrl,\n getServiceAccountPassword,\n getServiceAccountUsername,\n getTokenEndpoint,\n} from './configHelpers';\nimport { doAccessTokenRequest, parseJwt } from './utility';\n\n/**\n * Provides API entities from the Gloo Platform Portal REST server.\n */\nexport class GlooPlatformPortalProvider implements EntityProvider {\n private readonly env: string;\n private connection?: EntityProviderConnection;\n private logger: winston.Logger;\n private config: Config;\n private latestTokensResponse?: AccessTokensResponse;\n private debugLogging = false;\n\n log = (s: string) => this.logger.info(`gloo-platform-portal: ${s}`);\n warn = (s: string) => this.logger.warn(`gloo-platform-portal: ${s}`);\n error = (s: string) => this.logger.error(`gloo-platform-portal: ${s}`);\n getProviderName = () => `gloo-platform-portal-${this.env}`;\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n }\n\n //\n // 1. Init class\n //\n constructor(env: string, logger: winston.Logger, config: Config) {\n this.env = env;\n this.logger = logger;\n this.config = config;\n // Default extra debug-logging to false\n this.debugLogging = !!config.getOptionalBoolean(\n 'glooPlatformPortal.debugLogging',\n );\n this.log('Initializing GlooPlatformPortalProvider.');\n this.startTokensRequests();\n }\n\n //\n // 2. Get access_token\n //\n async startTokensRequests() {\n //\n // Make the initial request for the access_token.\n if (this.debugLogging) {\n this.log('Making the initial access_token request.');\n }\n const res = await doAccessTokenRequest(\n 'password',\n getTokenEndpoint(this.warn, this.config),\n getClientId(this.warn, this.config),\n getClientSecret(this.warn, this.config),\n getServiceAccountUsername(this.warn, this.config),\n getServiceAccountPassword(this.warn, this.config),\n );\n this.latestTokensResponse = res;\n if (this.debugLogging) {\n this.log('Got the initial access_token. ');\n }\n //\n // Set up a timeout to get refresh tokens this\n // updates this.latestToken on each callback.\n this.refreshTheToken();\n }\n\n /**\n *\n * 3. Get refresh_tokens.\n *\n * Calling this will refresh the access_token when it is expiring soon,\n * using the refresh_token in the access tokens response.\n * */\n async refreshTheToken() {\n const restartAccessTokenRequests = () => {\n // If there's a problem, wait to restart the access token\n // requests so as to not overload the auth server.\n this.warn('No latest access token. Re-requesting the access_token.');\n setTimeout(this.startTokensRequests, 5000);\n };\n if (!this.latestTokensResponse) {\n restartAccessTokenRequests();\n return;\n }\n //\n // Parse the access_token JWT to find when it expires.\n const parsedToken = parseJwt(this.latestTokensResponse.access_token);\n if (!parsedToken.exp) {\n this.warn('No `exp` property found in the access_token JWT.');\n }\n const nowDate = new Date();\n const expiresDate = new Date(parsedToken.exp * 1000);\n const millisUntilExpires = expiresDate.getTime() - nowDate.getTime();\n if (millisUntilExpires <= 0) {\n this.warn('access token is expired!');\n this.latestTokensResponse = undefined;\n return;\n }\n if (this.debugLogging) {\n this.log('Setting a timeout to refresh the token.');\n }\n // Set the timeout to request new tokens.\n setTimeout(\n async () => {\n if (!this.latestTokensResponse) {\n restartAccessTokenRequests();\n return;\n }\n try {\n if (this.debugLogging) {\n this.log('Making a refresh_token request.');\n }\n const res = await doAccessTokenRequest(\n 'refresh_token',\n getTokenEndpoint(this.warn, this.config),\n getClientId(this.warn, this.config),\n getClientSecret(this.warn, this.config),\n getServiceAccountUsername(this.warn, this.config),\n getServiceAccountPassword(this.warn, this.config),\n this.latestTokensResponse.refresh_token,\n );\n this.latestTokensResponse = res;\n if (this.debugLogging) {\n this.log('Got a new refresh_token.');\n }\n // Recurse\n this.refreshTheToken();\n } catch (e) {\n if (!!e && typeof e === 'string') {\n this.warn(e);\n }\n }\n },\n // Don't make this request more than once a second,\n // and do the refresh 5 seconds early.\n Math.max(1000, millisUntilExpires - 5000),\n );\n }\n\n /**\n *\n * 4. Schedule sync.\n *\n * This is called during setup, and passes the user config into the\n * Backstage plugin task scheduler.\n * */\n async startScheduler(scheduler: PluginTaskScheduler) {\n const frequency = this.config.getOptionalConfig(\n 'glooPlatformPortal.syncFrequency',\n );\n const timeout = this.config.getOptionalConfig(\n 'glooPlatformPortal.syncTimeout',\n );\n await scheduler.scheduleTask({\n id: 'run_gloo_platform_portal_refresh',\n fn: async () => {\n await this.run();\n },\n frequency: !!frequency\n ? {\n hours: frequency.getOptionalNumber('hours'),\n minutes: frequency.getOptionalNumber('minutes'),\n seconds: frequency.getOptionalNumber('seconds'),\n milliseconds: frequency.getOptionalNumber('milliseconds'),\n }\n : {\n minutes: 5,\n },\n timeout: !!timeout\n ? {\n hours: timeout.getOptionalNumber('hours'),\n minutes: timeout.getOptionalNumber('minutes'),\n seconds: timeout.getOptionalNumber('seconds'),\n milliseconds: timeout.getOptionalNumber('milliseconds'),\n }\n : {\n seconds: 30,\n },\n });\n }\n\n /**\n *\n * 4. Return new Backstage entities.\n *\n * Requests API information from the Gloo Platform Portal REST server,\n * and transforms the response into Backstage API entities.\n */\n async run(): Promise<void> {\n if (!this.connection || !this.latestTokensResponse) {\n throw new Error('Not initialized');\n }\n\n const entities: Entity[] = [];\n const bsGroupName = 'solo-io-service-accounts';\n const bsServiceAccountName = 'gloo-platform-portal-service-account';\n const bsSystemName = 'gloo-platform-portal-apis';\n const portalServerUrl = getPortalServerUrl(this.warn, this.config);\n const apisEndpoint = `${portalServerUrl}/apis`;\n //\n // Make API request\n try {\n const res = await fetch(apisEndpoint + '?includeSchema=true', {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n });\n let processedAPIs = (await res.json()) as API[];\n if (this.debugLogging) {\n this.log('Fetched APIs: ' + JSON.stringify(processedAPIs));\n }\n\n //\n // The server returns the APIs grouped by APIProduct,\n // so we can convert it back to a list here.\n //\n if (!!processedAPIs?.length && 'apiVersions' in processedAPIs[0]) {\n const apiProducts = processedAPIs as unknown as APIProduct[];\n processedAPIs = apiProducts.reduce((accum, curProd) => {\n accum.push(\n ...curProd.apiVersions.reduce((accumVer, api) => {\n if (!!api.openapiSpecFetchErr) {\n this.warn(\n `Schema fetch error for ${api.apiId} : ${JSON.stringify(\n api.openapiSpecFetchErr,\n )}`,\n );\n }\n accumVer.push({\n apiId: api.apiId,\n apiProductDisplayName: curProd.apiProductDisplayName,\n apiProductId: curProd.apiProductId,\n apiVersion: api.apiVersion,\n contact: api.contact,\n customMetadata: api.customMetadata,\n description: api.description,\n license: api.license,\n termsOfService: api.termsOfService,\n title: api.title,\n usagePlans: api.usagePlans,\n openapiSpec: api.openapiSpec,\n openapiSpecFetchErr: api.openapiSpecFetchErr,\n });\n return accumVer;\n }, [] as API[]),\n );\n return accum;\n }, [] as API[]);\n }\n\n //\n // Convert the APIs to entities\n for (let i = 0; i < processedAPIs.length; i++) {\n const apiVersion = processedAPIs[i];\n let schema = apiVersion.openapiSpec;\n if (!schema && !apiVersion.openapiSpecFetchErr) {\n // If the schema was not attempted to be fetched with\n // the /apis call, we individually fetch it here.\n // This is for backwards compatibility only, for\n // when the schema was not in the /apis response.\n const schemaRes = await fetch(\n `${apisEndpoint}/${apiVersion.apiId}/schema`,\n {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n },\n );\n schema = (await schemaRes.json()) as APISchema;\n }\n entities.push({\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'API',\n metadata: {\n tags: [\n 'gloo-platform',\n ...(!!apiVersion.apiVersion\n ? [\n 'api-version-' +\n apiVersion.apiVersion\n .replaceAll(' ', '-')\n .replaceAll('.', '-')\n .replaceAll(',', '-'),\n ]\n : []),\n ],\n name: apiVersion.apiId,\n title: apiVersion.apiId,\n description: apiVersion.description,\n annotations: {\n 'backstage.io/managed-by-location': `url:${apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n type: 'openapi',\n lifecycle: 'production',\n system: bsSystemName,\n owner: `user:${bsServiceAccountName}`,\n definition: JSON.stringify(schema),\n },\n });\n }\n if (this.debugLogging) {\n this.log(\n 'Transformed APIs into new entities: ' + JSON.stringify(entities),\n );\n }\n } catch (e) {\n this.error(\n `Could not get APIs from the portal server endpoint or their schemas or transform them into entities (${apisEndpoint}). Error: ${JSON.stringify(\n e,\n )}`,\n );\n }\n\n const locationKey = `gloo-platform-portal-provider:${this.env}`;\n await this.connection.applyMutation({\n type: 'full',\n entities: [\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Group',\n metadata: {\n name: bsGroupName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${portalServerUrl}`,\n },\n },\n spec: {\n type: 'service-account-group',\n children: [],\n members: [bsServiceAccountName],\n },\n },\n },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'User',\n metadata: {\n name: bsServiceAccountName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${portalServerUrl}`,\n },\n },\n spec: {\n displayName: 'Solo.io Service Account',\n email: '',\n picture: '',\n memberOf: [bsGroupName],\n },\n },\n },\n // {\n // locationKey,\n // entity: {\n // apiVersion: 'backstage.io/v1alpha1',\n // kind: 'Domain',\n // metadata: {\n // tags: ['gloo-platform'],\n // name: 'api-product',\n // description: 'Gloo Platform Portal ApiProduct resources.',\n // annotations: {\n // 'backstage.io/managed-by-location': 'url:' + apisEndpoint,\n // 'backstage.io/managed-by-origin-location':\n // 'url:' + apisEndpoint,\n // },\n // } as EntityMeta,\n // spec: {\n // owner: 'user:' + bsServiceAccountName,\n // },\n // },\n // },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'System',\n metadata: {\n tags: ['gloo-platform'],\n name: bsSystemName,\n title: 'Gloo Platform Portal APIs',\n annotations: {\n 'backstage.io/managed-by-location': `url:${apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n owner: `user:${bsServiceAccountName}`,\n // domain: 'api-product',\n },\n },\n },\n ...entities.map(entity => ({ locationKey, entity })),\n ],\n });\n }\n}\n"],"names":["fetch"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/provider/configHelpers.ts","../src/provider/utility.ts","../src/provider/GlooPlatformPortalProvider.ts"],"sourcesContent":["import { Config } from '@backstage/config';\n\ntype logFn = (s: string) => any;\n\nexport const getPortalServerUrl = (logErr: logFn, _: logFn, config: Config) => {\n if (!config) {\n logErr('No backstage config found when getting portal server url.');\n return '';\n }\n let value = config.getOptionalString(\n 'glooPlatformPortal.backend.portalServerUrl',\n );\n // Remove trailing slash if supplied.\n if (!!value && value.at(-1) === '/')\n value = value.substring(0, value.length - 1);\n return value ?? 'http://localhost:31080/v1';\n};\n\nexport const getClientSecret = (\n logErr: logFn,\n logWarning: logFn,\n config: Config,\n) => {\n if (!config) {\n logErr('No backstage config found when getting client secret.');\n return '';\n }\n const value = config.getOptionalString(\n 'glooPlatformPortal.backend.clientSecret',\n );\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.backend.clientSecret found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getClientId = (\n logErr: logFn,\n logWarning: logFn,\n config: Config,\n) => {\n if (!config) {\n logErr('No backstage config found when getting client id.');\n return '';\n }\n const value = config.getOptionalString('glooPlatformPortal.backend.clientId');\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.backend.clientId found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n\nexport const getTokenEndpoint = (\n logErr: logFn,\n logWarning: logFn,\n config: Config,\n) => {\n if (!config) {\n logErr('No backstage config found when getting token endpoint.');\n return '';\n }\n const value = config.getOptionalString(\n 'glooPlatformPortal.backend.tokenEndpoint',\n );\n if (!value) {\n logWarning(\n 'No glooPlatformPortal.backend.tokenEndpoint found in app-config.local.yaml',\n );\n }\n return value ?? '';\n};\n","import fetch from 'node-fetch';\nimport { AccessTokensResponse } from './api-types';\n\nexport function parseJwt(token: string) {\n const base64Url = token.split('.')[1];\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)\n .join(''),\n );\n return JSON.parse(jsonPayload);\n}\n\nexport function objectToUrlFormEncodedPayload(\n requestJSON: Record<string, string>,\n) {\n const formBodyPieces = [] as string[];\n for (const property in requestJSON) {\n if (!requestJSON.hasOwnProperty(property)) continue;\n const encodedKey = encodeURIComponent(property);\n const encodedValue = encodeURIComponent(\n requestJSON[property as keyof typeof requestJSON],\n );\n formBodyPieces.push(`${encodedKey}=${encodedValue}`);\n }\n const formBodyString = formBodyPieces.join('&');\n return formBodyString;\n}\n\nexport async function doAccessTokenRequest(\n grantType: 'refresh_token' | 'client_credentials',\n tokenEndpoint: string,\n clientId: string,\n clientSecret: string,\n refreshToken?: string,\n) {\n const formData = {} as Record<string, string>;\n //\n // Build the request payload for a new oauth access token.\n //\n formData.grant_type = grantType;\n formData.client_id = clientId;\n formData.client_secret = clientSecret;\n if (grantType === 'refresh_token') {\n if (!refreshToken) {\n return undefined;\n }\n formData.refresh_token = refreshToken;\n }\n //\n // Make the request\n //\n const rawRes = await fetch(tokenEndpoint, {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',\n },\n method: 'POST',\n body: objectToUrlFormEncodedPayload(formData),\n });\n let resJSON: any;\n try {\n resJSON = await rawRes.json();\n } catch {\n throw new Error('Error parsing oauth response.');\n }\n if (!!resJSON.error_description) {\n throw new Error(resJSON.error_description);\n }\n if (!!resJSON.error) {\n throw new Error(resJSON.error);\n }\n //\n // Check for the access token in the response.\n //\n if (!resJSON.access_token) {\n throw new Error(\n \"No 'access_token' property was found in the oauth response body.\",\n );\n }\n return resJSON as AccessTokensResponse;\n}\n\n//\n// From: https://backstage.io/docs/features/software-catalog/descriptor-format\n//\nconst sanitizeRegex = {\n // Each tag must be sequences of [a-z0-9:+#] separated by -, at most 63 characters in total\n tag: /[a-z]|[0-9]|\\:|\\+|\\#|\\-/,\n // Strings of length at least 1, and at most 63\n // Must consist of sequences of [a-z0-9A-Z] possibly separated by one of [-_.].\n name: /[a-z]|[0-9]|[A-Z]|\\-|\\_|\\./,\n // Namespaces must be sequences of [a-zA-Z0-9], possibly separated by -, at most 63 characters in total.\n namespace: /[a-z]|[0-9]|[A-Z]|\\-/,\n};\n\n/**\n * Sanitizes a string before adding it to a backstage entity.\n */\nexport const sanitizeStringForEntity = (\n propertyType: keyof typeof sanitizeRegex,\n propertyValue: string,\n) => {\n return propertyValue\n .split('')\n .map(ch => (!sanitizeRegex[propertyType].test(ch) ? '-' : ch))\n .reduce(\n (prev, cur) =>\n // Don't go over 63 characters.\n prev.length >= 62\n ? prev\n : // Don't repeat \"-\"\n prev.at(-1) === '-' && cur === '-'\n ? prev\n : prev + cur,\n '',\n );\n};\n","import { Entity, EntityMeta } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\n\nimport { PluginTaskScheduler } from '@backstage/backend-tasks';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport fetch from 'node-fetch';\nimport * as winston from 'winston';\nimport { API, APIProduct, APISchema, AccessTokensResponse } from './api-types';\nimport {\n getClientId,\n getClientSecret,\n getPortalServerUrl,\n getTokenEndpoint,\n} from './configHelpers';\nimport {\n doAccessTokenRequest,\n parseJwt,\n sanitizeStringForEntity,\n} from './utility';\n\n/**\n * Provides API entities from the Gloo Platform Portal REST server.\n */\nexport class GlooPlatformPortalProvider implements EntityProvider {\n private readonly env: string;\n private connection?: EntityProviderConnection;\n private logger: winston.Logger;\n private config: Config;\n private latestTokensResponse?: AccessTokensResponse;\n private debugLogging = false;\n\n log = (s: string) => this.logger.info(`gloo-platform-portal: ${s}`);\n warn = (s: string) => this.logger.warn(`gloo-platform-portal: ${s}`);\n error = (s: string) => this.logger.error(`gloo-platform-portal: ${s}`);\n getProviderName = () => `gloo-platform-portal-${this.env}`;\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n }\n\n //\n // 1. Init class\n //\n constructor(env: string, logger: winston.Logger, config: Config) {\n this.env = env;\n this.logger = logger;\n this.config = config;\n // Default extra debug-logging to false\n this.debugLogging = !!config.getOptionalBoolean(\n 'glooPlatformPortal.backend.debugLogging',\n );\n this.log('Initializing GlooPlatformPortalProvider.');\n this.startTokensRequests();\n }\n\n //\n // 2. Get access_token\n //\n async startTokensRequests() {\n //\n // Make the initial request for the access_token.\n if (this.debugLogging) {\n this.log('Making the initial access_token request.');\n }\n if (!this.config) {\n this.error(\n 'Backstage config object not found when doing access token request.',\n );\n return;\n }\n const res = await doAccessTokenRequest(\n 'client_credentials',\n getTokenEndpoint(this.error, this.warn, this.config),\n getClientId(this.error, this.warn, this.config),\n getClientSecret(this.error, this.warn, this.config),\n );\n this.latestTokensResponse = res;\n if (!this.latestTokensResponse) {\n // If there's a problem, wait to restart the access token\n // requests so as to not overload the auth server.\n this.warn('No latest access token. Re-requesting the access_token.');\n setTimeout(this.startTokensRequests.bind(this), 5000);\n return;\n }\n if (this.debugLogging) {\n this.log('Got the access_token.');\n }\n //\n // Parse the access_token JWT to find when it expires.\n const parsedToken = parseJwt(this.latestTokensResponse.access_token);\n if (!parsedToken.exp) {\n this.warn('No `exp` property found in the access_token JWT.');\n }\n const nowDate = new Date();\n const expiresDate = new Date(parsedToken.exp * 1000);\n const millisUntilExpires = expiresDate.getTime() - nowDate.getTime();\n if (millisUntilExpires <= 0) {\n this.warn('access token is expired!');\n this.latestTokensResponse = undefined;\n return;\n }\n if (this.debugLogging) {\n this.log('Setting a timeout to get the next access token.');\n }\n // Set the timeout to request new tokens.\n setTimeout(\n this.startTokensRequests.bind(this),\n // Don't make this request more than once a second,\n // and do the refresh 5 seconds early.\n Math.max(1000, millisUntilExpires - 5000),\n );\n }\n\n /**\n *\n * 3. Schedule sync.\n *\n * This is called during setup, and passes the user config into the\n * Backstage plugin task scheduler.\n * */\n async startScheduler(scheduler: PluginTaskScheduler) {\n const frequency = this.config.getOptionalConfig(\n 'glooPlatformPortal.backend.syncFrequency',\n );\n const timeout = this.config.getOptionalConfig(\n 'glooPlatformPortal.backend.syncTimeout',\n );\n await scheduler.scheduleTask({\n id: 'run_gloo_platform_portal_refresh',\n fn: async () => {\n await this.run();\n },\n frequency: !!frequency\n ? {\n hours: frequency.getOptionalNumber('hours'),\n minutes: frequency.getOptionalNumber('minutes'),\n seconds: frequency.getOptionalNumber('seconds'),\n milliseconds: frequency.getOptionalNumber('milliseconds'),\n }\n : {\n minutes: 5,\n },\n timeout: !!timeout\n ? {\n hours: timeout.getOptionalNumber('hours'),\n minutes: timeout.getOptionalNumber('minutes'),\n seconds: timeout.getOptionalNumber('seconds'),\n milliseconds: timeout.getOptionalNumber('milliseconds'),\n }\n : {\n seconds: 30,\n },\n });\n }\n\n /**\n *\n * 4. Return new Backstage entities.\n *\n * Requests API information from the Gloo Platform Portal REST server,\n * and transforms the response into Backstage API entities.\n */\n async run(): Promise<void> {\n if (!this.connection || !this.latestTokensResponse) {\n throw new Error('Not initialized');\n }\n\n const entities: Entity[] = [];\n const bsGroupName = 'solo-io-service-accounts';\n const bsServiceAccountName = 'gloo-platform-portal-service-account';\n const bsSystemName = 'gloo-platform-portal-apis';\n const portalServerUrl = getPortalServerUrl(\n this.error,\n this.warn,\n this.config,\n );\n const apisEndpoint = `${portalServerUrl}/apis`;\n //\n // Make API request\n try {\n const res = await fetch(apisEndpoint + '?includeSchema=true', {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n });\n let processedAPIs = (await res.json()) as API[];\n if (this.debugLogging) {\n this.log('Fetched APIs: ' + JSON.stringify(processedAPIs));\n }\n\n //\n // The server returns the APIs grouped by APIProduct,\n // so we can convert it back to a list here.\n //\n if (!!processedAPIs?.length && 'apiVersions' in processedAPIs[0]) {\n const apiProducts = processedAPIs as unknown as APIProduct[];\n processedAPIs = apiProducts.reduce((accum, curProd) => {\n accum.push(\n ...curProd.apiVersions.reduce((accumVer, api) => {\n if (!!api.openapiSpecFetchErr) {\n this.warn(\n `Schema fetch error for ${api.apiId} : ${JSON.stringify(\n api.openapiSpecFetchErr,\n )}`,\n );\n }\n accumVer.push({\n apiId: api.apiId,\n apiProductDisplayName: curProd.apiProductDisplayName,\n apiProductId: curProd.apiProductId,\n apiVersion: api.apiVersion,\n contact: api.contact,\n customMetadata: api.customMetadata,\n description: api.description,\n license: api.license,\n termsOfService: api.termsOfService,\n title: api.title,\n usagePlans: api.usagePlans,\n openapiSpec: api.openapiSpec,\n openapiSpecFetchErr: api.openapiSpecFetchErr,\n });\n return accumVer;\n }, [] as API[]),\n );\n return accum;\n }, [] as API[]);\n }\n\n //\n // Convert the APIs to entities\n for (let i = 0; i < processedAPIs.length; i++) {\n const apiVersion = processedAPIs[i];\n let schema = apiVersion.openapiSpec;\n if (!schema && !apiVersion.openapiSpecFetchErr) {\n // If the schema was not attempted to be fetched with\n // the /apis call, we individually fetch it here.\n // This is for backwards compatibility only, for\n // when the schema was not in the /apis response.\n const schemaRes = await fetch(\n `${apisEndpoint}/${apiVersion.apiId}/schema`,\n {\n headers: {\n Authorization: `Bearer ${this.latestTokensResponse.access_token}`,\n },\n },\n );\n schema = (await schemaRes.json()) as APISchema;\n }\n entities.push({\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'API',\n metadata: {\n tags: [\n 'gloo-platform',\n ...(!!apiVersion.apiVersion\n ? [\n 'api-version-' +\n sanitizeStringForEntity('tag', apiVersion.apiVersion),\n ]\n : []),\n ],\n name: sanitizeStringForEntity('name', apiVersion.apiId),\n title: apiVersion.apiId,\n description: apiVersion.description,\n annotations: {\n 'backstage.io/managed-by-location': `url:${apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n type: 'openapi',\n lifecycle: 'production',\n system: bsSystemName,\n owner: `user:${bsServiceAccountName}`,\n definition: JSON.stringify(schema),\n },\n });\n }\n if (this.debugLogging) {\n this.log(\n 'Transformed APIs into new entities: ' + JSON.stringify(entities),\n );\n }\n } catch (e) {\n this.error(\n `Could not get APIs from the portal server endpoint or their schemas or transform them into entities (${apisEndpoint}). Error: ${JSON.stringify(\n e,\n )}`,\n );\n }\n\n const locationKey = `gloo-platform-portal-provider:${this.env}`;\n await this.connection.applyMutation({\n type: 'full',\n entities: [\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Group',\n metadata: {\n name: bsGroupName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${portalServerUrl}`,\n },\n },\n spec: {\n type: 'service-account-group',\n children: [],\n members: [bsServiceAccountName],\n },\n },\n },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'User',\n metadata: {\n name: bsServiceAccountName,\n annotations: {\n 'backstage.io/managed-by-location': `url:${portalServerUrl}`,\n 'backstage.io/managed-by-origin-location': `url:${portalServerUrl}`,\n },\n },\n spec: {\n displayName: 'Solo.io Service Account',\n email: '',\n picture: '',\n memberOf: [bsGroupName],\n },\n },\n },\n // {\n // locationKey,\n // entity: {\n // apiVersion: 'backstage.io/v1alpha1',\n // kind: 'Domain',\n // metadata: {\n // tags: ['gloo-platform'],\n // name: 'api-product',\n // description: 'Gloo Platform Portal ApiProduct resources.',\n // annotations: {\n // 'backstage.io/managed-by-location': 'url:' + apisEndpoint,\n // 'backstage.io/managed-by-origin-location':\n // 'url:' + apisEndpoint,\n // },\n // } as EntityMeta,\n // spec: {\n // owner: 'user:' + bsServiceAccountName,\n // },\n // },\n // },\n {\n locationKey,\n entity: {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'System',\n metadata: {\n tags: ['gloo-platform'],\n name: bsSystemName,\n title: 'Gloo Platform Portal APIs',\n annotations: {\n 'backstage.io/managed-by-location': `url:${apisEndpoint}`,\n 'backstage.io/managed-by-origin-location': `url:${apisEndpoint}`,\n },\n } as EntityMeta,\n spec: {\n owner: `user:${bsServiceAccountName}`,\n // domain: 'api-product',\n },\n },\n },\n ...entities.map(entity => ({ locationKey, entity })),\n ],\n });\n }\n}\n"],"names":["fetch"],"mappings":";;;;;;;;;;AAIO,MAAM,kBAAqB,GAAA,CAAC,MAAe,EAAA,CAAA,EAAU,MAAmB,KAAA;AAC7E,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAA,MAAA,CAAO,2DAA2D,CAAA,CAAA;AAClE,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AACA,EAAA,IAAI,QAAQ,MAAO,CAAA,iBAAA;AAAA,IACjB,4CAAA;AAAA,GACF,CAAA;AAEA,EAAA,IAAI,CAAC,CAAC,KAAA,IAAS,KAAM,CAAA,EAAA,CAAG,EAAE,CAAM,KAAA,GAAA;AAC9B,IAAA,KAAA,GAAQ,KAAM,CAAA,SAAA,CAAU,CAAG,EAAA,KAAA,CAAM,SAAS,CAAC,CAAA,CAAA;AAC7C,EAAA,OAAO,KAAS,IAAA,IAAA,GAAA,KAAA,GAAA,2BAAA,CAAA;AAClB,CAAA,CAAA;AAEO,MAAM,eAAkB,GAAA,CAC7B,MACA,EAAA,UAAA,EACA,MACG,KAAA;AACH,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAA,MAAA,CAAO,uDAAuD,CAAA,CAAA;AAC9D,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AACA,EAAA,MAAM,QAAQ,MAAO,CAAA,iBAAA;AAAA,IACnB,yCAAA;AAAA,GACF,CAAA;AACA,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAA,UAAA;AAAA,MACE,2EAAA;AAAA,KACF,CAAA;AAAA,GACF;AACA,EAAA,OAAO,KAAS,IAAA,IAAA,GAAA,KAAA,GAAA,EAAA,CAAA;AAClB,CAAA,CAAA;AAEO,MAAM,WAAc,GAAA,CACzB,MACA,EAAA,UAAA,EACA,MACG,KAAA;AACH,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAA,MAAA,CAAO,mDAAmD,CAAA,CAAA;AAC1D,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AACA,EAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,iBAAA,CAAkB,qCAAqC,CAAA,CAAA;AAC5E,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAA,UAAA;AAAA,MACE,uEAAA;AAAA,KACF,CAAA;AAAA,GACF;AACA,EAAA,OAAO,KAAS,IAAA,IAAA,GAAA,KAAA,GAAA,EAAA,CAAA;AAClB,CAAA,CAAA;AAEO,MAAM,gBAAmB,GAAA,CAC9B,MACA,EAAA,UAAA,EACA,MACG,KAAA;AACH,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAA,MAAA,CAAO,wDAAwD,CAAA,CAAA;AAC/D,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AACA,EAAA,MAAM,QAAQ,MAAO,CAAA,iBAAA;AAAA,IACnB,0CAAA;AAAA,GACF,CAAA;AACA,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAA,UAAA;AAAA,MACE,4EAAA;AAAA,KACF,CAAA;AAAA,GACF;AACA,EAAA,OAAO,KAAS,IAAA,IAAA,GAAA,KAAA,GAAA,EAAA,CAAA;AAClB,CAAA;;ACvEO,SAAS,SAAS,KAAe,EAAA;AACtC,EAAA,MAAM,SAAY,GAAA,KAAA,CAAM,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA,CAAA;AACpC,EAAM,MAAA,MAAA,GAAS,UAAU,OAAQ,CAAA,IAAA,EAAM,GAAG,CAAE,CAAA,OAAA,CAAQ,MAAM,GAAG,CAAA,CAAA;AAC7D,EAAA,MAAM,WAAc,GAAA,kBAAA;AAAA,IAClB,IAAA,CAAK,MAAM,CAAA,CACR,KAAM,CAAA,EAAE,EACR,GAAI,CAAA,CAAA,CAAA,KAAK,CAAI,CAAA,EAAA,CAAA,EAAA,EAAK,CAAE,CAAA,UAAA,CAAW,CAAC,CAAE,CAAA,QAAA,CAAS,EAAE,CAAC,CAAG,CAAA,CAAA,KAAA,CAAM,EAAE,CAAC,CAAA,CAAE,CAC5D,CAAA,IAAA,CAAK,EAAE,CAAA;AAAA,GACZ,CAAA;AACA,EAAO,OAAA,IAAA,CAAK,MAAM,WAAW,CAAA,CAAA;AAC/B,CAAA;AAEO,SAAS,8BACd,WACA,EAAA;AACA,EAAA,MAAM,iBAAiB,EAAC,CAAA;AACxB,EAAA,KAAA,MAAW,YAAY,WAAa,EAAA;AAClC,IAAI,IAAA,CAAC,WAAY,CAAA,cAAA,CAAe,QAAQ,CAAA;AAAG,MAAA,SAAA;AAC3C,IAAM,MAAA,UAAA,GAAa,mBAAmB,QAAQ,CAAA,CAAA;AAC9C,IAAA,MAAM,YAAe,GAAA,kBAAA;AAAA,MACnB,YAAY,QAAoC,CAAA;AAAA,KAClD,CAAA;AACA,IAAA,cAAA,CAAe,IAAK,CAAA,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,YAAY,CAAE,CAAA,CAAA,CAAA;AAAA,GACrD;AACA,EAAM,MAAA,cAAA,GAAiB,cAAe,CAAA,IAAA,CAAK,GAAG,CAAA,CAAA;AAC9C,EAAO,OAAA,cAAA,CAAA;AACT,CAAA;AAEA,eAAsB,oBACpB,CAAA,SAAA,EACA,aACA,EAAA,QAAA,EACA,cACA,YACA,EAAA;AACA,EAAA,MAAM,WAAW,EAAC,CAAA;AAIlB,EAAA,QAAA,CAAS,UAAa,GAAA,SAAA,CAAA;AACtB,EAAA,QAAA,CAAS,SAAY,GAAA,QAAA,CAAA;AACrB,EAAA,QAAA,CAAS,aAAgB,GAAA,YAAA,CAAA;AACzB,EAAA,IAAI,cAAc,eAAiB,EAAA;AACjC,IAAA,IAAI,CAAC,YAAc,EAAA;AACjB,MAAO,OAAA,KAAA,CAAA,CAAA;AAAA,KACT;AACA,IAAA,QAAA,CAAS,aAAgB,GAAA,YAAA,CAAA;AAAA,GAC3B;AAIA,EAAM,MAAA,MAAA,GAAS,MAAMA,yBAAA,CAAM,aAAe,EAAA;AAAA,IACxC,OAAS,EAAA;AAAA,MACP,cAAgB,EAAA,iDAAA;AAAA,KAClB;AAAA,IACA,MAAQ,EAAA,MAAA;AAAA,IACR,IAAA,EAAM,8BAA8B,QAAQ,CAAA;AAAA,GAC7C,CAAA,CAAA;AACD,EAAI,IAAA,OAAA,CAAA;AACJ,EAAI,IAAA;AACF,IAAU,OAAA,GAAA,MAAM,OAAO,IAAK,EAAA,CAAA;AAAA,GACtB,CAAA,MAAA;AACN,IAAM,MAAA,IAAI,MAAM,+BAA+B,CAAA,CAAA;AAAA,GACjD;AACA,EAAI,IAAA,CAAC,CAAC,OAAA,CAAQ,iBAAmB,EAAA;AAC/B,IAAM,MAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,iBAAiB,CAAA,CAAA;AAAA,GAC3C;AACA,EAAI,IAAA,CAAC,CAAC,OAAA,CAAQ,KAAO,EAAA;AACnB,IAAM,MAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAA,CAAA;AAAA,GAC/B;AAIA,EAAI,IAAA,CAAC,QAAQ,YAAc,EAAA;AACzB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,kEAAA;AAAA,KACF,CAAA;AAAA,GACF;AACA,EAAO,OAAA,OAAA,CAAA;AACT,CAAA;AAKA,MAAM,aAAgB,GAAA;AAAA;AAAA,EAEpB,GAAK,EAAA,yBAAA;AAAA;AAAA;AAAA,EAGL,IAAM,EAAA,4BAAA;AAAA;AAAA,EAEN,SAAW,EAAA,sBAAA;AACb,CAAA,CAAA;AAKa,MAAA,uBAAA,GAA0B,CACrC,YAAA,EACA,aACG,KAAA;AACH,EAAA,OAAO,aACJ,CAAA,KAAA,CAAM,EAAE,CAAA,CACR,IAAI,CAAO,EAAA,KAAA,CAAC,aAAc,CAAA,YAAY,EAAE,IAAK,CAAA,EAAE,CAAI,GAAA,GAAA,GAAM,EAAG,CAC5D,CAAA,MAAA;AAAA,IACC,CAAC,IAAM,EAAA,GAAA;AAAA;AAAA,MAEL,IAAA,CAAK,UAAU,EACX,GAAA,IAAA;AAAA;AAAA,QAEF,IAAA,CAAK,GAAG,CAAE,CAAA,CAAA,KAAM,OAAO,GAAQ,KAAA,GAAA,GAC7B,OACA,IAAO,GAAA,GAAA;AAAA,OAAA;AAAA,KAAA;AAAA,IACb,EAAA;AAAA,GACF,CAAA;AACJ,CAAA;;;;;;;;AC5FO,MAAM,0BAAqD,CAAA;AAAA;AAAA;AAAA;AAAA,EAmBhE,WAAA,CAAY,GAAa,EAAA,MAAA,EAAwB,MAAgB,EAAA;AAlBjE,IAAiB,aAAA,CAAA,IAAA,EAAA,KAAA,CAAA,CAAA;AACjB,IAAQ,aAAA,CAAA,IAAA,EAAA,YAAA,CAAA,CAAA;AACR,IAAQ,aAAA,CAAA,IAAA,EAAA,QAAA,CAAA,CAAA;AACR,IAAQ,aAAA,CAAA,IAAA,EAAA,QAAA,CAAA,CAAA;AACR,IAAQ,aAAA,CAAA,IAAA,EAAA,sBAAA,CAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,cAAe,EAAA,KAAA,CAAA,CAAA;AAEvB,IAAA,aAAA,CAAA,IAAA,EAAA,KAAA,EAAM,CAAC,CAAc,KAAA,IAAA,CAAK,OAAO,IAAK,CAAA,CAAA,sBAAA,EAAyB,CAAC,CAAE,CAAA,CAAA,CAAA,CAAA;AAClE,IAAA,aAAA,CAAA,IAAA,EAAA,MAAA,EAAO,CAAC,CAAc,KAAA,IAAA,CAAK,OAAO,IAAK,CAAA,CAAA,sBAAA,EAAyB,CAAC,CAAE,CAAA,CAAA,CAAA,CAAA;AACnE,IAAA,aAAA,CAAA,IAAA,EAAA,OAAA,EAAQ,CAAC,CAAc,KAAA,IAAA,CAAK,OAAO,KAAM,CAAA,CAAA,sBAAA,EAAyB,CAAC,CAAE,CAAA,CAAA,CAAA,CAAA;AACrE,IAAkB,aAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,MAAM,CAAwB,qBAAA,EAAA,IAAA,CAAK,GAAG,CAAA,CAAA,CAAA,CAAA;AAStD,IAAA,IAAA,CAAK,GAAM,GAAA,GAAA,CAAA;AACX,IAAA,IAAA,CAAK,MAAS,GAAA,MAAA,CAAA;AACd,IAAA,IAAA,CAAK,MAAS,GAAA,MAAA,CAAA;AAEd,IAAK,IAAA,CAAA,YAAA,GAAe,CAAC,CAAC,MAAO,CAAA,kBAAA;AAAA,MAC3B,yCAAA;AAAA,KACF,CAAA;AACA,IAAA,IAAA,CAAK,IAAI,0CAA0C,CAAA,CAAA;AACnD,IAAA,IAAA,CAAK,mBAAoB,EAAA,CAAA;AAAA,GAC3B;AAAA,EAjBA,MAAM,QAAQ,UAAqD,EAAA;AACjE,IAAA,IAAA,CAAK,UAAa,GAAA,UAAA,CAAA;AAAA,GACpB;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,mBAAsB,GAAA;AAG1B,IAAA,IAAI,KAAK,YAAc,EAAA;AACrB,MAAA,IAAA,CAAK,IAAI,0CAA0C,CAAA,CAAA;AAAA,KACrD;AACA,IAAI,IAAA,CAAC,KAAK,MAAQ,EAAA;AAChB,MAAK,IAAA,CAAA,KAAA;AAAA,QACH,oEAAA;AAAA,OACF,CAAA;AACA,MAAA,OAAA;AAAA,KACF;AACA,IAAA,MAAM,MAAM,MAAM,oBAAA;AAAA,MAChB,oBAAA;AAAA,MACA,iBAAiB,IAAK,CAAA,KAAA,EAAO,IAAK,CAAA,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,MACnD,YAAY,IAAK,CAAA,KAAA,EAAO,IAAK,CAAA,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,MAC9C,gBAAgB,IAAK,CAAA,KAAA,EAAO,IAAK,CAAA,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,KACpD,CAAA;AACA,IAAA,IAAA,CAAK,oBAAuB,GAAA,GAAA,CAAA;AAC5B,IAAI,IAAA,CAAC,KAAK,oBAAsB,EAAA;AAG9B,MAAA,IAAA,CAAK,KAAK,yDAAyD,CAAA,CAAA;AACnE,MAAA,UAAA,CAAW,IAAK,CAAA,mBAAA,CAAoB,IAAK,CAAA,IAAI,GAAG,GAAI,CAAA,CAAA;AACpD,MAAA,OAAA;AAAA,KACF;AACA,IAAA,IAAI,KAAK,YAAc,EAAA;AACrB,MAAA,IAAA,CAAK,IAAI,uBAAuB,CAAA,CAAA;AAAA,KAClC;AAGA,IAAA,MAAM,WAAc,GAAA,QAAA,CAAS,IAAK,CAAA,oBAAA,CAAqB,YAAY,CAAA,CAAA;AACnE,IAAI,IAAA,CAAC,YAAY,GAAK,EAAA;AACpB,MAAA,IAAA,CAAK,KAAK,kDAAkD,CAAA,CAAA;AAAA,KAC9D;AACA,IAAM,MAAA,OAAA,uBAAc,IAAK,EAAA,CAAA;AACzB,IAAA,MAAM,WAAc,GAAA,IAAI,IAAK,CAAA,WAAA,CAAY,MAAM,GAAI,CAAA,CAAA;AACnD,IAAA,MAAM,kBAAqB,GAAA,WAAA,CAAY,OAAQ,EAAA,GAAI,QAAQ,OAAQ,EAAA,CAAA;AACnE,IAAA,IAAI,sBAAsB,CAAG,EAAA;AAC3B,MAAA,IAAA,CAAK,KAAK,0BAA0B,CAAA,CAAA;AACpC,MAAA,IAAA,CAAK,oBAAuB,GAAA,KAAA,CAAA,CAAA;AAC5B,MAAA,OAAA;AAAA,KACF;AACA,IAAA,IAAI,KAAK,YAAc,EAAA;AACrB,MAAA,IAAA,CAAK,IAAI,iDAAiD,CAAA,CAAA;AAAA,KAC5D;AAEA,IAAA,UAAA;AAAA,MACE,IAAA,CAAK,mBAAoB,CAAA,IAAA,CAAK,IAAI,CAAA;AAAA;AAAA;AAAA,MAGlC,IAAK,CAAA,GAAA,CAAI,GAAM,EAAA,kBAAA,GAAqB,GAAI,CAAA;AAAA,KAC1C,CAAA;AAAA,GACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAe,SAAgC,EAAA;AACnD,IAAM,MAAA,SAAA,GAAY,KAAK,MAAO,CAAA,iBAAA;AAAA,MAC5B,0CAAA;AAAA,KACF,CAAA;AACA,IAAM,MAAA,OAAA,GAAU,KAAK,MAAO,CAAA,iBAAA;AAAA,MAC1B,wCAAA;AAAA,KACF,CAAA;AACA,IAAA,MAAM,UAAU,YAAa,CAAA;AAAA,MAC3B,EAAI,EAAA,kCAAA;AAAA,MACJ,IAAI,YAAY;AACd,QAAA,MAAM,KAAK,GAAI,EAAA,CAAA;AAAA,OACjB;AAAA,MACA,SAAA,EAAW,CAAC,CAAC,SACT,GAAA;AAAA,QACE,KAAA,EAAO,SAAU,CAAA,iBAAA,CAAkB,OAAO,CAAA;AAAA,QAC1C,OAAA,EAAS,SAAU,CAAA,iBAAA,CAAkB,SAAS,CAAA;AAAA,QAC9C,OAAA,EAAS,SAAU,CAAA,iBAAA,CAAkB,SAAS,CAAA;AAAA,QAC9C,YAAA,EAAc,SAAU,CAAA,iBAAA,CAAkB,cAAc,CAAA;AAAA,OAE1D,GAAA;AAAA,QACE,OAAS,EAAA,CAAA;AAAA,OACX;AAAA,MACJ,OAAA,EAAS,CAAC,CAAC,OACP,GAAA;AAAA,QACE,KAAA,EAAO,OAAQ,CAAA,iBAAA,CAAkB,OAAO,CAAA;AAAA,QACxC,OAAA,EAAS,OAAQ,CAAA,iBAAA,CAAkB,SAAS,CAAA;AAAA,QAC5C,OAAA,EAAS,OAAQ,CAAA,iBAAA,CAAkB,SAAS,CAAA;AAAA,QAC5C,YAAA,EAAc,OAAQ,CAAA,iBAAA,CAAkB,cAAc,CAAA;AAAA,OAExD,GAAA;AAAA,QACE,OAAS,EAAA,EAAA;AAAA,OACX;AAAA,KACL,CAAA,CAAA;AAAA,GACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,GAAqB,GAAA;AACzB,IAAA,IAAI,CAAC,IAAA,CAAK,UAAc,IAAA,CAAC,KAAK,oBAAsB,EAAA;AAClD,MAAM,MAAA,IAAI,MAAM,iBAAiB,CAAA,CAAA;AAAA,KACnC;AAEA,IAAA,MAAM,WAAqB,EAAC,CAAA;AAC5B,IAAA,MAAM,WAAc,GAAA,0BAAA,CAAA;AACpB,IAAA,MAAM,oBAAuB,GAAA,sCAAA,CAAA;AAC7B,IAAA,MAAM,YAAe,GAAA,2BAAA,CAAA;AACrB,IAAA,MAAM,eAAkB,GAAA,kBAAA;AAAA,MACtB,IAAK,CAAA,KAAA;AAAA,MACL,IAAK,CAAA,IAAA;AAAA,MACL,IAAK,CAAA,MAAA;AAAA,KACP,CAAA;AACA,IAAM,MAAA,YAAA,GAAe,GAAG,eAAe,CAAA,KAAA,CAAA,CAAA;AAGvC,IAAI,IAAA;AACF,MAAA,MAAM,GAAM,GAAA,MAAMA,yBAAM,CAAA,YAAA,GAAe,qBAAuB,EAAA;AAAA,QAC5D,OAAS,EAAA;AAAA,UACP,aAAe,EAAA,CAAA,OAAA,EAAU,IAAK,CAAA,oBAAA,CAAqB,YAAY,CAAA,CAAA;AAAA,SACjE;AAAA,OACD,CAAA,CAAA;AACD,MAAI,IAAA,aAAA,GAAiB,MAAM,GAAA,CAAI,IAAK,EAAA,CAAA;AACpC,MAAA,IAAI,KAAK,YAAc,EAAA;AACrB,QAAA,IAAA,CAAK,GAAI,CAAA,gBAAA,GAAmB,IAAK,CAAA,SAAA,CAAU,aAAa,CAAC,CAAA,CAAA;AAAA,OAC3D;AAMA,MAAA,IAAI,CAAC,EAAC,aAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,aAAA,CAAe,WAAU,aAAiB,IAAA,aAAA,CAAc,CAAC,CAAG,EAAA;AAChE,QAAA,MAAM,WAAc,GAAA,aAAA,CAAA;AACpB,QAAA,aAAA,GAAgB,WAAY,CAAA,MAAA,CAAO,CAAC,KAAA,EAAO,OAAY,KAAA;AACrD,UAAM,KAAA,CAAA,IAAA;AAAA,YACJ,GAAG,OAAQ,CAAA,WAAA,CAAY,MAAO,CAAA,CAAC,UAAU,GAAQ,KAAA;AAC/C,cAAI,IAAA,CAAC,CAAC,GAAA,CAAI,mBAAqB,EAAA;AAC7B,gBAAK,IAAA,CAAA,IAAA;AAAA,kBACH,CAA0B,uBAAA,EAAA,GAAA,CAAI,KAAK,CAAA,GAAA,EAAM,IAAK,CAAA,SAAA;AAAA,oBAC5C,GAAI,CAAA,mBAAA;AAAA,mBACL,CAAA,CAAA;AAAA,iBACH,CAAA;AAAA,eACF;AACA,cAAA,QAAA,CAAS,IAAK,CAAA;AAAA,gBACZ,OAAO,GAAI,CAAA,KAAA;AAAA,gBACX,uBAAuB,OAAQ,CAAA,qBAAA;AAAA,gBAC/B,cAAc,OAAQ,CAAA,YAAA;AAAA,gBACtB,YAAY,GAAI,CAAA,UAAA;AAAA,gBAChB,SAAS,GAAI,CAAA,OAAA;AAAA,gBACb,gBAAgB,GAAI,CAAA,cAAA;AAAA,gBACpB,aAAa,GAAI,CAAA,WAAA;AAAA,gBACjB,SAAS,GAAI,CAAA,OAAA;AAAA,gBACb,gBAAgB,GAAI,CAAA,cAAA;AAAA,gBACpB,OAAO,GAAI,CAAA,KAAA;AAAA,gBACX,YAAY,GAAI,CAAA,UAAA;AAAA,gBAChB,aAAa,GAAI,CAAA,WAAA;AAAA,gBACjB,qBAAqB,GAAI,CAAA,mBAAA;AAAA,eAC1B,CAAA,CAAA;AACD,cAAO,OAAA,QAAA,CAAA;AAAA,aACT,EAAG,EAAW,CAAA;AAAA,WAChB,CAAA;AACA,UAAO,OAAA,KAAA,CAAA;AAAA,SACT,EAAG,EAAW,CAAA,CAAA;AAAA,OAChB;AAIA,MAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,aAAA,CAAc,QAAQ,CAAK,EAAA,EAAA;AAC7C,QAAM,MAAA,UAAA,GAAa,cAAc,CAAC,CAAA,CAAA;AAClC,QAAA,IAAI,SAAS,UAAW,CAAA,WAAA,CAAA;AACxB,QAAA,IAAI,CAAC,MAAA,IAAU,CAAC,UAAA,CAAW,mBAAqB,EAAA;AAK9C,UAAA,MAAM,YAAY,MAAMA,yBAAA;AAAA,YACtB,CAAG,EAAA,YAAY,CAAI,CAAA,EAAA,UAAA,CAAW,KAAK,CAAA,OAAA,CAAA;AAAA,YACnC;AAAA,cACE,OAAS,EAAA;AAAA,gBACP,aAAe,EAAA,CAAA,OAAA,EAAU,IAAK,CAAA,oBAAA,CAAqB,YAAY,CAAA,CAAA;AAAA,eACjE;AAAA,aACF;AAAA,WACF,CAAA;AACA,UAAU,MAAA,GAAA,MAAM,UAAU,IAAK,EAAA,CAAA;AAAA,SACjC;AACA,QAAA,QAAA,CAAS,IAAK,CAAA;AAAA,UACZ,UAAY,EAAA,uBAAA;AAAA,UACZ,IAAM,EAAA,KAAA;AAAA,UACN,QAAU,EAAA;AAAA,YACR,IAAM,EAAA;AAAA,cACJ,eAAA;AAAA,cACA,GAAI,CAAC,CAAC,UAAA,CAAW,UACb,GAAA;AAAA,gBACE,cACE,GAAA,uBAAA,CAAwB,KAAO,EAAA,UAAA,CAAW,UAAU,CAAA;AAAA,kBAExD,EAAC;AAAA,aACP;AAAA,YACA,IAAM,EAAA,uBAAA,CAAwB,MAAQ,EAAA,UAAA,CAAW,KAAK,CAAA;AAAA,YACtD,OAAO,UAAW,CAAA,KAAA;AAAA,YAClB,aAAa,UAAW,CAAA,WAAA;AAAA,YACxB,WAAa,EAAA;AAAA,cACX,kCAAA,EAAoC,OAAO,YAAY,CAAA,CAAA;AAAA,cACvD,yCAAA,EAA2C,OAAO,YAAY,CAAA,CAAA;AAAA,aAChE;AAAA,WACF;AAAA,UACA,IAAM,EAAA;AAAA,YACJ,IAAM,EAAA,SAAA;AAAA,YACN,SAAW,EAAA,YAAA;AAAA,YACX,MAAQ,EAAA,YAAA;AAAA,YACR,KAAA,EAAO,QAAQ,oBAAoB,CAAA,CAAA;AAAA,YACnC,UAAA,EAAY,IAAK,CAAA,SAAA,CAAU,MAAM,CAAA;AAAA,WACnC;AAAA,SACD,CAAA,CAAA;AAAA,OACH;AACA,MAAA,IAAI,KAAK,YAAc,EAAA;AACrB,QAAK,IAAA,CAAA,GAAA;AAAA,UACH,sCAAA,GAAyC,IAAK,CAAA,SAAA,CAAU,QAAQ,CAAA;AAAA,SAClE,CAAA;AAAA,OACF;AAAA,aACO,CAAG,EAAA;AACV,MAAK,IAAA,CAAA,KAAA;AAAA,QACH,CAAA,qGAAA,EAAwG,YAAY,CAAA,UAAA,EAAa,IAAK,CAAA,SAAA;AAAA,UACpI,CAAA;AAAA,SACD,CAAA,CAAA;AAAA,OACH,CAAA;AAAA,KACF;AAEA,IAAM,MAAA,WAAA,GAAc,CAAiC,8BAAA,EAAA,IAAA,CAAK,GAAG,CAAA,CAAA,CAAA;AAC7D,IAAM,MAAA,IAAA,CAAK,WAAW,aAAc,CAAA;AAAA,MAClC,IAAM,EAAA,MAAA;AAAA,MACN,QAAU,EAAA;AAAA,QACR;AAAA,UACE,WAAA;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,UAAY,EAAA,uBAAA;AAAA,YACZ,IAAM,EAAA,OAAA;AAAA,YACN,QAAU,EAAA;AAAA,cACR,IAAM,EAAA,WAAA;AAAA,cACN,WAAa,EAAA;AAAA,gBACX,kCAAA,EAAoC,OAAO,eAAe,CAAA,CAAA;AAAA,gBAC1D,yCAAA,EAA2C,OAAO,eAAe,CAAA,CAAA;AAAA,eACnE;AAAA,aACF;AAAA,YACA,IAAM,EAAA;AAAA,cACJ,IAAM,EAAA,uBAAA;AAAA,cACN,UAAU,EAAC;AAAA,cACX,OAAA,EAAS,CAAC,oBAAoB,CAAA;AAAA,aAChC;AAAA,WACF;AAAA,SACF;AAAA,QACA;AAAA,UACE,WAAA;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,UAAY,EAAA,uBAAA;AAAA,YACZ,IAAM,EAAA,MAAA;AAAA,YACN,QAAU,EAAA;AAAA,cACR,IAAM,EAAA,oBAAA;AAAA,cACN,WAAa,EAAA;AAAA,gBACX,kCAAA,EAAoC,OAAO,eAAe,CAAA,CAAA;AAAA,gBAC1D,yCAAA,EAA2C,OAAO,eAAe,CAAA,CAAA;AAAA,eACnE;AAAA,aACF;AAAA,YACA,IAAM,EAAA;AAAA,cACJ,WAAa,EAAA,yBAAA;AAAA,cACb,KAAO,EAAA,EAAA;AAAA,cACP,OAAS,EAAA,EAAA;AAAA,cACT,QAAA,EAAU,CAAC,WAAW,CAAA;AAAA,aACxB;AAAA,WACF;AAAA,SACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAqBA;AAAA,UACE,WAAA;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,UAAY,EAAA,uBAAA;AAAA,YACZ,IAAM,EAAA,QAAA;AAAA,YACN,QAAU,EAAA;AAAA,cACR,IAAA,EAAM,CAAC,eAAe,CAAA;AAAA,cACtB,IAAM,EAAA,YAAA;AAAA,cACN,KAAO,EAAA,2BAAA;AAAA,cACP,WAAa,EAAA;AAAA,gBACX,kCAAA,EAAoC,OAAO,YAAY,CAAA,CAAA;AAAA,gBACvD,yCAAA,EAA2C,OAAO,YAAY,CAAA,CAAA;AAAA,eAChE;AAAA,aACF;AAAA,YACA,IAAM,EAAA;AAAA,cACJ,KAAA,EAAO,QAAQ,oBAAoB,CAAA,CAAA;AAAA;AAAA,aAErC;AAAA,WACF;AAAA,SACF;AAAA,QACA,GAAG,QAAS,CAAA,GAAA,CAAI,aAAW,EAAE,WAAA,EAAa,QAAS,CAAA,CAAA;AAAA,OACrD;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF;;;;"}
package/dist/index.d.ts CHANGED
@@ -22,15 +22,7 @@ declare class GlooPlatformPortalProvider implements EntityProvider {
22
22
  startTokensRequests(): Promise<void>;
23
23
  /**
24
24
  *
25
- * 3. Get refresh_tokens.
26
- *
27
- * Calling this will refresh the access_token when it is expiring soon,
28
- * using the refresh_token in the access tokens response.
29
- * */
30
- refreshTheToken(): Promise<void>;
31
- /**
32
- *
33
- * 4. Schedule sync.
25
+ * 3. Schedule sync.
34
26
  *
35
27
  * This is called during setup, and passes the user config into the
36
28
  * Backstage plugin task scheduler.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@solo.io/platform-portal-backstage-plugin-backend",
3
3
  "description": "A Backstage backend plugin that synchronizes Gloo Platform Portal APIs with the Backstage catalog.",
4
- "version": "0.0.19",
4
+ "version": "0.0.21",
5
5
  "main": "dist/index.cjs.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",