@adobe/aio-commerce-lib-auth 0.1.0 → 0.2.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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +16 -0
- package/README.md +74 -13
- package/dist/cjs/index.cjs +179 -86
- package/dist/cjs/index.d.cts +79 -30
- package/dist/es/index.d.ts +79 -30
- package/dist/es/index.js +176 -86
- package/package.json +5 -2
- package/source/index.ts +23 -2
- package/source/lib/ims-auth/provider.ts +160 -0
- package/source/lib/ims-auth/schema.ts +87 -0
- package/source/lib/integration-auth/provider.ts +145 -0
- package/source/lib/integration-auth/schema.ts +87 -0
- package/test/ims-auth.test.ts +119 -41
- package/test/integration-auth.test.ts +97 -34
- package/source/lib/ims-auth.ts +0 -95
- package/source/lib/integration-auth.ts +0 -95
- package/source/lib/params.ts +0 -34
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
|
|
2
|
-
> @adobe/aio-commerce-lib-auth@0.
|
|
2
|
+
> @adobe/aio-commerce-lib-auth@0.2.0 build /home/runner/work/aio-commerce-sdk/aio-commerce-sdk/packages/aio-commerce-lib-auth
|
|
3
3
|
> tsdown
|
|
4
4
|
|
|
5
|
-
[34mℹ[39m tsdown [2mv0.12.9[22m powered by rolldown [2mv1.0.0-beta.
|
|
5
|
+
[34mℹ[39m tsdown [2mv0.12.9[22m powered by rolldown [2mv1.0.0-beta.24[22m
|
|
6
6
|
[34mℹ[39m Using tsdown config: [4m/home/runner/work/aio-commerce-sdk/aio-commerce-sdk/packages/aio-commerce-lib-auth/tsdown.config.ts[24m
|
|
7
7
|
[34mℹ[39m entry: [34msource/index.ts[39m
|
|
8
8
|
[34mℹ[39m target: [34mnode22.0.0[39m
|
|
9
9
|
[34mℹ[39m tsconfig: [34mtsconfig.json[39m
|
|
10
10
|
[34mℹ[39m Build start
|
|
11
|
-
[34mℹ[39m [33m[CJS][39m [2mdist/cjs/[22m[1mindex.cjs[22m [
|
|
12
|
-
[34mℹ[39m [33m[CJS][39m 1 files, total:
|
|
13
|
-
[34mℹ[39m [33m[CJS][39m [2mdist/[22m[32m[1mindex.d.cts[22m[39m [
|
|
14
|
-
[34mℹ[39m [33m[CJS][39m 1 files, total:
|
|
15
|
-
[34mℹ[39m [34m[ESM][39m [2mdist/es/[22m[1mindex.js[22m [
|
|
16
|
-
[34mℹ[39m [34m[ESM][39m [2mdist/es/[22m[32m[1mindex.d.ts[22m[39m [
|
|
17
|
-
[34mℹ[39m [34m[ESM][39m 2 files, total:
|
|
18
|
-
[32m✔[39m Build complete in [
|
|
11
|
+
[34mℹ[39m [33m[CJS][39m [2mdist/cjs/[22m[1mindex.cjs[22m [2m10.48 kB[22m [2m│ gzip: 2.73 kB[22m
|
|
12
|
+
[34mℹ[39m [33m[CJS][39m 1 files, total: 10.48 kB
|
|
13
|
+
[34mℹ[39m [33m[CJS][39m [2mdist/[22m[32m[1mindex.d.cts[22m[39m [2m7.68 kB[22m [2m│ gzip: 1.41 kB[22m
|
|
14
|
+
[34mℹ[39m [33m[CJS][39m 1 files, total: 7.68 kB
|
|
15
|
+
[34mℹ[39m [34m[ESM][39m [2mdist/es/[22m[1mindex.js[22m [2m8.55 kB[22m [2m│ gzip: 2.28 kB[22m
|
|
16
|
+
[34mℹ[39m [34m[ESM][39m [2mdist/es/[22m[32m[1mindex.d.ts[22m[39m [2m7.63 kB[22m [2m│ gzip: 1.41 kB[22m
|
|
17
|
+
[34mℹ[39m [34m[ESM][39m 2 files, total: 16.18 kB
|
|
18
|
+
[32m✔[39m Build complete in [32m2646ms[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @adobe/aio-commerce-lib-auth
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#18](https://github.com/adobe/aio-commerce-sdk/pull/18) [`aadbff1`](https://github.com/adobe/aio-commerce-sdk/commit/aadbff1acd08120f9d5cb8db4e3c849f552d8c79) Thanks [@jnatherley](https://github.com/jnatherley)! - Introduces the `aio-commerce-lib-core` package, which contains core utilities for the AIO Commerce SDK. It includes:
|
|
8
|
+
- A `Result` type based on Rust's `Result` type, to do better error handling.
|
|
9
|
+
- A set of validation utilities, including pretty printing of validation errors, and custom validation error types.
|
|
10
|
+
- Refactor aio-commerce-lib-auth to use aio-commerce-lib-core
|
|
11
|
+
|
|
12
|
+
Implements validation for the `aio-commerce-lib-auth` operations via `valibot`.
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [[`aadbff1`](https://github.com/adobe/aio-commerce-sdk/commit/aadbff1acd08120f9d5cb8db4e3c849f552d8c79)]:
|
|
17
|
+
- @adobe/aio-commerce-lib-core@0.2.0
|
|
18
|
+
|
|
3
19
|
## 0.1.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -11,15 +11,29 @@ This library provides a unified interface for authentication in Adobe Commerce A
|
|
|
11
11
|
|
|
12
12
|
The library supports two main authentication providers:
|
|
13
13
|
|
|
14
|
-
- **IMS Provider**: For authenticating users or services via Adobe Identity Management System (IMS) using OAuth2
|
|
15
|
-
-
|
|
14
|
+
- **IMS Provider**: For authenticating users or services via Adobe Identity Management System (IMS) using OAuth2.
|
|
15
|
+
- Required Params
|
|
16
|
+
- AIO_COMMERCE_IMS_CLIENT_ID: string
|
|
17
|
+
- AIO_COMMERCE_IMS_CLIENT_SECRETS: string
|
|
18
|
+
- AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_ID: string
|
|
19
|
+
- AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_EMAIL: string
|
|
20
|
+
- AIO_COMMERCE_IMS_IMS_ORG_ID: string
|
|
21
|
+
- AIO_COMMERCE_IMS_ENV: string e.g `'prod'` or `'stage'`
|
|
22
|
+
- AIO_COMMERCE_IMS_SCOPES: string e.g `'["value1", "value2"]'`
|
|
23
|
+
- AIO_COMMERCE_IMS_CTX: string
|
|
24
|
+
- **Integrations Provider**: For authenticating with Adobe Commerce integrations using OAuth 1.0a.
|
|
25
|
+
- Required params
|
|
26
|
+
- AIO_COMMERCE_INTEGRATIONS_CONSUMER_KEY: string
|
|
27
|
+
- AIO_COMMERCE_INTEGRATIONS_CONSUMER_SECRET: string
|
|
28
|
+
- AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN: string
|
|
29
|
+
- AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN_SECRET: string
|
|
16
30
|
|
|
17
31
|
These providers abstract the complexity of authentication, making it easy to obtain and use access tokens in your App Builder applications.
|
|
18
32
|
|
|
19
33
|
## Installation
|
|
20
34
|
|
|
21
35
|
```shell
|
|
22
|
-
|
|
36
|
+
npm install @adobe/aio-commerce-lib-auth
|
|
23
37
|
```
|
|
24
38
|
|
|
25
39
|
## Usage
|
|
@@ -31,13 +45,36 @@ In your App Builder application, you can use the library to authenticate users o
|
|
|
31
45
|
In the runtime action you can generate an access token using the IMS Provider:
|
|
32
46
|
|
|
33
47
|
```typescript
|
|
34
|
-
import {
|
|
48
|
+
import { tryGetImsAuthProvider } from "@adobe/aio-commerce-lib-auth";
|
|
49
|
+
import { isErr, unwrap } from "@adobe/aio-commerce-lib-core";
|
|
35
50
|
|
|
36
51
|
export const main = async function (params: Record<string, unknown>) {
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
52
|
+
const result = tryGetImsAuthProvider(params); // Validate parameters and get the integration auth provider
|
|
53
|
+
|
|
54
|
+
if (isErr(result)) {
|
|
55
|
+
const { error } = result;
|
|
56
|
+
return {
|
|
57
|
+
statusCode: 400,
|
|
58
|
+
body: {
|
|
59
|
+
error: `Unable to get IMS Auth Provider ${error.message}`,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const imsAuthProvider = unwrap(result);
|
|
65
|
+
const headersResult = imsAuthProvider.getHeaders();
|
|
66
|
+
|
|
67
|
+
if (isErr(headersResult)) {
|
|
68
|
+
const { error } = result;
|
|
69
|
+
return {
|
|
70
|
+
statusCode: 400,
|
|
71
|
+
body: {
|
|
72
|
+
error: `Unable to get auth headers for IMS Auth Provider ${error.message}`,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// business logic e.g requesting orders
|
|
41
78
|
return { statusCode: 200 };
|
|
42
79
|
};
|
|
43
80
|
```
|
|
@@ -47,20 +84,44 @@ export const main = async function (params: Record<string, unknown>) {
|
|
|
47
84
|
In the runtime action you can generate an access token using the Integrations Provider:
|
|
48
85
|
|
|
49
86
|
```typescript
|
|
50
|
-
import {
|
|
87
|
+
import { tryGetIntegrationAuthProvider } from "@adobe/aio-commerce-lib-auth";
|
|
88
|
+
import { isErr, unwrapErr, unwrap } from "@adobe/aio-commerce-lib-core";
|
|
51
89
|
|
|
52
90
|
export const main = async function (params: Record<string, unknown>) {
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
91
|
+
const result = tryGetIntegrationAuthProvider(params); // Validate parameters and get the integration auth provider
|
|
92
|
+
|
|
93
|
+
if (isErr(result)) {
|
|
94
|
+
const { error } = result;
|
|
95
|
+
return {
|
|
96
|
+
statusCode: 400,
|
|
97
|
+
body: {
|
|
98
|
+
error: `Unable to get Integration Auth Provider ${error.message}`,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const integrationsAuth = unwrap(result);
|
|
104
|
+
const headersResult = integrationsAuth.getHeaders(
|
|
56
105
|
"GET",
|
|
57
106
|
"http://localhost/rest/V1/orders",
|
|
58
107
|
);
|
|
59
108
|
|
|
109
|
+
if (isErr(headersResult)) {
|
|
110
|
+
const { error } = result;
|
|
111
|
+
return {
|
|
112
|
+
statusCode: 400,
|
|
113
|
+
body: {
|
|
114
|
+
error: `Unable to get auth headers for Integration Auth Provider ${error.message}`,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// business logic e.g requesting orders
|
|
120
|
+
|
|
60
121
|
return { statusCode: 200 };
|
|
61
122
|
};
|
|
62
123
|
```
|
|
63
124
|
|
|
64
125
|
## Contributing
|
|
65
126
|
|
|
66
|
-
This package is part of the Adobe Commerce SDK monorepo. See the [Contributing Guide](
|
|
127
|
+
This package is part of the Adobe Commerce SDK monorepo. See the [Contributing Guide](https://github.com/adobe/aio-commerce-sdk/blob/main/.github/CONTRIBUTING.md) and [Development Guide](https://github.com/adobe/aio-commerce-sdk/blob/main/.github/DEVELOPMENT.md) for development setup and guidelines.
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -21,115 +21,208 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
+
const __adobe_aio_commerce_lib_core_result = __toESM(require("@adobe/aio-commerce-lib-core/result"));
|
|
24
25
|
const __adobe_aio_lib_ims = __toESM(require("@adobe/aio-lib-ims"));
|
|
26
|
+
const valibot = __toESM(require("valibot"));
|
|
25
27
|
const node_crypto = __toESM(require("node:crypto"));
|
|
26
28
|
const oauth_1_0a = __toESM(require("oauth-1.0a"));
|
|
27
29
|
|
|
28
|
-
//#region source/lib/
|
|
30
|
+
//#region source/lib/ims-auth/schema.ts
|
|
31
|
+
const imsAuthParameter = (name) => (0, valibot.pipe)((0, valibot.string)(`Expected a string value for the IMS auth parameter ${name}`), (0, valibot.nonEmpty)(`Expected a non-empty string value for the IMS auth parameter ${name}`));
|
|
32
|
+
const jsonStringArray = (name) => {
|
|
33
|
+
const jsonStringArraySchema = (0, valibot.message)((0, valibot.pipe)((0, valibot.string)(`Expected a string value for the IMS auth parameter ${name}`), (0, valibot.nonEmpty)(`Expected a non-empty string value for the IMS auth parameter ${name}`), (0, valibot.parseJson)()), `An error occurred while parsing the JSON string array parameter ${name}`);
|
|
34
|
+
return (0, valibot.pipe)(jsonStringArraySchema, (0, valibot.array)((0, valibot.string)(), `Expected a stringified JSON array value for the IMS auth parameter ${name}`));
|
|
35
|
+
};
|
|
36
|
+
/** The environments accepted by the IMS auth service. */
|
|
37
|
+
const IMS_AUTH_ENV = {
|
|
38
|
+
PROD: "prod",
|
|
39
|
+
STAGE: "stage"
|
|
40
|
+
};
|
|
41
|
+
const ImsAuthEnvSchema = (0, valibot.enum)(IMS_AUTH_ENV);
|
|
42
|
+
/** Defines the schema to validate the necessary parameters for the IMS auth service. */
|
|
43
|
+
const ImsAuthParamsSchema = (0, valibot.object)({
|
|
44
|
+
AIO_COMMERCE_IMS_CLIENT_ID: imsAuthParameter("AIO_COMMERCE_IMS_CLIENT_ID"),
|
|
45
|
+
AIO_COMMERCE_IMS_CLIENT_SECRETS: jsonStringArray("AIO_COMMERCE_IMS_CLIENT_SECRETS"),
|
|
46
|
+
AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_ID: imsAuthParameter("AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_ID"),
|
|
47
|
+
AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_EMAIL: imsAuthParameter("AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_EMAIL"),
|
|
48
|
+
AIO_COMMERCE_IMS_IMS_ORG_ID: imsAuthParameter("AIO_COMMERCE_IMS_IMS_ORG_ID"),
|
|
49
|
+
AIO_COMMERCE_IMS_ENV: (0, valibot.pipe)((0, valibot.optional)(ImsAuthEnvSchema, IMS_AUTH_ENV.PROD)),
|
|
50
|
+
AIO_COMMERCE_IMS_CTX: (0, valibot.pipe)((0, valibot.optional)((0, valibot.string)(), "aio-commerce-sdk-creds")),
|
|
51
|
+
AIO_COMMERCE_IMS_SCOPES: jsonStringArray("AIO_COMMERCE_IMS_SCOPES")
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region source/lib/ims-auth/provider.ts
|
|
56
|
+
function snakeCaseImsAuthConfig(config) {
|
|
57
|
+
return {
|
|
58
|
+
...config,
|
|
59
|
+
client_id: config.clientId,
|
|
60
|
+
client_secrets: config.clientSecrets,
|
|
61
|
+
technical_account_id: config.technicalAccountId,
|
|
62
|
+
technical_account_email: config.technicalAccountEmail,
|
|
63
|
+
ims_org_id: config.imsOrgId
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function makeImsAuthValidationError(message, issues) {
|
|
67
|
+
return {
|
|
68
|
+
_tag: "ImsAuthValidationError",
|
|
69
|
+
message,
|
|
70
|
+
issues
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function makeImsAuthError(message, error) {
|
|
74
|
+
return {
|
|
75
|
+
_tag: "ImsAuthError",
|
|
76
|
+
message,
|
|
77
|
+
error
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function fromParams$1(params) {
|
|
81
|
+
return {
|
|
82
|
+
clientId: params.AIO_COMMERCE_IMS_CLIENT_ID,
|
|
83
|
+
clientSecrets: params.AIO_COMMERCE_IMS_CLIENT_SECRETS,
|
|
84
|
+
technicalAccountId: params.AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_ID,
|
|
85
|
+
technicalAccountEmail: params.AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
86
|
+
imsOrgId: params.AIO_COMMERCE_IMS_IMS_ORG_ID,
|
|
87
|
+
scopes: params.AIO_COMMERCE_IMS_SCOPES,
|
|
88
|
+
environment: params.AIO_COMMERCE_IMS_ENV,
|
|
89
|
+
context: params.AIO_COMMERCE_IMS_CTX
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function tryGetAccessToken(contextName) {
|
|
93
|
+
try {
|
|
94
|
+
const accessToken = await (0, __adobe_aio_lib_ims.getToken)(contextName, {});
|
|
95
|
+
return (0, __adobe_aio_commerce_lib_core_result.ok)(accessToken);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return (0, __adobe_aio_commerce_lib_core_result.err)(makeImsAuthError("Failed to retrieve IMS access token", error));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
29
100
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* @
|
|
33
|
-
* @param value of the parameter.
|
|
101
|
+
* Creates an {@link ImsAuthProvider} based on the provided configuration.
|
|
102
|
+
* @param config The configuration for the IMS Auth Provider.
|
|
103
|
+
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
34
104
|
*/
|
|
35
|
-
function
|
|
36
|
-
const
|
|
37
|
-
|
|
105
|
+
function getImsAuthProvider(config) {
|
|
106
|
+
const getAccessToken = async () => {
|
|
107
|
+
const snakeCasedConfig = snakeCaseImsAuthConfig(config);
|
|
108
|
+
await __adobe_aio_lib_ims.context.set(config.context, snakeCasedConfig);
|
|
109
|
+
return tryGetAccessToken(config.context);
|
|
110
|
+
};
|
|
111
|
+
const getHeaders = async () => {
|
|
112
|
+
const result = await getAccessToken();
|
|
113
|
+
return (0, __adobe_aio_commerce_lib_core_result.map)(result, (accessToken) => ({
|
|
114
|
+
Authorization: `Bearer ${accessToken}`,
|
|
115
|
+
"x-api-key": config.clientId
|
|
116
|
+
}));
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
getAccessToken,
|
|
120
|
+
getHeaders
|
|
121
|
+
};
|
|
38
122
|
}
|
|
39
123
|
/**
|
|
40
|
-
*
|
|
41
|
-
* @param params
|
|
42
|
-
* @
|
|
124
|
+
* Tries to create an {@link ImsAuthProvider} based on the provided parameters.
|
|
125
|
+
* @param params The parameters required to create the IMS Auth Provider.
|
|
126
|
+
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
43
127
|
*/
|
|
44
|
-
function
|
|
45
|
-
|
|
128
|
+
function tryGetImsAuthProvider(params) {
|
|
129
|
+
const validation = (0, valibot.safeParse)(ImsAuthParamsSchema, params);
|
|
130
|
+
if (!validation.success) return (0, __adobe_aio_commerce_lib_core_result.err)(makeImsAuthValidationError("Failed to validate the provided IMS parameters", validation.issues));
|
|
131
|
+
return (0, __adobe_aio_commerce_lib_core_result.ok)(getImsAuthProvider(fromParams$1(validation.output)));
|
|
46
132
|
}
|
|
47
133
|
|
|
48
134
|
//#endregion
|
|
49
|
-
//#region source/lib/
|
|
135
|
+
//#region source/lib/integration-auth/schema.ts
|
|
50
136
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
137
|
+
* The HTTP methods supported by Commerce.
|
|
138
|
+
* This is used to determine which headers to include in the signing of the authorization header.
|
|
53
139
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function resolveImsConfig(params) {
|
|
72
|
-
if (allNonEmpty(params, [
|
|
73
|
-
"AIO_COMMERCE_IMS_CLIENT_ID",
|
|
74
|
-
"AIO_COMMERCE_IMS_CLIENT_SECRETS",
|
|
75
|
-
"AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_ID",
|
|
76
|
-
"AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_EMAIL",
|
|
77
|
-
"AIO_COMMERCE_IMS_IMS_ORG_ID",
|
|
78
|
-
"AIO_COMMERCE_IMS_SCOPES"
|
|
79
|
-
])) return {
|
|
80
|
-
client_id: params.AIO_COMMERCE_IMS_CLIENT_ID,
|
|
81
|
-
client_secrets: JSON.parse(params.AIO_COMMERCE_IMS_CLIENT_SECRETS ?? "[]"),
|
|
82
|
-
technical_account_id: params.AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_ID,
|
|
83
|
-
technical_account_email: params.AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
84
|
-
ims_org_id: params.AIO_COMMERCE_IMS_IMS_ORG_ID,
|
|
85
|
-
scopes: JSON.parse(params.AIO_COMMERCE_IMS_SCOPES ?? "[]"),
|
|
86
|
-
environment: params.AIO_COMMERCE_IMS_ENV ?? "prod"
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
//#endregion
|
|
91
|
-
//#region source/lib/integration-auth.ts
|
|
140
|
+
const AllowedHttpMethod = [
|
|
141
|
+
"GET",
|
|
142
|
+
"POST",
|
|
143
|
+
"PUT",
|
|
144
|
+
"PATCH",
|
|
145
|
+
"DELETE"
|
|
146
|
+
];
|
|
147
|
+
const HttpMethodSchema = (0, valibot.picklist)(AllowedHttpMethod);
|
|
148
|
+
const integrationAuthParameter = (name) => (0, valibot.pipe)((0, valibot.string)(`Expected a string value for the Commerce Integration parameter ${name}`), (0, valibot.nonEmpty)(`Expected a non-empty string value for the Commerce Integration parameter ${name}`));
|
|
149
|
+
const BaseUrlSchema = (0, valibot.pipe)((0, valibot.string)("Expected a string for the Adobe Commerce endpoint"), (0, valibot.nonEmpty)("Expected a non-empty string for the Adobe Commerce endpoint"), (0, valibot.url)("Expected a valid url for the Adobe Commerce endpoint"));
|
|
150
|
+
const UrlSchema = (0, valibot.pipe)((0, valibot.union)([BaseUrlSchema, (0, valibot.instance)(URL)]), (0, valibot.transform)((url) => {
|
|
151
|
+
if (url instanceof URL) return url.toString();
|
|
152
|
+
return url;
|
|
153
|
+
}));
|
|
92
154
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
155
|
+
* The schema for the Commerce Integration parameters.
|
|
156
|
+
* This is used to validate the parameters passed to the Commerce Integration provider.
|
|
95
157
|
*/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return { getHeaders(method, url) {
|
|
112
|
-
return oauth.toHeader(oauth.authorize({
|
|
113
|
-
url,
|
|
114
|
-
method
|
|
115
|
-
}, oauthToken));
|
|
116
|
-
} };
|
|
117
|
-
}
|
|
158
|
+
const IntegrationAuthParamsSchema = (0, valibot.nonOptional)((0, valibot.object)({
|
|
159
|
+
AIO_COMMERCE_INTEGRATIONS_CONSUMER_KEY: integrationAuthParameter("AIO_COMMERCE_INTEGRATIONS_CONSUMER_KEY"),
|
|
160
|
+
AIO_COMMERCE_INTEGRATIONS_CONSUMER_SECRET: integrationAuthParameter("AIO_COMMERCE_INTEGRATIONS_CONSUMER_SECRET"),
|
|
161
|
+
AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN: integrationAuthParameter("AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN"),
|
|
162
|
+
AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN_SECRET: integrationAuthParameter("AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN_SECRET")
|
|
163
|
+
}));
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region source/lib/integration-auth/provider.ts
|
|
167
|
+
function makeIntegrationAuthValidationError(message, issues) {
|
|
168
|
+
return {
|
|
169
|
+
_tag: "IntegrationAuthValidationError",
|
|
170
|
+
message,
|
|
171
|
+
issues
|
|
172
|
+
};
|
|
118
173
|
}
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
"AIO_COMMERCE_INTEGRATIONS_CONSUMER_KEY",
|
|
122
|
-
"AIO_COMMERCE_INTEGRATIONS_CONSUMER_SECRET",
|
|
123
|
-
"AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN",
|
|
124
|
-
"AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN_SECRET"
|
|
125
|
-
])) return {
|
|
174
|
+
function fromParams(params) {
|
|
175
|
+
return {
|
|
126
176
|
consumerKey: params.AIO_COMMERCE_INTEGRATIONS_CONSUMER_KEY,
|
|
127
177
|
consumerSecret: params.AIO_COMMERCE_INTEGRATIONS_CONSUMER_SECRET,
|
|
128
178
|
accessToken: params.AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN,
|
|
129
179
|
accessTokenSecret: params.AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN_SECRET
|
|
130
180
|
};
|
|
131
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Creates an {@link IntegrationAuthProvider} based on the provided configuration.
|
|
184
|
+
* @param config The configuration for the integration.
|
|
185
|
+
* @returns An {@link IntegrationAuthProvider} instance that can be used to get auth headers.
|
|
186
|
+
*/
|
|
187
|
+
function getIntegrationAuthProvider(config) {
|
|
188
|
+
const oauth = new oauth_1_0a.default({
|
|
189
|
+
consumer: {
|
|
190
|
+
key: config.consumerKey,
|
|
191
|
+
secret: config.consumerSecret
|
|
192
|
+
},
|
|
193
|
+
signature_method: "HMAC-SHA256",
|
|
194
|
+
hash_function: (baseString, key) => node_crypto.default.createHmac("sha256", key).update(baseString).digest("base64")
|
|
195
|
+
});
|
|
196
|
+
const oauthToken = {
|
|
197
|
+
key: config.accessToken,
|
|
198
|
+
secret: config.accessTokenSecret
|
|
199
|
+
};
|
|
200
|
+
const getHeaders = (method, url) => {
|
|
201
|
+
const uriValidation = (0, valibot.safeParse)(UrlSchema, url);
|
|
202
|
+
if (!uriValidation.success) return (0, __adobe_aio_commerce_lib_core_result.err)(makeIntegrationAuthValidationError("Failed to validate the provided Adobe Commerce URL", uriValidation.issues));
|
|
203
|
+
const finalUrl = uriValidation.output;
|
|
204
|
+
const headers = oauth.toHeader(oauth.authorize({
|
|
205
|
+
url: finalUrl,
|
|
206
|
+
method
|
|
207
|
+
}, oauthToken));
|
|
208
|
+
return (0, __adobe_aio_commerce_lib_core_result.ok)(headers);
|
|
209
|
+
};
|
|
210
|
+
return { getHeaders };
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Tries to create an {@link IntegrationAuthProvider} based on the provided parameters.
|
|
214
|
+
* @param params The parameters required for integration authentication.
|
|
215
|
+
* @returns An {@link IntegrationAuthProvider} instance that can be used to get auth headers.
|
|
216
|
+
*/
|
|
217
|
+
function tryGetIntegrationAuthProvider(params) {
|
|
218
|
+
const validation = (0, valibot.safeParse)(IntegrationAuthParamsSchema, params);
|
|
219
|
+
if (!validation.success) return (0, __adobe_aio_commerce_lib_core_result.err)(makeIntegrationAuthValidationError("Failed to validate the provided integration parameters", validation.issues));
|
|
220
|
+
return (0, __adobe_aio_commerce_lib_core_result.ok)(getIntegrationAuthProvider(fromParams(validation.output)));
|
|
221
|
+
}
|
|
132
222
|
|
|
133
223
|
//#endregion
|
|
224
|
+
exports.IMS_AUTH_ENV = IMS_AUTH_ENV;
|
|
134
225
|
exports.getImsAuthProvider = getImsAuthProvider;
|
|
135
|
-
exports.getIntegrationAuthProvider = getIntegrationAuthProvider;
|
|
226
|
+
exports.getIntegrationAuthProvider = getIntegrationAuthProvider;
|
|
227
|
+
exports.tryGetImsAuthProvider = tryGetImsAuthProvider;
|
|
228
|
+
exports.tryGetIntegrationAuthProvider = tryGetIntegrationAuthProvider;
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -1,39 +1,88 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ErrorType, Result } from "@adobe/aio-commerce-lib-core/result";
|
|
2
|
+
import { ValidationErrorType } from "@adobe/aio-commerce-lib-core/validation";
|
|
3
|
+
import * as valibot25 from "valibot";
|
|
4
|
+
import { InferInput, InferIssue, InferOutput } from "valibot";
|
|
5
|
+
import * as url5 from "url";
|
|
2
6
|
|
|
3
|
-
//#region source/lib/ims-auth.d.ts
|
|
4
|
-
declare const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
//#region source/lib/ims-auth/schema.d.ts
|
|
8
|
+
declare const IMS_AUTH_ENV: {
|
|
9
|
+
readonly PROD: "prod";
|
|
10
|
+
readonly STAGE: "stage";
|
|
11
|
+
};
|
|
12
|
+
declare const ImsAuthEnvSchema: valibot25.EnumSchema<{
|
|
13
|
+
readonly PROD: "prod";
|
|
14
|
+
readonly STAGE: "stage";
|
|
15
|
+
}, undefined>;
|
|
16
|
+
declare const ImsAuthParamsSchema: valibot25.ObjectSchema<{
|
|
17
|
+
readonly AIO_COMMERCE_IMS_CLIENT_ID: valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
18
|
+
readonly AIO_COMMERCE_IMS_CLIENT_SECRETS: valibot25.SchemaWithPipe<readonly [valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>, valibot25.ParseJsonAction<string, undefined, undefined>]>, valibot25.ArraySchema<valibot25.StringSchema<undefined>, `Expected a stringified JSON array value for the IMS auth parameter ${string}`>]>;
|
|
19
|
+
readonly AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_ID: valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
20
|
+
readonly AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_EMAIL: valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
21
|
+
readonly AIO_COMMERCE_IMS_IMS_ORG_ID: valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
22
|
+
readonly AIO_COMMERCE_IMS_ENV: valibot25.SchemaWithPipe<readonly [valibot25.OptionalSchema<valibot25.EnumSchema<{
|
|
23
|
+
readonly PROD: "prod";
|
|
24
|
+
readonly STAGE: "stage";
|
|
25
|
+
}, undefined>, "prod">]>;
|
|
26
|
+
readonly AIO_COMMERCE_IMS_CTX: valibot25.SchemaWithPipe<readonly [valibot25.OptionalSchema<valibot25.StringSchema<undefined>, "aio-commerce-sdk-creds">]>;
|
|
27
|
+
readonly AIO_COMMERCE_IMS_SCOPES: valibot25.SchemaWithPipe<readonly [valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>, valibot25.ParseJsonAction<string, undefined, undefined>]>, valibot25.ArraySchema<valibot25.StringSchema<undefined>, `Expected a stringified JSON array value for the IMS auth parameter ${string}`>]>;
|
|
28
|
+
}, undefined>;
|
|
29
|
+
type ImsAuthParams = InferOutput<typeof ImsAuthParamsSchema>;
|
|
30
|
+
type ImsAuthEnv = InferOutput<typeof ImsAuthEnvSchema>;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region source/lib/ims-auth/provider.d.ts
|
|
10
33
|
type ImsAccessToken = string;
|
|
34
|
+
type ImsAuthHeader = "Authorization" | "x-api-key";
|
|
35
|
+
type ImsAuthHeaders = Record<ImsAuthHeader, string>;
|
|
36
|
+
type ImsAuthValidationError = ValidationErrorType<"ImsAuthValidationError", InferIssue<typeof ImsAuthParamsSchema>[]>;
|
|
37
|
+
type ImsAuthError<TError = unknown> = ErrorType<"ImsAuthError", {
|
|
38
|
+
message: string;
|
|
39
|
+
error: TError;
|
|
40
|
+
}>;
|
|
41
|
+
interface ImsAuthConfig {
|
|
42
|
+
clientId: string;
|
|
43
|
+
clientSecrets: string[];
|
|
44
|
+
technicalAccountId: string;
|
|
45
|
+
technicalAccountEmail: string;
|
|
46
|
+
imsOrgId: string;
|
|
47
|
+
scopes: string[];
|
|
48
|
+
environment: ImsAuthEnv;
|
|
49
|
+
context: string;
|
|
50
|
+
}
|
|
11
51
|
interface ImsAuthProvider {
|
|
12
|
-
|
|
13
|
-
|
|
52
|
+
getAccessToken: () => Promise<Result<ImsAccessToken, ImsAuthError>>;
|
|
53
|
+
getHeaders: () => Promise<Result<ImsAuthHeaders, ImsAuthError>>;
|
|
14
54
|
}
|
|
15
|
-
declare function getImsAuthProvider(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
55
|
+
declare function getImsAuthProvider(config: ImsAuthConfig): ImsAuthProvider;
|
|
56
|
+
declare function tryGetImsAuthProvider(params: InferInput<typeof ImsAuthParamsSchema>): Result<ImsAuthProvider, ImsAuthValidationError>;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region source/lib/integration-auth/schema.d.ts
|
|
59
|
+
declare const HttpMethodSchema: valibot25.PicklistSchema<readonly ["GET", "POST", "PUT", "PATCH", "DELETE"], undefined>;
|
|
60
|
+
type HttpMethodInput = InferInput<typeof HttpMethodSchema>;
|
|
61
|
+
declare const UrlSchema: valibot25.SchemaWithPipe<readonly [valibot25.UnionSchema<[valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<"Expected a string for the Adobe Commerce endpoint">, valibot25.NonEmptyAction<string, "Expected a non-empty string for the Adobe Commerce endpoint">, valibot25.UrlAction<string, "Expected a valid url for the Adobe Commerce endpoint">]>, valibot25.InstanceSchema<typeof url5.URL, undefined>], undefined>, valibot25.TransformAction<string | url5.URL, string>]>;
|
|
62
|
+
type AdobeCommerceUri = InferInput<typeof UrlSchema>;
|
|
63
|
+
declare const IntegrationAuthParamsSchema: valibot25.NonOptionalSchema<valibot25.ObjectSchema<{
|
|
64
|
+
readonly AIO_COMMERCE_INTEGRATIONS_CONSUMER_KEY: valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
65
|
+
readonly AIO_COMMERCE_INTEGRATIONS_CONSUMER_SECRET: valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
66
|
+
readonly AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN: valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
67
|
+
readonly AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN_SECRET: valibot25.SchemaWithPipe<readonly [valibot25.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot25.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
68
|
+
}, undefined>, undefined>;
|
|
69
|
+
type IntegrationAuthParams = InferInput<typeof IntegrationAuthParamsSchema>;
|
|
22
70
|
//#endregion
|
|
23
|
-
//#region source/lib/integration-auth.d.ts
|
|
24
|
-
|
|
25
|
-
declare const INTEGRATION_AUTH_HEADERS: readonly ["Authorization"];
|
|
26
|
-
declare const INTEGRATION_AUTH_PARAMS: readonly ["AIO_COMMERCE_INTEGRATIONS_CONSUMER_KEY", "AIO_COMMERCE_INTEGRATIONS_CONSUMER_SECRET", "AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN", "AIO_COMMERCE_INTEGRATIONS_ACCESS_TOKEN_SECRET"];
|
|
27
|
-
type IntegrationAuthParam = (typeof INTEGRATION_AUTH_PARAMS)[number];
|
|
28
|
-
type IntegrationAuthParams = Partial<Record<IntegrationAuthParam, string>>;
|
|
29
|
-
type IntegrationAuthHeader = (typeof INTEGRATION_AUTH_HEADERS)[number];
|
|
71
|
+
//#region source/lib/integration-auth/provider.d.ts
|
|
72
|
+
type IntegrationAuthHeader = "Authorization";
|
|
30
73
|
type IntegrationAuthHeaders = Record<IntegrationAuthHeader, string>;
|
|
31
|
-
|
|
74
|
+
interface IntegrationConfig {
|
|
75
|
+
consumerKey: string;
|
|
76
|
+
consumerSecret: string;
|
|
77
|
+
accessToken: string;
|
|
78
|
+
accessTokenSecret: string;
|
|
79
|
+
}
|
|
80
|
+
type ValidationIssues = InferIssue<typeof IntegrationAuthParamsSchema>[] | InferIssue<typeof UrlSchema>[];
|
|
81
|
+
type IntegrationAuthError = ValidationErrorType<"IntegrationAuthValidationError", ValidationIssues>;
|
|
32
82
|
interface IntegrationAuthProvider {
|
|
33
|
-
getHeaders: (method:
|
|
83
|
+
getHeaders: (method: HttpMethodInput, url: AdobeCommerceUri) => Result<IntegrationAuthHeaders, IntegrationAuthError>;
|
|
34
84
|
}
|
|
35
|
-
declare function getIntegrationAuthProvider(
|
|
36
|
-
|
|
37
|
-
} | undefined;
|
|
85
|
+
declare function getIntegrationAuthProvider(config: IntegrationConfig): IntegrationAuthProvider;
|
|
86
|
+
declare function tryGetIntegrationAuthProvider(params: IntegrationAuthParams): Result<IntegrationAuthProvider, IntegrationAuthError>;
|
|
38
87
|
//#endregion
|
|
39
|
-
export {
|
|
88
|
+
export { IMS_AUTH_ENV, ImsAuthConfig, ImsAuthEnv, ImsAuthError, ImsAuthParams, ImsAuthProvider, IntegrationAuthError, IntegrationAuthParams, IntegrationAuthProvider, IntegrationConfig, getImsAuthProvider, getIntegrationAuthProvider, tryGetImsAuthProvider, tryGetIntegrationAuthProvider };
|