@adobe/spacecat-shared-http-utils 1.10.2 → 1.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [@adobe/spacecat-shared-http-utils-v1.10.4](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-http-utils-v1.10.3...@adobe/spacecat-shared-http-utils-v1.10.4) (2025-05-07)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * auth handling with ims token ([#678](https://github.com/adobe/spacecat-shared/issues/678)) ([9868748](https://github.com/adobe/spacecat-shared/commit/9868748b6d6d7269d2b598748f26f02dc707b1d6))
7
+
8
+ # [@adobe/spacecat-shared-http-utils-v1.10.3](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-http-utils-v1.10.2...@adobe/spacecat-shared-http-utils-v1.10.3) (2025-04-15)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **deps:** update external fixes ([#679](https://github.com/adobe/spacecat-shared/issues/679)) ([a41bf0c](https://github.com/adobe/spacecat-shared/commit/a41bf0cd488efa0f72af0933992edb256302af18))
14
+
1
15
  # [@adobe/spacecat-shared-http-utils-v1.10.2](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-http-utils-v1.10.1...@adobe/spacecat-shared-http-utils-v1.10.2) (2025-04-02)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-http-utils",
3
- "version": "1.10.2",
3
+ "version": "1.10.4",
4
4
  "description": "Shared modules of the Spacecat Services - HTTP Utils",
5
5
  "type": "module",
6
6
  "engines": {
@@ -36,7 +36,7 @@
36
36
  "@adobe/fetch": "4.2.0",
37
37
  "@adobe/spacecat-shared-utils": "1.26.4",
38
38
  "@adobe/spacecat-shared-data-access": "2.0.2",
39
- "jose": "6.0.8"
39
+ "jose": "6.0.10"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@adobe/helix-shared-wrap": "2.0.2",
@@ -72,6 +72,8 @@ export default class AuthInfo {
72
72
  return this;
73
73
  }
74
74
 
75
+ getType() { return this.type; }
76
+
75
77
  getScopes() { return this.scopes; }
76
78
 
77
79
  getProfile() { return this.profile; }
@@ -79,4 +81,18 @@ export default class AuthInfo {
79
81
  getReason() { return this.reason; }
80
82
 
81
83
  isAuthenticated() { return this.authenticated; }
84
+
85
+ isAdmin() { return this.profile?.is_admin; }
86
+
87
+ hasOrganization(orgId) {
88
+ const [id] = orgId.split('@');
89
+ return this.profile?.tenants?.some(
90
+ (tenant) => tenant.id === id,
91
+ );
92
+ }
93
+
94
+ hasScope(name, subScope) {
95
+ return this.scopes.some((scope) => scope.name === name
96
+ && (!subScope || scope.subScopes?.includes(subScope)));
97
+ }
82
98
  }
@@ -40,6 +40,7 @@ const IGNORED_PROFILE_PROPS = [
40
40
  const loadConfig = (context) => {
41
41
  try {
42
42
  const config = JSON.parse(context.env.AUTH_HANDLER_IMS);
43
+ context.log.info(`Loaded config name: ${config.name}`);
43
44
  return config;
44
45
  } catch (e) {
45
46
  context.log.error(`Failed to load config from context: ${e.message}`);
@@ -122,7 +123,8 @@ export default class AdobeImsHandler extends AbstractHandler {
122
123
  return new AuthInfo()
123
124
  .withType(this.name)
124
125
  .withAuthenticated(true)
125
- .withProfile(profile);
126
+ .withProfile(profile)
127
+ .withScopes([{ name: 'admin' }]);
126
128
  } catch (e) {
127
129
  this.log(`Failed to validate token: ${e.message}`, 'error');
128
130
  }
@@ -26,12 +26,14 @@ export default class JwtHandler extends AbstractHandler {
26
26
  }
27
27
 
28
28
  async #setup(context) {
29
- const authPublicKey = context.env?.AUTH_PUBLIC_KEY;
29
+ const authPublicKeyB64 = context.env?.AUTH_PUBLIC_KEY_B64;
30
30
 
31
- if (!hasText(authPublicKey)) {
31
+ if (!hasText(authPublicKeyB64)) {
32
32
  throw new Error('No public key provided');
33
33
  }
34
34
 
35
+ const authPublicKey = Buffer.from(authPublicKeyB64, 'base64').toString('utf-8');
36
+
35
37
  this.authPublicKey = await importSPKI(authPublicKey, ALGORITHM_ES256);
36
38
  }
37
39
 
@@ -48,14 +50,12 @@ export default class JwtHandler extends AbstractHandler {
48
50
  },
49
51
  );
50
52
 
53
+ verifiedToken.payload.tenants = verifiedToken.payload.tenants || [];
54
+
51
55
  return verifiedToken.payload;
52
56
  }
53
57
 
54
58
  async checkAuth(request, context) {
55
- const authInfo = new AuthInfo()
56
- .withType(this.name)
57
- .withAuthenticated(false);
58
-
59
59
  try {
60
60
  await this.#setup(context);
61
61
 
@@ -63,21 +63,26 @@ export default class JwtHandler extends AbstractHandler {
63
63
 
64
64
  if (!hasText(token)) {
65
65
  this.log('No bearer token provided', 'debug');
66
- authInfo.withReason('No bearer token provided');
67
- return authInfo;
66
+ return null;
68
67
  }
69
68
 
70
69
  const payload = await this.#validateToken(token);
71
70
 
71
+ const scopes = payload.is_admin ? [{ name: 'admin' }] : [];
72
+
73
+ scopes.push(...payload.tenants.map(
74
+ (tenant) => ({ name: 'user', domains: [tenant.id], subScopes: tenant.subServices }),
75
+ ));
76
+
72
77
  return new AuthInfo()
73
78
  .withType(this.name)
74
79
  .withAuthenticated(true)
75
- .withProfile(payload);
80
+ .withProfile(payload)
81
+ .withScopes(scopes);
76
82
  } catch (e) {
77
83
  this.log(`Failed to validate token: ${e.message}`, 'error');
78
- authInfo.withReason(e.message);
79
84
  }
80
85
 
81
- return authInfo;
86
+ return null;
82
87
  }
83
88
  }
package/src/index.d.ts CHANGED
@@ -25,6 +25,10 @@ export declare function internalServerError(message?: string, headers?: object):
25
25
 
26
26
  export declare function found(location: string): Response;
27
27
 
28
+ export declare function unauthorized(message?: string, headers?: object): Response;
29
+
30
+ export declare function forbidden(message?: string, headers?: object): Response;
31
+
28
32
  /**
29
33
  * Utility functions
30
34
  */
package/src/index.js CHANGED
@@ -15,6 +15,7 @@ import { Response } from '@adobe/fetch';
15
15
  import LegacyApiKeyHandler from './auth/handlers/legacy-api-key.js';
16
16
  import AdobeImsHandler from './auth/handlers/ims.js';
17
17
  import ScopedApiKeyHandler from './auth/handlers/scoped-api-key.js';
18
+ import JwtHandler from './auth/handlers/jwt.js';
18
19
 
19
20
  const HEADER_CONTENT_TYPE = 'content-type';
20
21
  const HEADER_ERROR = 'x-error';
@@ -106,4 +107,6 @@ export { authWrapper } from './auth/auth-wrapper.js';
106
107
  export { enrichPathInfo } from './enrich-path-info-wrapper.js';
107
108
  export { hashWithSHA256 } from './auth/generate-hash.js';
108
109
 
109
- export { AdobeImsHandler, ScopedApiKeyHandler, LegacyApiKeyHandler };
110
+ export {
111
+ AdobeImsHandler, ScopedApiKeyHandler, LegacyApiKeyHandler, JwtHandler,
112
+ };