@adobe/spacecat-shared-http-utils 1.13.1 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/src/auth/handlers/jwt.js +2 -1
- package/src/index.d.ts +4 -0
- package/src/index.js +8 -2
- package/src/auth/handlers/cookie-auth.js +0 -88
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-http-utils-v1.14.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-http-utils-v1.13.2...@adobe/spacecat-shared-http-utils-v1.14.0) (2025-05-27)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add 405 response util ([#768](https://github.com/adobe/spacecat-shared/issues/768)) ([300ceb2](https://github.com/adobe/spacecat-shared/commit/300ceb2c979b304849a30f0e227823308d144c40))
|
|
7
|
+
|
|
8
|
+
# [@adobe/spacecat-shared-http-utils-v1.13.2](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-http-utils-v1.13.1...@adobe/spacecat-shared-http-utils-v1.13.2) (2025-05-21)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* merge cookie auth logic with jwt handler ([#751](https://github.com/adobe/spacecat-shared/issues/751)) ([407273b](https://github.com/adobe/spacecat-shared/commit/407273b4e2a2dafe4839ee3e22969f1f648878e8))
|
|
14
|
+
|
|
1
15
|
# [@adobe/spacecat-shared-http-utils-v1.13.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-http-utils-v1.13.0...@adobe/spacecat-shared-http-utils-v1.13.1) (2025-05-20)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
package/src/auth/handlers/jwt.js
CHANGED
|
@@ -16,6 +16,7 @@ import { importSPKI, jwtVerify } from 'jose';
|
|
|
16
16
|
import AbstractHandler from './abstract.js';
|
|
17
17
|
import AuthInfo from '../auth-info.js';
|
|
18
18
|
import { getBearerToken } from './utils/bearer.js';
|
|
19
|
+
import { getCookieValue } from './utils/cookie.js';
|
|
19
20
|
|
|
20
21
|
const ALGORITHM_ES256 = 'ES256';
|
|
21
22
|
export const ISSUER = 'https://spacecat.experiencecloud.live';
|
|
@@ -59,7 +60,7 @@ export default class JwtHandler extends AbstractHandler {
|
|
|
59
60
|
try {
|
|
60
61
|
await this.#setup(context);
|
|
61
62
|
|
|
62
|
-
const token = getBearerToken(context);
|
|
63
|
+
const token = getBearerToken(context) ?? getCookieValue(context, 'sessionToken');
|
|
63
64
|
|
|
64
65
|
if (!hasText(token)) {
|
|
65
66
|
this.log('No bearer token provided', 'debug');
|
package/src/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { Response } from '@adobe/fetch';
|
|
13
13
|
|
|
14
|
+
export declare function createResponse(body: object, status?: number, headers?: object): Response;
|
|
15
|
+
|
|
14
16
|
export declare function ok(body?: string, headers?: object): Response;
|
|
15
17
|
|
|
16
18
|
export declare function created(body: object, headers?: object): Response;
|
|
@@ -23,6 +25,8 @@ export declare function badRequest(message?: string, headers?: object): Response
|
|
|
23
25
|
|
|
24
26
|
export declare function notFound(message?: string, headers?: object): Response;
|
|
25
27
|
|
|
28
|
+
export declare function methodNotAllowed(message?: string, headers?: object): Response;
|
|
29
|
+
|
|
26
30
|
export declare function internalServerError(message?: string, headers?: object): Response;
|
|
27
31
|
|
|
28
32
|
export declare function found(location: string): Response;
|
package/src/index.js
CHANGED
|
@@ -16,7 +16,6 @@ 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
18
|
import JwtHandler from './auth/handlers/jwt.js';
|
|
19
|
-
import CookieAuthHandler from './auth/handlers/cookie-auth.js';
|
|
20
19
|
|
|
21
20
|
const HEADER_CONTENT_TYPE = 'content-type';
|
|
22
21
|
const HEADER_ERROR = 'x-error';
|
|
@@ -101,6 +100,13 @@ export function notFound(message = 'not found', headers = {}) {
|
|
|
101
100
|
});
|
|
102
101
|
}
|
|
103
102
|
|
|
103
|
+
export function methodNotAllowed(message = 'method not allowed', headers = {}) {
|
|
104
|
+
return createResponse({ message }, 405, {
|
|
105
|
+
[HEADER_ERROR]: message,
|
|
106
|
+
...headers,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
104
110
|
export function internalServerError(message = 'internal server error', headers = {}) {
|
|
105
111
|
return createResponse({ message }, 500, {
|
|
106
112
|
[HEADER_ERROR]: message,
|
|
@@ -113,5 +119,5 @@ export { enrichPathInfo } from './enrich-path-info-wrapper.js';
|
|
|
113
119
|
export { hashWithSHA256 } from './auth/generate-hash.js';
|
|
114
120
|
|
|
115
121
|
export {
|
|
116
|
-
AdobeImsHandler,
|
|
122
|
+
AdobeImsHandler, ScopedApiKeyHandler, LegacyApiKeyHandler, JwtHandler,
|
|
117
123
|
};
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { hasText } from '@adobe/spacecat-shared-utils';
|
|
14
|
-
import { importSPKI, jwtVerify } from 'jose';
|
|
15
|
-
|
|
16
|
-
import AbstractHandler from './abstract.js';
|
|
17
|
-
import AuthInfo from '../auth-info.js';
|
|
18
|
-
import { getCookieValue } from './utils/cookie.js';
|
|
19
|
-
|
|
20
|
-
const ALGORITHM_ES256 = 'ES256';
|
|
21
|
-
export const ISSUER = 'https://spacecat.experiencecloud.live';
|
|
22
|
-
|
|
23
|
-
export default class CookieAuthHandler extends AbstractHandler {
|
|
24
|
-
constructor(log) {
|
|
25
|
-
super('cookieAuth', log);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async #setup(context) {
|
|
29
|
-
const authPublicKeyB64 = context.env?.AUTH_PUBLIC_KEY_B64;
|
|
30
|
-
|
|
31
|
-
if (!hasText(authPublicKeyB64)) {
|
|
32
|
-
throw new Error('No public key provided');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const authPublicKey = Buffer.from(authPublicKeyB64, 'base64').toString('utf-8');
|
|
36
|
-
|
|
37
|
-
this.authPublicKey = await importSPKI(authPublicKey, ALGORITHM_ES256);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async #validateToken(token) {
|
|
41
|
-
const verifiedToken = await jwtVerify(
|
|
42
|
-
token,
|
|
43
|
-
this.authPublicKey,
|
|
44
|
-
{
|
|
45
|
-
algorithms: [ALGORITHM_ES256], // force expected algorithm
|
|
46
|
-
clockTolerance: 5, // number of seconds to tolerate when checking the nbf and exp claims
|
|
47
|
-
complete: false, // only return the payload and not headers etc.
|
|
48
|
-
ignoreExpiration: false, // validate expiration
|
|
49
|
-
issuer: ISSUER, // validate issuer
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
verifiedToken.payload.tenants = verifiedToken.payload.tenants || [];
|
|
54
|
-
|
|
55
|
-
return verifiedToken.payload;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async checkAuth(request, context) {
|
|
59
|
-
try {
|
|
60
|
-
await this.#setup(context);
|
|
61
|
-
|
|
62
|
-
const sessionToken = getCookieValue(context, 'sessionToken');
|
|
63
|
-
|
|
64
|
-
if (!hasText(sessionToken)) {
|
|
65
|
-
this.log('No session token provided', 'debug');
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const payload = await this.#validateToken(sessionToken);
|
|
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
|
-
|
|
77
|
-
return new AuthInfo()
|
|
78
|
-
.withType(this.name)
|
|
79
|
-
.withAuthenticated(true)
|
|
80
|
-
.withProfile(payload)
|
|
81
|
-
.withScopes(scopes);
|
|
82
|
-
} catch (e) {
|
|
83
|
-
this.log(`Failed to validate token: ${e.message}`, 'error');
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
}
|