@adobe/aio-commerce-lib-auth 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +1 -117
- package/dist/cjs/index.cjs +37 -230
- package/dist/cjs/index.d.cts +179 -17
- package/dist/es/index.d.ts +166 -4
- package/dist/es/index.js +31 -200
- package/package.json +20 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @adobe/aio-commerce-lib-auth
|
|
2
2
|
|
|
3
|
+
## 0.3.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`08edb37`](https://github.com/adobe/aio-commerce-sdk/commit/08edb372c6b1a97ffed26d5f84b1c189bd6bd330) Thanks [@jnatherley](https://github.com/jnatherley)! - `ImsAuthConfig.context` could be received as `undefined` by the `context.set` method, after an `assertImsAuthParams` due to us discarding the Valibot output (which was setting a default). Now, the value is manually defaulted if not set.
|
|
8
|
+
|
|
9
|
+
- [`0b37a82`](https://github.com/adobe/aio-commerce-sdk/commit/0b37a821f3a7d8c8acd1d2bb16e12b55a5ec7c71) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Fix small typo in validation message of `stringArray` schema.
|
|
10
|
+
|
|
11
|
+
## 0.3.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`4b75585`](https://github.com/adobe/aio-commerce-sdk/commit/4b75585c0d27bd472de3277be5ddaf6a977664de)]:
|
|
16
|
+
- @adobe/aio-commerce-lib-core@0.4.0
|
|
17
|
+
|
|
3
18
|
## 0.3.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -7,15 +7,6 @@ Authentication utilities for Adobe Commerce apps deployed in Adobe App Builder.
|
|
|
7
7
|
|
|
8
8
|
This library provides a unified interface for authentication in Adobe Commerce App Builder applications, supporting multiple authentication mechanisms required for different integration scenarios.
|
|
9
9
|
|
|
10
|
-
## Overview
|
|
11
|
-
|
|
12
|
-
The library supports two main authentication providers:
|
|
13
|
-
|
|
14
|
-
- **IMS Provider**: For authenticating users or services via Adobe Identity Management System (IMS) using OAuth2
|
|
15
|
-
- **Integrations Provider**: For authenticating with Adobe Commerce integrations using OAuth 1.0a
|
|
16
|
-
|
|
17
|
-
These providers abstract the complexity of authentication, making it easy to obtain and use access tokens in your App Builder applications.
|
|
18
|
-
|
|
19
10
|
## Installation
|
|
20
11
|
|
|
21
12
|
```shell
|
|
@@ -24,114 +15,7 @@ pnpm install @adobe/aio-commerce-lib-auth
|
|
|
24
15
|
|
|
25
16
|
## Usage
|
|
26
17
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
### IMS Provider
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
import {
|
|
33
|
-
assertImsAuthParams,
|
|
34
|
-
getImsAuthProvider,
|
|
35
|
-
} from "@adobe/aio-commerce-lib-auth";
|
|
36
|
-
|
|
37
|
-
import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core";
|
|
38
|
-
|
|
39
|
-
export const main = async function (params: Record<string, unknown>) {
|
|
40
|
-
try {
|
|
41
|
-
// Validate parameters and get the IMS auth provider
|
|
42
|
-
assertImsAuthParams(params);
|
|
43
|
-
const imsAuthProvider = getImsAuthProvider(params);
|
|
44
|
-
|
|
45
|
-
const token = await imsAuthProvider.getAccessToken();
|
|
46
|
-
const headers = await imsAuthProvider.getHeaders();
|
|
47
|
-
|
|
48
|
-
// Use headers in your API calls
|
|
49
|
-
// business logic e.g requesting orders
|
|
50
|
-
return { statusCode: 200 };
|
|
51
|
-
} catch (error) {
|
|
52
|
-
if (error instanceof CommerceSdkValidationError) {
|
|
53
|
-
return {
|
|
54
|
-
statusCode: 400,
|
|
55
|
-
body: {
|
|
56
|
-
error: `Invalid IMS configuration: ${error.message}`,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Integrations Provider
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
import {
|
|
69
|
-
assertIntegrationAuthParams,
|
|
70
|
-
getIntegrationAuthProvider,
|
|
71
|
-
} from "@adobe/aio-commerce-lib-auth";
|
|
72
|
-
|
|
73
|
-
import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core";
|
|
74
|
-
|
|
75
|
-
export const main = async function (params: Record<string, unknown>) {
|
|
76
|
-
try {
|
|
77
|
-
// Validate parameters and get the integration auth provider
|
|
78
|
-
assertIntegrationAuthParams(params);
|
|
79
|
-
const integrationsAuth = getIntegrationAuthProvider(params);
|
|
80
|
-
|
|
81
|
-
// Get OAuth headers for API requests
|
|
82
|
-
const headers = integrationsAuth.getHeaders(
|
|
83
|
-
"GET",
|
|
84
|
-
"http://localhost/rest/V1/orders",
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
// Use headers in your API calls
|
|
88
|
-
// business logic e.g requesting orders
|
|
89
|
-
return { statusCode: 200 };
|
|
90
|
-
} catch (error) {
|
|
91
|
-
if (error instanceof CommerceSdkValidationError) {
|
|
92
|
-
return {
|
|
93
|
-
statusCode: 400,
|
|
94
|
-
body: {
|
|
95
|
-
error: `Invalid Integration configuration: ${error.message}`,
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
throw error;
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Error Handling
|
|
105
|
-
|
|
106
|
-
The library uses validation to ensure all required parameters are provided and correctly formatted. When validation fails, a `CommerceSdkValidationError` is thrown with detailed information about what went wrong.
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core/error";
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
assertImsAuthParams({
|
|
113
|
-
clientId: "valid-id",
|
|
114
|
-
// Missing required fields
|
|
115
|
-
});
|
|
116
|
-
} catch (error) {
|
|
117
|
-
if (error instanceof CommerceSdkValidationError) {
|
|
118
|
-
console.error(error.display());
|
|
119
|
-
// Output:
|
|
120
|
-
// Invalid ImsAuthProvider configuration
|
|
121
|
-
// ├── Schema validation error at clientSecrets → Expected at least one client secret for IMS auth
|
|
122
|
-
// ├── Schema validation error at technicalAccountId → Expected a non-empty string value for the IMS auth parameter technicalAccountId
|
|
123
|
-
// └── Schema validation error at technicalAccountEmail → Expected a valid email format for technicalAccountEmail
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## Best Practices
|
|
129
|
-
|
|
130
|
-
1. **Always validate parameters** - Use the `assert*` functions before creating providers
|
|
131
|
-
2. **Handle errors gracefully** - Catch and properly handle validation and authentication errors
|
|
132
|
-
3. **Store credentials securely** - Use environment variables or secure configuration management
|
|
133
|
-
4. **Cache tokens when possible** - The IMS provider handles token lifecycle internally
|
|
134
|
-
5. **Use TypeScript** - Leverage the full type safety provided by the library
|
|
18
|
+
See the [Usage Guide](./docs/usage.md) for more information.
|
|
135
19
|
|
|
136
20
|
## Contributing
|
|
137
21
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,78 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
5
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
7
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
11
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
var __create = Object.create, __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __getOwnPropNames = Object.getOwnPropertyNames, __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty, __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from == "object" || typeof from == "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) key = keys[i], !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, {
|
|
16
|
+
get: ((k) => from[k]).bind(null, key),
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
16
19
|
return to;
|
|
17
|
-
}
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
}, __toESM = (mod, isNodeMode, target) => (target = mod == null ? {} : __create(__getProtoOf(mod)), __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
21
|
value: mod,
|
|
20
|
-
enumerable:
|
|
22
|
+
enumerable: !0
|
|
21
23
|
}) : target, mod));
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
const __adobe_aio_commerce_lib_core_error = __toESM(require("@adobe/aio-commerce-lib-core/error"));
|
|
25
|
-
const __adobe_aio_lib_ims = __toESM(require("@adobe/aio-lib-ims"));
|
|
26
|
-
const valibot = __toESM(require("valibot"));
|
|
27
|
-
const node_crypto = __toESM(require("node:crypto"));
|
|
28
|
-
const oauth_1_0a = __toESM(require("oauth-1.0a"));
|
|
29
|
-
|
|
30
|
-
//#region source/lib/ims-auth/schema.ts
|
|
31
|
-
/**
|
|
32
|
-
* Creates a validation schema for a required IMS auth string parameter.
|
|
33
|
-
* @param name The name of the parameter for error messages.
|
|
34
|
-
* @returns A validation pipeline that ensures the parameter is a non-empty string.
|
|
35
|
-
*/
|
|
36
|
-
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}`));
|
|
37
|
-
/**
|
|
38
|
-
* Creates a validation schema for an IMS auth string array parameter.
|
|
39
|
-
* @param name The name of the parameter for error messages.
|
|
40
|
-
* @returns A validation pipeline that ensures the parameter is an array of strings.
|
|
41
|
-
*/
|
|
42
|
-
const stringArray = (name) => {
|
|
43
|
-
return (0, valibot.pipe)((0, valibot.array)((0, valibot.string)(), `Expected a stringified JSON array value for the IMS auth parameter ${name}`));
|
|
44
|
-
};
|
|
45
|
-
/** The environments accepted by the IMS auth service. */
|
|
46
|
-
const IMS_AUTH_ENV = {
|
|
24
|
+
const __adobe_aio_commerce_lib_core_error = __toESM(require("@adobe/aio-commerce-lib-core/error")), __adobe_aio_lib_ims = __toESM(require("@adobe/aio-lib-ims")), valibot = __toESM(require("valibot")), crypto = __toESM(require("crypto")), oauth_1_0a = __toESM(require("oauth-1.0a")), 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}`)), stringArray = (name) => (0, valibot.pipe)((0, valibot.array)((0, valibot.string)(), `Expected a string array value for the IMS auth parameter ${name}`)), IMS_AUTH_ENV = {
|
|
47
25
|
PROD: "prod",
|
|
48
26
|
STAGE: "stage"
|
|
49
|
-
}
|
|
50
|
-
/** Validation schema for IMS auth environment values. */
|
|
51
|
-
const ImsAuthEnvSchema = (0, valibot.enum)(IMS_AUTH_ENV);
|
|
52
|
-
/** Defines the schema to validate the necessary parameters for the IMS auth service. */
|
|
53
|
-
const ImsAuthParamsSchema = (0, valibot.object)({
|
|
27
|
+
}, ImsAuthEnvSchema = (0, valibot.enum)(IMS_AUTH_ENV), ImsAuthParamsSchema = (0, valibot.object)({
|
|
54
28
|
clientId: imsAuthParameter("clientId"),
|
|
55
29
|
clientSecrets: (0, valibot.pipe)(stringArray("clientSecrets"), (0, valibot.minLength)(1, "Expected at least one client secret for IMS auth")),
|
|
56
30
|
technicalAccountId: imsAuthParameter("technicalAccountId"),
|
|
57
31
|
technicalAccountEmail: (0, valibot.pipe)((0, valibot.string)("Expected a string value for the IMS auth parameter technicalAccountEmail"), (0, valibot.email)("Expected a valid email format for technicalAccountEmail")),
|
|
58
32
|
imsOrgId: imsAuthParameter("imsOrgId"),
|
|
59
33
|
environment: (0, valibot.pipe)((0, valibot.optional)(ImsAuthEnvSchema, IMS_AUTH_ENV.PROD)),
|
|
60
|
-
context: (0, valibot.pipe)((0, valibot.optional)((0, valibot.string)()
|
|
34
|
+
context: (0, valibot.pipe)((0, valibot.optional)((0, valibot.string)())),
|
|
61
35
|
scopes: (0, valibot.pipe)(stringArray("scopes"), (0, valibot.minLength)(1, "Expected at least one scope for IMS auth"))
|
|
62
36
|
});
|
|
63
|
-
|
|
64
|
-
//#endregion
|
|
65
|
-
//#region source/lib/ims-auth/provider.ts
|
|
66
|
-
/**
|
|
67
|
-
* Converts IMS auth configuration properties to snake_case format.
|
|
68
|
-
* @param config The IMS auth configuration with camelCase properties.
|
|
69
|
-
* @returns The configuration with snake_case properties.
|
|
70
|
-
*/
|
|
71
37
|
function toImsAuthConfig(config) {
|
|
72
38
|
return {
|
|
73
39
|
scopes: config.scopes,
|
|
74
40
|
env: config?.environment ?? "prod",
|
|
75
|
-
context: config.context,
|
|
41
|
+
context: config.context ?? "aio-commerce-lib-auth-creds",
|
|
76
42
|
client_id: config.clientId,
|
|
77
43
|
client_secrets: config.clientSecrets,
|
|
78
44
|
technical_account_id: config.technicalAccountId,
|
|
@@ -80,90 +46,16 @@ function toImsAuthConfig(config) {
|
|
|
80
46
|
ims_org_id: config.imsOrgId
|
|
81
47
|
};
|
|
82
48
|
}
|
|
83
|
-
/**
|
|
84
|
-
* Asserts the provided configuration for an Adobe IMS authentication provider. {@link ImsAuthParams}
|
|
85
|
-
* {@link ImsAuthProvider}
|
|
86
|
-
* @param config {Record<PropertyKey, unknown>} The configuration to validate.
|
|
87
|
-
* @throws {CommerceSdkValidationError} If the configuration is invalid.
|
|
88
|
-
* @example
|
|
89
|
-
* ```typescript
|
|
90
|
-
* const config = {
|
|
91
|
-
* clientId: "your-client-id",
|
|
92
|
-
* clientSecrets: ["your-client-secret"],
|
|
93
|
-
* technicalAccountId: "your-technical-account-id",
|
|
94
|
-
* technicalAccountEmail: "your-account@example.com",
|
|
95
|
-
* imsOrgId: "your-ims-org-id@AdobeOrg",
|
|
96
|
-
* scopes: ["AdobeID", "openid"],
|
|
97
|
-
* environment: "prod", // or "stage"
|
|
98
|
-
* context: "my-app-context"
|
|
99
|
-
* };
|
|
100
|
-
*
|
|
101
|
-
* // This will validate the config and throw if invalid
|
|
102
|
-
* assertImsAuthParams(config);
|
|
103
|
-
*```
|
|
104
|
-
* @example
|
|
105
|
-
* ```typescript
|
|
106
|
-
* // Example of a failing assert:
|
|
107
|
-
* try {
|
|
108
|
-
* assertImsAuthParams({
|
|
109
|
-
* clientId: "valid-client-id",
|
|
110
|
-
* // Missing required fields like clientSecrets, technicalAccountId, etc.
|
|
111
|
-
* });
|
|
112
|
-
* } catch (error) {
|
|
113
|
-
* console.error(error.message); // "Invalid ImsAuthProvider configuration"
|
|
114
|
-
* console.error(error.issues); // Array of validation issues
|
|
115
|
-
* }
|
|
116
|
-
* ```
|
|
117
|
-
*/
|
|
118
49
|
function assertImsAuthParams(config) {
|
|
119
|
-
|
|
50
|
+
let result = (0, valibot.safeParse)(ImsAuthParamsSchema, config);
|
|
120
51
|
if (!result.success) throw new __adobe_aio_commerce_lib_core_error.CommerceSdkValidationError("Invalid ImsAuthProvider configuration", { issues: result.issues });
|
|
121
52
|
}
|
|
122
|
-
/**
|
|
123
|
-
* Creates an {@link ImsAuthProvider} based on the provided configuration.
|
|
124
|
-
* @param config An {@link ImsAuthParams} parameter that contains the configuration for the IMS auth provider.
|
|
125
|
-
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
126
|
-
* @example
|
|
127
|
-
* ```typescript
|
|
128
|
-
* const config = {
|
|
129
|
-
* clientId: "your-client-id",
|
|
130
|
-
* clientSecrets: ["your-client-secret"],
|
|
131
|
-
* technicalAccountId: "your-technical-account-id",
|
|
132
|
-
* technicalAccountEmail: "your-account@example.com",
|
|
133
|
-
* imsOrgId: "your-ims-org-id@AdobeOrg",
|
|
134
|
-
* scopes: ["AdobeID", "openid"],
|
|
135
|
-
* environment: "prod",
|
|
136
|
-
* context: "my-app-context"
|
|
137
|
-
* };
|
|
138
|
-
*
|
|
139
|
-
* const authProvider = getImsAuthProvider(config);
|
|
140
|
-
*
|
|
141
|
-
* // Get access token
|
|
142
|
-
* const token = await authProvider.getAccessToken();
|
|
143
|
-
* console.log(token); // "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."
|
|
144
|
-
*
|
|
145
|
-
* // Get headers for API requests
|
|
146
|
-
* const headers = await authProvider.getHeaders();
|
|
147
|
-
* console.log(headers);
|
|
148
|
-
* // {
|
|
149
|
-
* // Authorization: "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
|
|
150
|
-
* // "x-api-key": "your-client-id"
|
|
151
|
-
* // }
|
|
152
|
-
*
|
|
153
|
-
* // Use headers in API calls
|
|
154
|
-
* const response = await fetch('https://api.adobe.io/some-endpoint', {
|
|
155
|
-
* headers: await authProvider.getHeaders()
|
|
156
|
-
* });
|
|
157
|
-
* ```
|
|
158
|
-
*/
|
|
159
53
|
function getImsAuthProvider(authParams) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
await __adobe_aio_lib_ims.context.set(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const getHeaders = async () => {
|
|
166
|
-
const accessToken = await getAccessToken();
|
|
54
|
+
let getAccessToken = async () => {
|
|
55
|
+
let imsAuthConfig = toImsAuthConfig(authParams);
|
|
56
|
+
return await __adobe_aio_lib_ims.context.set(imsAuthConfig.context, imsAuthConfig), (0, __adobe_aio_lib_ims.getToken)(imsAuthConfig.context, {});
|
|
57
|
+
}, getHeaders = async () => {
|
|
58
|
+
let accessToken = await getAccessToken();
|
|
167
59
|
return {
|
|
168
60
|
Authorization: `Bearer ${accessToken}`,
|
|
169
61
|
"x-api-key": authParams.clientId
|
|
@@ -174,119 +66,34 @@ function getImsAuthProvider(authParams) {
|
|
|
174
66
|
getHeaders
|
|
175
67
|
};
|
|
176
68
|
}
|
|
177
|
-
|
|
178
|
-
//#endregion
|
|
179
|
-
//#region source/lib/integration-auth/schema.ts
|
|
180
|
-
/**
|
|
181
|
-
* Creates a validation schema for a required Commerce Integration string parameter.
|
|
182
|
-
* @param name The name of the parameter for error messages.
|
|
183
|
-
* @returns A validation pipeline that ensures the parameter is a non-empty string.
|
|
184
|
-
*/
|
|
185
|
-
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}`));
|
|
186
|
-
/** Validation schema for the Adobe Commerce endpoint base URL. */
|
|
187
|
-
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"));
|
|
188
|
-
/** Validation schema that accepts either a URL string or URL instance and normalizes to string. */
|
|
189
|
-
const UrlSchema = (0, valibot.pipe)((0, valibot.union)([BaseUrlSchema, (0, valibot.instance)(URL)]), (0, valibot.transform)((url) => {
|
|
190
|
-
if (url instanceof URL) return url.toString();
|
|
191
|
-
return url;
|
|
192
|
-
}));
|
|
193
|
-
/**
|
|
194
|
-
* The schema for the Commerce Integration parameters.
|
|
195
|
-
* This is used to validate the parameters passed to the Commerce Integration provider.
|
|
196
|
-
*/
|
|
197
|
-
const IntegrationAuthParamsSchema = (0, valibot.nonOptional)((0, valibot.object)({
|
|
69
|
+
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}`)), 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")), UrlSchema = (0, valibot.pipe)((0, valibot.union)([BaseUrlSchema, (0, valibot.instance)(URL)]), (0, valibot.transform)((url) => url instanceof URL ? url.toString() : url)), IntegrationAuthParamsSchema = (0, valibot.nonOptional)((0, valibot.object)({
|
|
198
70
|
consumerKey: integrationAuthParameter("consumerKey"),
|
|
199
71
|
consumerSecret: integrationAuthParameter("consumerSecret"),
|
|
200
72
|
accessToken: integrationAuthParameter("accessToken"),
|
|
201
73
|
accessTokenSecret: integrationAuthParameter("accessTokenSecret")
|
|
202
74
|
}));
|
|
203
|
-
|
|
204
|
-
//#endregion
|
|
205
|
-
//#region source/lib/integration-auth/provider.ts
|
|
206
|
-
/**
|
|
207
|
-
* Asserts the provided configuration for an Adobe Commerce integration authentication provider. {@link IntegrationAuthParams}
|
|
208
|
-
* {@link IntegrationAuthProvider}
|
|
209
|
-
* @param config {Record<PropertyKey, unknown>} The configuration to validate.
|
|
210
|
-
* @throws {CommerceSdkValidationError} If the configuration is invalid.
|
|
211
|
-
* @example
|
|
212
|
-
* ```typescript
|
|
213
|
-
* const config = {
|
|
214
|
-
* consumerKey: "your-consumer-key",
|
|
215
|
-
* consumerSecret: "your-consumer-secret",
|
|
216
|
-
* accessToken: "your-access-token",
|
|
217
|
-
* accessTokenSecret: "your-access-token-secret"
|
|
218
|
-
* };
|
|
219
|
-
*
|
|
220
|
-
* // This will validate the config and throw if invalid
|
|
221
|
-
* assertIntegrationAuthParams(config);
|
|
222
|
-
* ```
|
|
223
|
-
* @example
|
|
224
|
-
* ```typescript
|
|
225
|
-
* // Example of a failing assert:
|
|
226
|
-
* try {
|
|
227
|
-
* assertIntegrationAuthParams({
|
|
228
|
-
* consumerKey: "valid-consumer-key",
|
|
229
|
-
* // Missing required fields like consumerSecret, accessToken, accessTokenSecret
|
|
230
|
-
* });
|
|
231
|
-
* } catch (error) {
|
|
232
|
-
* console.error(error.message); // "Invalid IntegrationAuthProvider configuration"
|
|
233
|
-
* console.error(error.issues); // Array of validation issues
|
|
234
|
-
* }
|
|
235
|
-
* ```
|
|
236
|
-
*/
|
|
237
75
|
function assertIntegrationAuthParams(config) {
|
|
238
|
-
|
|
76
|
+
let result = (0, valibot.safeParse)(IntegrationAuthParamsSchema, config);
|
|
239
77
|
if (!result.success) throw new __adobe_aio_commerce_lib_core_error.CommerceSdkValidationError("Invalid IntegrationAuthProvider configuration", { issues: result.issues });
|
|
240
78
|
}
|
|
241
|
-
/**
|
|
242
|
-
* Creates an {@link IntegrationAuthProvider} based on the provided configuration.
|
|
243
|
-
* @param config {IntegrationAuthParams} The configuration for the integration.
|
|
244
|
-
* @returns An {@link IntegrationAuthProvider} instance that can be used to get auth headers.
|
|
245
|
-
* @example
|
|
246
|
-
* ```typescript
|
|
247
|
-
* const config = {
|
|
248
|
-
* consumerKey: "your-consumer-key",
|
|
249
|
-
* consumerSecret: "your-consumer-secret",
|
|
250
|
-
* accessToken: "your-access-token",
|
|
251
|
-
* accessTokenSecret: "your-access-token-secret"
|
|
252
|
-
* };
|
|
253
|
-
*
|
|
254
|
-
* const authProvider = getIntegrationAuthProvider(config);
|
|
255
|
-
*
|
|
256
|
-
* // Get OAuth headers for a REST API call
|
|
257
|
-
* const headers = authProvider.getHeaders("GET", "https://your-store.com/rest/V1/products");
|
|
258
|
-
* console.log(headers); // { Authorization: "OAuth oauth_consumer_key=..., oauth_signature=..." }
|
|
259
|
-
*
|
|
260
|
-
* // Can also be used with URL objects
|
|
261
|
-
* const url = new URL("https://your-store.com/rest/V1/customers");
|
|
262
|
-
* const postHeaders = authProvider.getHeaders("POST", url);
|
|
263
|
-
* ```
|
|
264
|
-
*/
|
|
265
79
|
function getIntegrationAuthProvider(authParams) {
|
|
266
|
-
|
|
80
|
+
let oauth = new oauth_1_0a.default({
|
|
267
81
|
consumer: {
|
|
268
82
|
key: authParams.consumerKey,
|
|
269
83
|
secret: authParams.consumerSecret
|
|
270
84
|
},
|
|
271
85
|
signature_method: "HMAC-SHA256",
|
|
272
|
-
hash_function: (baseString, key) =>
|
|
273
|
-
})
|
|
274
|
-
const oauthToken = {
|
|
86
|
+
hash_function: (baseString, key) => crypto.default.createHmac("sha256", key).update(baseString).digest("base64")
|
|
87
|
+
}), oauthToken = {
|
|
275
88
|
key: authParams.accessToken,
|
|
276
89
|
secret: authParams.accessTokenSecret
|
|
277
90
|
};
|
|
278
91
|
return { getHeaders: (method, url) => {
|
|
279
|
-
|
|
92
|
+
let urlString = url instanceof URL ? url.toString() : url;
|
|
280
93
|
return oauth.toHeader(oauth.authorize({
|
|
281
94
|
url: urlString,
|
|
282
95
|
method
|
|
283
96
|
}, oauthToken));
|
|
284
97
|
} };
|
|
285
98
|
}
|
|
286
|
-
|
|
287
|
-
//#endregion
|
|
288
|
-
exports.IMS_AUTH_ENV = IMS_AUTH_ENV;
|
|
289
|
-
exports.assertImsAuthParams = assertImsAuthParams;
|
|
290
|
-
exports.assertIntegrationAuthParams = assertIntegrationAuthParams;
|
|
291
|
-
exports.getImsAuthProvider = getImsAuthProvider;
|
|
292
|
-
exports.getIntegrationAuthProvider = getIntegrationAuthProvider;
|
|
99
|
+
exports.IMS_AUTH_ENV = IMS_AUTH_ENV, exports.assertImsAuthParams = assertImsAuthParams, exports.assertIntegrationAuthParams = assertIntegrationAuthParams, exports.getImsAuthProvider = getImsAuthProvider, exports.getIntegrationAuthProvider = getIntegrationAuthProvider;
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -1,39 +1,132 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
5
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
7
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
11
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import * as valibot21 from "valibot";
|
|
2
16
|
import { InferOutput } from "valibot";
|
|
3
17
|
|
|
4
18
|
//#region source/lib/ims-auth/schema.d.ts
|
|
19
|
+
/** The environments accepted by the IMS auth service. */
|
|
5
20
|
declare const IMS_AUTH_ENV: {
|
|
6
21
|
readonly PROD: "prod";
|
|
7
22
|
readonly STAGE: "stage";
|
|
8
23
|
};
|
|
9
|
-
|
|
24
|
+
/** Validation schema for IMS auth environment values. */
|
|
25
|
+
declare const ImsAuthEnvSchema: valibot21.EnumSchema<{
|
|
10
26
|
readonly PROD: "prod";
|
|
11
27
|
readonly STAGE: "stage";
|
|
12
28
|
}, undefined>;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
readonly
|
|
16
|
-
readonly
|
|
17
|
-
readonly
|
|
18
|
-
readonly
|
|
19
|
-
readonly
|
|
29
|
+
/** Defines the schema to validate the necessary parameters for the IMS auth service. */
|
|
30
|
+
declare const ImsAuthParamsSchema: valibot21.ObjectSchema<{
|
|
31
|
+
readonly clientId: valibot21.SchemaWithPipe<readonly [valibot21.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot21.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
32
|
+
readonly clientSecrets: valibot21.SchemaWithPipe<readonly [valibot21.SchemaWithPipe<readonly [valibot21.ArraySchema<valibot21.StringSchema<undefined>, `Expected a string array value for the IMS auth parameter ${string}`>]>, valibot21.MinLengthAction<string[], 1, "Expected at least one client secret for IMS auth">]>;
|
|
33
|
+
readonly technicalAccountId: valibot21.SchemaWithPipe<readonly [valibot21.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot21.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
34
|
+
readonly technicalAccountEmail: valibot21.SchemaWithPipe<readonly [valibot21.StringSchema<"Expected a string value for the IMS auth parameter technicalAccountEmail">, valibot21.EmailAction<string, "Expected a valid email format for technicalAccountEmail">]>;
|
|
35
|
+
readonly imsOrgId: valibot21.SchemaWithPipe<readonly [valibot21.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot21.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
36
|
+
readonly environment: valibot21.SchemaWithPipe<readonly [valibot21.OptionalSchema<valibot21.EnumSchema<{
|
|
20
37
|
readonly PROD: "prod";
|
|
21
38
|
readonly STAGE: "stage";
|
|
22
39
|
}, undefined>, "prod">]>;
|
|
23
|
-
readonly context:
|
|
24
|
-
readonly scopes:
|
|
40
|
+
readonly context: valibot21.SchemaWithPipe<readonly [valibot21.OptionalSchema<valibot21.StringSchema<undefined>, undefined>]>;
|
|
41
|
+
readonly scopes: valibot21.SchemaWithPipe<readonly [valibot21.SchemaWithPipe<readonly [valibot21.ArraySchema<valibot21.StringSchema<undefined>, `Expected a string array value for the IMS auth parameter ${string}`>]>, valibot21.MinLengthAction<string[], 1, "Expected at least one scope for IMS auth">]>;
|
|
25
42
|
}, undefined>;
|
|
43
|
+
/** Defines the parameters for the IMS auth service. */
|
|
26
44
|
type ImsAuthParams = InferOutput<typeof ImsAuthParamsSchema>;
|
|
45
|
+
/** Defines the environments accepted by the IMS auth service. */
|
|
27
46
|
type ImsAuthEnv = InferOutput<typeof ImsAuthEnvSchema>;
|
|
28
47
|
//#endregion
|
|
29
48
|
//#region source/lib/ims-auth/provider.d.ts
|
|
49
|
+
/** Defines the header keys used for IMS authentication. */
|
|
30
50
|
type ImsAuthHeader = "Authorization" | "x-api-key";
|
|
51
|
+
/** Defines the headers required for IMS authentication. */
|
|
31
52
|
type ImsAuthHeaders = Record<ImsAuthHeader, string>;
|
|
53
|
+
/** Defines an authentication provider for Adobe IMS. */
|
|
32
54
|
interface ImsAuthProvider {
|
|
33
55
|
getAccessToken: () => Promise<string>;
|
|
34
56
|
getHeaders: () => Promise<ImsAuthHeaders>;
|
|
35
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Asserts the provided configuration for an {@link ImsAuthProvider}.
|
|
60
|
+
* @param config The configuration to validate.
|
|
61
|
+
* @throws {CommerceSdkValidationError} If the configuration is invalid.
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const config = {
|
|
65
|
+
* clientId: "your-client-id",
|
|
66
|
+
* clientSecrets: ["your-client-secret"],
|
|
67
|
+
* technicalAccountId: "your-technical-account-id",
|
|
68
|
+
* technicalAccountEmail: "your-account@example.com",
|
|
69
|
+
* imsOrgId: "your-ims-org-id@AdobeOrg",
|
|
70
|
+
* scopes: ["AdobeID", "openid"],
|
|
71
|
+
* environment: "prod", // or "stage"
|
|
72
|
+
* context: "my-app-context"
|
|
73
|
+
* };
|
|
74
|
+
*
|
|
75
|
+
* // This will validate the config and throw if invalid
|
|
76
|
+
* assertImsAuthParams(config);
|
|
77
|
+
*```
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* // Example of a failing assert:
|
|
81
|
+
* try {
|
|
82
|
+
* assertImsAuthParams({
|
|
83
|
+
* clientId: "valid-client-id",
|
|
84
|
+
* // Missing required fields like clientSecrets, technicalAccountId, etc.
|
|
85
|
+
* });
|
|
86
|
+
* } catch (error) {
|
|
87
|
+
* console.error(error.message); // "Invalid ImsAuthProvider configuration"
|
|
88
|
+
* console.error(error.issues); // Array of validation issues
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
36
92
|
declare function assertImsAuthParams(config: Record<PropertyKey, unknown>): asserts config is ImsAuthParams;
|
|
93
|
+
/**
|
|
94
|
+
* Creates an {@link ImsAuthProvider} based on the provided configuration.
|
|
95
|
+
* @param authParams An {@link ImsAuthParams} parameter that contains the configuration for the {@link ImsAuthProvider}.
|
|
96
|
+
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const config = {
|
|
100
|
+
* clientId: "your-client-id",
|
|
101
|
+
* clientSecrets: ["your-client-secret"],
|
|
102
|
+
* technicalAccountId: "your-technical-account-id",
|
|
103
|
+
* technicalAccountEmail: "your-account@example.com",
|
|
104
|
+
* imsOrgId: "your-ims-org-id@AdobeOrg",
|
|
105
|
+
* scopes: ["AdobeID", "openid"],
|
|
106
|
+
* environment: "prod",
|
|
107
|
+
* context: "my-app-context"
|
|
108
|
+
* };
|
|
109
|
+
*
|
|
110
|
+
* const authProvider = getImsAuthProvider(config);
|
|
111
|
+
*
|
|
112
|
+
* // Get access token
|
|
113
|
+
* const token = await authProvider.getAccessToken();
|
|
114
|
+
* console.log(token); // "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."
|
|
115
|
+
*
|
|
116
|
+
* // Get headers for API requests
|
|
117
|
+
* const headers = await authProvider.getHeaders();
|
|
118
|
+
* console.log(headers);
|
|
119
|
+
* // {
|
|
120
|
+
* // Authorization: "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
|
|
121
|
+
* // "x-api-key": "your-client-id"
|
|
122
|
+
* // }
|
|
123
|
+
*
|
|
124
|
+
* // Use headers in API calls
|
|
125
|
+
* const response = await fetch('https://api.adobe.io/some-endpoint', {
|
|
126
|
+
* headers: await authProvider.getHeaders()
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
37
130
|
declare function getImsAuthProvider(authParams: ImsAuthParams): {
|
|
38
131
|
getAccessToken: () => Promise<string>;
|
|
39
132
|
getHeaders: () => Promise<{
|
|
@@ -43,23 +136,92 @@ declare function getImsAuthProvider(authParams: ImsAuthParams): {
|
|
|
43
136
|
};
|
|
44
137
|
//#endregion
|
|
45
138
|
//#region source/lib/integration-auth/schema.d.ts
|
|
139
|
+
/**
|
|
140
|
+
* The HTTP methods supported by Commerce.
|
|
141
|
+
* This is used to determine which headers to include in the signing of the authorization header.
|
|
142
|
+
*/
|
|
46
143
|
type HttpMethodInput = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
144
|
+
/** Validation schema that accepts either a URL string or URL instance and normalizes to string. */
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The schema for the Commerce Integration parameters.
|
|
148
|
+
* This is used to validate the parameters passed to the Commerce Integration provider.
|
|
149
|
+
*/
|
|
150
|
+
declare const IntegrationAuthParamsSchema: valibot21.NonOptionalSchema<valibot21.ObjectSchema<{
|
|
151
|
+
readonly consumerKey: valibot21.SchemaWithPipe<readonly [valibot21.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot21.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
152
|
+
readonly consumerSecret: valibot21.SchemaWithPipe<readonly [valibot21.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot21.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
153
|
+
readonly accessToken: valibot21.SchemaWithPipe<readonly [valibot21.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot21.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
154
|
+
readonly accessTokenSecret: valibot21.SchemaWithPipe<readonly [valibot21.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot21.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
52
155
|
}, undefined>, undefined>;
|
|
156
|
+
/** Defines the parameters required for Commerce Integration authentication. */
|
|
53
157
|
type IntegrationAuthParams = InferOutput<typeof IntegrationAuthParamsSchema>;
|
|
54
158
|
//#endregion
|
|
55
159
|
//#region source/lib/integration-auth/provider.d.ts
|
|
160
|
+
/** Defines the header key used for Commerce Integration authentication. */
|
|
56
161
|
type IntegrationAuthHeader = "Authorization";
|
|
162
|
+
/** Defines the headers required for Commerce Integration authentication. */
|
|
57
163
|
type IntegrationAuthHeaders = Record<IntegrationAuthHeader, string>;
|
|
164
|
+
/** Represents a URL for Adobe Commerce endpoints, accepting either string or URL object. */
|
|
58
165
|
type AdobeCommerceUrl = string | URL;
|
|
166
|
+
/** Defines an authentication provider for Adobe Commerce integrations. */
|
|
59
167
|
interface IntegrationAuthProvider {
|
|
60
168
|
getHeaders: (method: HttpMethodInput, url: AdobeCommerceUrl) => IntegrationAuthHeaders;
|
|
61
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Asserts the provided configuration for an Adobe Commerce {@link IntegrationAuthProvider}.
|
|
172
|
+
* @param config The configuration to validate.
|
|
173
|
+
* @throws {CommerceSdkValidationError} If the configuration is invalid.
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const config = {
|
|
177
|
+
* consumerKey: "your-consumer-key",
|
|
178
|
+
* consumerSecret: "your-consumer-secret",
|
|
179
|
+
* accessToken: "your-access-token",
|
|
180
|
+
* accessTokenSecret: "your-access-token-secret"
|
|
181
|
+
* };
|
|
182
|
+
*
|
|
183
|
+
* // This will validate the config and throw if invalid
|
|
184
|
+
* assertIntegrationAuthParams(config);
|
|
185
|
+
* ```
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* // Example of a failing assert:
|
|
189
|
+
* try {
|
|
190
|
+
* assertIntegrationAuthParams({
|
|
191
|
+
* consumerKey: "valid-consumer-key",
|
|
192
|
+
* // Missing required fields like consumerSecret, accessToken, accessTokenSecret
|
|
193
|
+
* });
|
|
194
|
+
* } catch (error) {
|
|
195
|
+
* console.error(error.message); // "Invalid IntegrationAuthProvider configuration"
|
|
196
|
+
* console.error(error.issues); // Array of validation issues
|
|
197
|
+
* }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
62
200
|
declare function assertIntegrationAuthParams(config: Record<PropertyKey, unknown>): asserts config is IntegrationAuthParams;
|
|
201
|
+
/**
|
|
202
|
+
* Creates an {@link IntegrationAuthProvider} based on the provided configuration.
|
|
203
|
+
* @param authParams The configuration for the integration.
|
|
204
|
+
* @returns An {@link IntegrationAuthProvider} instance that can be used to get auth headers.
|
|
205
|
+
* @example
|
|
206
|
+
* ```typescript
|
|
207
|
+
* const config = {
|
|
208
|
+
* consumerKey: "your-consumer-key",
|
|
209
|
+
* consumerSecret: "your-consumer-secret",
|
|
210
|
+
* accessToken: "your-access-token",
|
|
211
|
+
* accessTokenSecret: "your-access-token-secret"
|
|
212
|
+
* };
|
|
213
|
+
*
|
|
214
|
+
* const authProvider = getIntegrationAuthProvider(config);
|
|
215
|
+
*
|
|
216
|
+
* // Get OAuth headers for a REST API call
|
|
217
|
+
* const headers = authProvider.getHeaders("GET", "https://your-store.com/rest/V1/products");
|
|
218
|
+
* console.log(headers); // { Authorization: "OAuth oauth_consumer_key=..., oauth_signature=..." }
|
|
219
|
+
*
|
|
220
|
+
* // Can also be used with URL objects
|
|
221
|
+
* const url = new URL("https://your-store.com/rest/V1/customers");
|
|
222
|
+
* const postHeaders = authProvider.getHeaders("POST", url);
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
63
225
|
declare function getIntegrationAuthProvider(authParams: IntegrationAuthParams): IntegrationAuthProvider;
|
|
64
226
|
//#endregion
|
|
65
|
-
export { IMS_AUTH_ENV, ImsAuthEnv, ImsAuthParams, ImsAuthProvider, IntegrationAuthParams, IntegrationAuthProvider, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };
|
|
227
|
+
export { IMS_AUTH_ENV, type ImsAuthEnv, type ImsAuthParams, type ImsAuthProvider, type IntegrationAuthParams, type IntegrationAuthProvider, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };
|
package/dist/es/index.d.ts
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
5
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
7
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
11
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
1
15
|
import * as valibot0 from "valibot";
|
|
2
16
|
import { InferOutput } from "valibot";
|
|
3
17
|
|
|
4
18
|
//#region source/lib/ims-auth/schema.d.ts
|
|
19
|
+
/** The environments accepted by the IMS auth service. */
|
|
5
20
|
declare const IMS_AUTH_ENV: {
|
|
6
21
|
readonly PROD: "prod";
|
|
7
22
|
readonly STAGE: "stage";
|
|
8
23
|
};
|
|
24
|
+
/** Validation schema for IMS auth environment values. */
|
|
9
25
|
declare const ImsAuthEnvSchema: valibot0.EnumSchema<{
|
|
10
26
|
readonly PROD: "prod";
|
|
11
27
|
readonly STAGE: "stage";
|
|
12
28
|
}, undefined>;
|
|
29
|
+
/** Defines the schema to validate the necessary parameters for the IMS auth service. */
|
|
13
30
|
declare const ImsAuthParamsSchema: valibot0.ObjectSchema<{
|
|
14
31
|
readonly clientId: valibot0.SchemaWithPipe<readonly [valibot0.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot0.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
15
|
-
readonly clientSecrets: valibot0.SchemaWithPipe<readonly [valibot0.SchemaWithPipe<readonly [valibot0.ArraySchema<valibot0.StringSchema<undefined>, `Expected a
|
|
32
|
+
readonly clientSecrets: valibot0.SchemaWithPipe<readonly [valibot0.SchemaWithPipe<readonly [valibot0.ArraySchema<valibot0.StringSchema<undefined>, `Expected a string array value for the IMS auth parameter ${string}`>]>, valibot0.MinLengthAction<string[], 1, "Expected at least one client secret for IMS auth">]>;
|
|
16
33
|
readonly technicalAccountId: valibot0.SchemaWithPipe<readonly [valibot0.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot0.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
17
34
|
readonly technicalAccountEmail: valibot0.SchemaWithPipe<readonly [valibot0.StringSchema<"Expected a string value for the IMS auth parameter technicalAccountEmail">, valibot0.EmailAction<string, "Expected a valid email format for technicalAccountEmail">]>;
|
|
18
35
|
readonly imsOrgId: valibot0.SchemaWithPipe<readonly [valibot0.StringSchema<`Expected a string value for the IMS auth parameter ${string}`>, valibot0.NonEmptyAction<string, `Expected a non-empty string value for the IMS auth parameter ${string}`>]>;
|
|
@@ -20,20 +37,96 @@ declare const ImsAuthParamsSchema: valibot0.ObjectSchema<{
|
|
|
20
37
|
readonly PROD: "prod";
|
|
21
38
|
readonly STAGE: "stage";
|
|
22
39
|
}, undefined>, "prod">]>;
|
|
23
|
-
readonly context: valibot0.SchemaWithPipe<readonly [valibot0.OptionalSchema<valibot0.StringSchema<undefined>,
|
|
24
|
-
readonly scopes: valibot0.SchemaWithPipe<readonly [valibot0.SchemaWithPipe<readonly [valibot0.ArraySchema<valibot0.StringSchema<undefined>, `Expected a
|
|
40
|
+
readonly context: valibot0.SchemaWithPipe<readonly [valibot0.OptionalSchema<valibot0.StringSchema<undefined>, undefined>]>;
|
|
41
|
+
readonly scopes: valibot0.SchemaWithPipe<readonly [valibot0.SchemaWithPipe<readonly [valibot0.ArraySchema<valibot0.StringSchema<undefined>, `Expected a string array value for the IMS auth parameter ${string}`>]>, valibot0.MinLengthAction<string[], 1, "Expected at least one scope for IMS auth">]>;
|
|
25
42
|
}, undefined>;
|
|
43
|
+
/** Defines the parameters for the IMS auth service. */
|
|
26
44
|
type ImsAuthParams = InferOutput<typeof ImsAuthParamsSchema>;
|
|
45
|
+
/** Defines the environments accepted by the IMS auth service. */
|
|
27
46
|
type ImsAuthEnv = InferOutput<typeof ImsAuthEnvSchema>;
|
|
28
47
|
//#endregion
|
|
29
48
|
//#region source/lib/ims-auth/provider.d.ts
|
|
49
|
+
/** Defines the header keys used for IMS authentication. */
|
|
30
50
|
type ImsAuthHeader = "Authorization" | "x-api-key";
|
|
51
|
+
/** Defines the headers required for IMS authentication. */
|
|
31
52
|
type ImsAuthHeaders = Record<ImsAuthHeader, string>;
|
|
53
|
+
/** Defines an authentication provider for Adobe IMS. */
|
|
32
54
|
interface ImsAuthProvider {
|
|
33
55
|
getAccessToken: () => Promise<string>;
|
|
34
56
|
getHeaders: () => Promise<ImsAuthHeaders>;
|
|
35
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Asserts the provided configuration for an {@link ImsAuthProvider}.
|
|
60
|
+
* @param config The configuration to validate.
|
|
61
|
+
* @throws {CommerceSdkValidationError} If the configuration is invalid.
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const config = {
|
|
65
|
+
* clientId: "your-client-id",
|
|
66
|
+
* clientSecrets: ["your-client-secret"],
|
|
67
|
+
* technicalAccountId: "your-technical-account-id",
|
|
68
|
+
* technicalAccountEmail: "your-account@example.com",
|
|
69
|
+
* imsOrgId: "your-ims-org-id@AdobeOrg",
|
|
70
|
+
* scopes: ["AdobeID", "openid"],
|
|
71
|
+
* environment: "prod", // or "stage"
|
|
72
|
+
* context: "my-app-context"
|
|
73
|
+
* };
|
|
74
|
+
*
|
|
75
|
+
* // This will validate the config and throw if invalid
|
|
76
|
+
* assertImsAuthParams(config);
|
|
77
|
+
*```
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* // Example of a failing assert:
|
|
81
|
+
* try {
|
|
82
|
+
* assertImsAuthParams({
|
|
83
|
+
* clientId: "valid-client-id",
|
|
84
|
+
* // Missing required fields like clientSecrets, technicalAccountId, etc.
|
|
85
|
+
* });
|
|
86
|
+
* } catch (error) {
|
|
87
|
+
* console.error(error.message); // "Invalid ImsAuthProvider configuration"
|
|
88
|
+
* console.error(error.issues); // Array of validation issues
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
36
92
|
declare function assertImsAuthParams(config: Record<PropertyKey, unknown>): asserts config is ImsAuthParams;
|
|
93
|
+
/**
|
|
94
|
+
* Creates an {@link ImsAuthProvider} based on the provided configuration.
|
|
95
|
+
* @param authParams An {@link ImsAuthParams} parameter that contains the configuration for the {@link ImsAuthProvider}.
|
|
96
|
+
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const config = {
|
|
100
|
+
* clientId: "your-client-id",
|
|
101
|
+
* clientSecrets: ["your-client-secret"],
|
|
102
|
+
* technicalAccountId: "your-technical-account-id",
|
|
103
|
+
* technicalAccountEmail: "your-account@example.com",
|
|
104
|
+
* imsOrgId: "your-ims-org-id@AdobeOrg",
|
|
105
|
+
* scopes: ["AdobeID", "openid"],
|
|
106
|
+
* environment: "prod",
|
|
107
|
+
* context: "my-app-context"
|
|
108
|
+
* };
|
|
109
|
+
*
|
|
110
|
+
* const authProvider = getImsAuthProvider(config);
|
|
111
|
+
*
|
|
112
|
+
* // Get access token
|
|
113
|
+
* const token = await authProvider.getAccessToken();
|
|
114
|
+
* console.log(token); // "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."
|
|
115
|
+
*
|
|
116
|
+
* // Get headers for API requests
|
|
117
|
+
* const headers = await authProvider.getHeaders();
|
|
118
|
+
* console.log(headers);
|
|
119
|
+
* // {
|
|
120
|
+
* // Authorization: "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
|
|
121
|
+
* // "x-api-key": "your-client-id"
|
|
122
|
+
* // }
|
|
123
|
+
*
|
|
124
|
+
* // Use headers in API calls
|
|
125
|
+
* const response = await fetch('https://api.adobe.io/some-endpoint', {
|
|
126
|
+
* headers: await authProvider.getHeaders()
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
37
130
|
declare function getImsAuthProvider(authParams: ImsAuthParams): {
|
|
38
131
|
getAccessToken: () => Promise<string>;
|
|
39
132
|
getHeaders: () => Promise<{
|
|
@@ -43,23 +136,92 @@ declare function getImsAuthProvider(authParams: ImsAuthParams): {
|
|
|
43
136
|
};
|
|
44
137
|
//#endregion
|
|
45
138
|
//#region source/lib/integration-auth/schema.d.ts
|
|
139
|
+
/**
|
|
140
|
+
* The HTTP methods supported by Commerce.
|
|
141
|
+
* This is used to determine which headers to include in the signing of the authorization header.
|
|
142
|
+
*/
|
|
46
143
|
type HttpMethodInput = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
144
|
+
/** Validation schema that accepts either a URL string or URL instance and normalizes to string. */
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The schema for the Commerce Integration parameters.
|
|
148
|
+
* This is used to validate the parameters passed to the Commerce Integration provider.
|
|
149
|
+
*/
|
|
47
150
|
declare const IntegrationAuthParamsSchema: valibot0.NonOptionalSchema<valibot0.ObjectSchema<{
|
|
48
151
|
readonly consumerKey: valibot0.SchemaWithPipe<readonly [valibot0.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot0.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
49
152
|
readonly consumerSecret: valibot0.SchemaWithPipe<readonly [valibot0.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot0.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
50
153
|
readonly accessToken: valibot0.SchemaWithPipe<readonly [valibot0.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot0.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
51
154
|
readonly accessTokenSecret: valibot0.SchemaWithPipe<readonly [valibot0.StringSchema<`Expected a string value for the Commerce Integration parameter ${string}`>, valibot0.NonEmptyAction<string, `Expected a non-empty string value for the Commerce Integration parameter ${string}`>]>;
|
|
52
155
|
}, undefined>, undefined>;
|
|
156
|
+
/** Defines the parameters required for Commerce Integration authentication. */
|
|
53
157
|
type IntegrationAuthParams = InferOutput<typeof IntegrationAuthParamsSchema>;
|
|
54
158
|
//#endregion
|
|
55
159
|
//#region source/lib/integration-auth/provider.d.ts
|
|
160
|
+
/** Defines the header key used for Commerce Integration authentication. */
|
|
56
161
|
type IntegrationAuthHeader = "Authorization";
|
|
162
|
+
/** Defines the headers required for Commerce Integration authentication. */
|
|
57
163
|
type IntegrationAuthHeaders = Record<IntegrationAuthHeader, string>;
|
|
164
|
+
/** Represents a URL for Adobe Commerce endpoints, accepting either string or URL object. */
|
|
58
165
|
type AdobeCommerceUrl = string | URL;
|
|
166
|
+
/** Defines an authentication provider for Adobe Commerce integrations. */
|
|
59
167
|
interface IntegrationAuthProvider {
|
|
60
168
|
getHeaders: (method: HttpMethodInput, url: AdobeCommerceUrl) => IntegrationAuthHeaders;
|
|
61
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Asserts the provided configuration for an Adobe Commerce {@link IntegrationAuthProvider}.
|
|
172
|
+
* @param config The configuration to validate.
|
|
173
|
+
* @throws {CommerceSdkValidationError} If the configuration is invalid.
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const config = {
|
|
177
|
+
* consumerKey: "your-consumer-key",
|
|
178
|
+
* consumerSecret: "your-consumer-secret",
|
|
179
|
+
* accessToken: "your-access-token",
|
|
180
|
+
* accessTokenSecret: "your-access-token-secret"
|
|
181
|
+
* };
|
|
182
|
+
*
|
|
183
|
+
* // This will validate the config and throw if invalid
|
|
184
|
+
* assertIntegrationAuthParams(config);
|
|
185
|
+
* ```
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* // Example of a failing assert:
|
|
189
|
+
* try {
|
|
190
|
+
* assertIntegrationAuthParams({
|
|
191
|
+
* consumerKey: "valid-consumer-key",
|
|
192
|
+
* // Missing required fields like consumerSecret, accessToken, accessTokenSecret
|
|
193
|
+
* });
|
|
194
|
+
* } catch (error) {
|
|
195
|
+
* console.error(error.message); // "Invalid IntegrationAuthProvider configuration"
|
|
196
|
+
* console.error(error.issues); // Array of validation issues
|
|
197
|
+
* }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
62
200
|
declare function assertIntegrationAuthParams(config: Record<PropertyKey, unknown>): asserts config is IntegrationAuthParams;
|
|
201
|
+
/**
|
|
202
|
+
* Creates an {@link IntegrationAuthProvider} based on the provided configuration.
|
|
203
|
+
* @param authParams The configuration for the integration.
|
|
204
|
+
* @returns An {@link IntegrationAuthProvider} instance that can be used to get auth headers.
|
|
205
|
+
* @example
|
|
206
|
+
* ```typescript
|
|
207
|
+
* const config = {
|
|
208
|
+
* consumerKey: "your-consumer-key",
|
|
209
|
+
* consumerSecret: "your-consumer-secret",
|
|
210
|
+
* accessToken: "your-access-token",
|
|
211
|
+
* accessTokenSecret: "your-access-token-secret"
|
|
212
|
+
* };
|
|
213
|
+
*
|
|
214
|
+
* const authProvider = getIntegrationAuthProvider(config);
|
|
215
|
+
*
|
|
216
|
+
* // Get OAuth headers for a REST API call
|
|
217
|
+
* const headers = authProvider.getHeaders("GET", "https://your-store.com/rest/V1/products");
|
|
218
|
+
* console.log(headers); // { Authorization: "OAuth oauth_consumer_key=..., oauth_signature=..." }
|
|
219
|
+
*
|
|
220
|
+
* // Can also be used with URL objects
|
|
221
|
+
* const url = new URL("https://your-store.com/rest/V1/customers");
|
|
222
|
+
* const postHeaders = authProvider.getHeaders("POST", url);
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
63
225
|
declare function getIntegrationAuthProvider(authParams: IntegrationAuthParams): IntegrationAuthProvider;
|
|
64
226
|
//#endregion
|
|
65
|
-
export { IMS_AUTH_ENV, ImsAuthEnv, ImsAuthParams, ImsAuthProvider, IntegrationAuthParams, IntegrationAuthProvider, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };
|
|
227
|
+
export { IMS_AUTH_ENV, type ImsAuthEnv, type ImsAuthParams, type ImsAuthProvider, type IntegrationAuthParams, type IntegrationAuthProvider, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };
|
package/dist/es/index.js
CHANGED
|
@@ -1,55 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
5
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
7
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
11
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*/
|
|
1
14
|
import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core/error";
|
|
2
15
|
import { context, getToken } from "@adobe/aio-lib-ims";
|
|
3
16
|
import { array, email, enum as enum$1, instance, minLength, nonEmpty, nonOptional, object, optional, pipe, safeParse, string, transform, union, url } from "valibot";
|
|
4
|
-
import crypto from "
|
|
17
|
+
import crypto from "crypto";
|
|
5
18
|
import OAuth1a from "oauth-1.0a";
|
|
6
|
-
|
|
7
|
-
//#region source/lib/ims-auth/schema.ts
|
|
8
|
-
/**
|
|
9
|
-
* Creates a validation schema for a required IMS auth string parameter.
|
|
10
|
-
* @param name The name of the parameter for error messages.
|
|
11
|
-
* @returns A validation pipeline that ensures the parameter is a non-empty string.
|
|
12
|
-
*/
|
|
13
|
-
const imsAuthParameter = (name) => pipe(string(`Expected a string value for the IMS auth parameter ${name}`), nonEmpty(`Expected a non-empty string value for the IMS auth parameter ${name}`));
|
|
14
|
-
/**
|
|
15
|
-
* Creates a validation schema for an IMS auth string array parameter.
|
|
16
|
-
* @param name The name of the parameter for error messages.
|
|
17
|
-
* @returns A validation pipeline that ensures the parameter is an array of strings.
|
|
18
|
-
*/
|
|
19
|
-
const stringArray = (name) => {
|
|
20
|
-
return pipe(array(string(), `Expected a stringified JSON array value for the IMS auth parameter ${name}`));
|
|
21
|
-
};
|
|
22
|
-
/** The environments accepted by the IMS auth service. */
|
|
23
|
-
const IMS_AUTH_ENV = {
|
|
19
|
+
const imsAuthParameter = (name) => pipe(string(`Expected a string value for the IMS auth parameter ${name}`), nonEmpty(`Expected a non-empty string value for the IMS auth parameter ${name}`)), stringArray = (name) => pipe(array(string(), `Expected a string array value for the IMS auth parameter ${name}`)), IMS_AUTH_ENV = {
|
|
24
20
|
PROD: "prod",
|
|
25
21
|
STAGE: "stage"
|
|
26
|
-
}
|
|
27
|
-
/** Validation schema for IMS auth environment values. */
|
|
28
|
-
const ImsAuthEnvSchema = enum$1(IMS_AUTH_ENV);
|
|
29
|
-
/** Defines the schema to validate the necessary parameters for the IMS auth service. */
|
|
30
|
-
const ImsAuthParamsSchema = object({
|
|
22
|
+
}, ImsAuthEnvSchema = enum$1(IMS_AUTH_ENV), ImsAuthParamsSchema = object({
|
|
31
23
|
clientId: imsAuthParameter("clientId"),
|
|
32
24
|
clientSecrets: pipe(stringArray("clientSecrets"), minLength(1, "Expected at least one client secret for IMS auth")),
|
|
33
25
|
technicalAccountId: imsAuthParameter("technicalAccountId"),
|
|
34
26
|
technicalAccountEmail: pipe(string("Expected a string value for the IMS auth parameter technicalAccountEmail"), email("Expected a valid email format for technicalAccountEmail")),
|
|
35
27
|
imsOrgId: imsAuthParameter("imsOrgId"),
|
|
36
28
|
environment: pipe(optional(ImsAuthEnvSchema, IMS_AUTH_ENV.PROD)),
|
|
37
|
-
context: pipe(optional(string()
|
|
29
|
+
context: pipe(optional(string())),
|
|
38
30
|
scopes: pipe(stringArray("scopes"), minLength(1, "Expected at least one scope for IMS auth"))
|
|
39
31
|
});
|
|
40
|
-
|
|
41
|
-
//#endregion
|
|
42
|
-
//#region source/lib/ims-auth/provider.ts
|
|
43
|
-
/**
|
|
44
|
-
* Converts IMS auth configuration properties to snake_case format.
|
|
45
|
-
* @param config The IMS auth configuration with camelCase properties.
|
|
46
|
-
* @returns The configuration with snake_case properties.
|
|
47
|
-
*/
|
|
48
32
|
function toImsAuthConfig(config) {
|
|
49
33
|
return {
|
|
50
34
|
scopes: config.scopes,
|
|
51
35
|
env: config?.environment ?? "prod",
|
|
52
|
-
context: config.context,
|
|
36
|
+
context: config.context ?? "aio-commerce-lib-auth-creds",
|
|
53
37
|
client_id: config.clientId,
|
|
54
38
|
client_secrets: config.clientSecrets,
|
|
55
39
|
technical_account_id: config.technicalAccountId,
|
|
@@ -57,90 +41,16 @@ function toImsAuthConfig(config) {
|
|
|
57
41
|
ims_org_id: config.imsOrgId
|
|
58
42
|
};
|
|
59
43
|
}
|
|
60
|
-
/**
|
|
61
|
-
* Asserts the provided configuration for an Adobe IMS authentication provider. {@link ImsAuthParams}
|
|
62
|
-
* {@link ImsAuthProvider}
|
|
63
|
-
* @param config {Record<PropertyKey, unknown>} The configuration to validate.
|
|
64
|
-
* @throws {CommerceSdkValidationError} If the configuration is invalid.
|
|
65
|
-
* @example
|
|
66
|
-
* ```typescript
|
|
67
|
-
* const config = {
|
|
68
|
-
* clientId: "your-client-id",
|
|
69
|
-
* clientSecrets: ["your-client-secret"],
|
|
70
|
-
* technicalAccountId: "your-technical-account-id",
|
|
71
|
-
* technicalAccountEmail: "your-account@example.com",
|
|
72
|
-
* imsOrgId: "your-ims-org-id@AdobeOrg",
|
|
73
|
-
* scopes: ["AdobeID", "openid"],
|
|
74
|
-
* environment: "prod", // or "stage"
|
|
75
|
-
* context: "my-app-context"
|
|
76
|
-
* };
|
|
77
|
-
*
|
|
78
|
-
* // This will validate the config and throw if invalid
|
|
79
|
-
* assertImsAuthParams(config);
|
|
80
|
-
*```
|
|
81
|
-
* @example
|
|
82
|
-
* ```typescript
|
|
83
|
-
* // Example of a failing assert:
|
|
84
|
-
* try {
|
|
85
|
-
* assertImsAuthParams({
|
|
86
|
-
* clientId: "valid-client-id",
|
|
87
|
-
* // Missing required fields like clientSecrets, technicalAccountId, etc.
|
|
88
|
-
* });
|
|
89
|
-
* } catch (error) {
|
|
90
|
-
* console.error(error.message); // "Invalid ImsAuthProvider configuration"
|
|
91
|
-
* console.error(error.issues); // Array of validation issues
|
|
92
|
-
* }
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
44
|
function assertImsAuthParams(config) {
|
|
96
|
-
|
|
45
|
+
let result = safeParse(ImsAuthParamsSchema, config);
|
|
97
46
|
if (!result.success) throw new CommerceSdkValidationError("Invalid ImsAuthProvider configuration", { issues: result.issues });
|
|
98
47
|
}
|
|
99
|
-
/**
|
|
100
|
-
* Creates an {@link ImsAuthProvider} based on the provided configuration.
|
|
101
|
-
* @param config An {@link ImsAuthParams} parameter that contains the configuration for the IMS auth provider.
|
|
102
|
-
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
103
|
-
* @example
|
|
104
|
-
* ```typescript
|
|
105
|
-
* const config = {
|
|
106
|
-
* clientId: "your-client-id",
|
|
107
|
-
* clientSecrets: ["your-client-secret"],
|
|
108
|
-
* technicalAccountId: "your-technical-account-id",
|
|
109
|
-
* technicalAccountEmail: "your-account@example.com",
|
|
110
|
-
* imsOrgId: "your-ims-org-id@AdobeOrg",
|
|
111
|
-
* scopes: ["AdobeID", "openid"],
|
|
112
|
-
* environment: "prod",
|
|
113
|
-
* context: "my-app-context"
|
|
114
|
-
* };
|
|
115
|
-
*
|
|
116
|
-
* const authProvider = getImsAuthProvider(config);
|
|
117
|
-
*
|
|
118
|
-
* // Get access token
|
|
119
|
-
* const token = await authProvider.getAccessToken();
|
|
120
|
-
* console.log(token); // "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."
|
|
121
|
-
*
|
|
122
|
-
* // Get headers for API requests
|
|
123
|
-
* const headers = await authProvider.getHeaders();
|
|
124
|
-
* console.log(headers);
|
|
125
|
-
* // {
|
|
126
|
-
* // Authorization: "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
|
|
127
|
-
* // "x-api-key": "your-client-id"
|
|
128
|
-
* // }
|
|
129
|
-
*
|
|
130
|
-
* // Use headers in API calls
|
|
131
|
-
* const response = await fetch('https://api.adobe.io/some-endpoint', {
|
|
132
|
-
* headers: await authProvider.getHeaders()
|
|
133
|
-
* });
|
|
134
|
-
* ```
|
|
135
|
-
*/
|
|
136
48
|
function getImsAuthProvider(authParams) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
await context.set(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const getHeaders = async () => {
|
|
143
|
-
const accessToken = await getAccessToken();
|
|
49
|
+
let getAccessToken = async () => {
|
|
50
|
+
let imsAuthConfig = toImsAuthConfig(authParams);
|
|
51
|
+
return await context.set(imsAuthConfig.context, imsAuthConfig), getToken(imsAuthConfig.context, {});
|
|
52
|
+
}, getHeaders = async () => {
|
|
53
|
+
let accessToken = await getAccessToken();
|
|
144
54
|
return {
|
|
145
55
|
Authorization: `Bearer ${accessToken}`,
|
|
146
56
|
"x-api-key": authParams.clientId
|
|
@@ -151,115 +61,36 @@ function getImsAuthProvider(authParams) {
|
|
|
151
61
|
getHeaders
|
|
152
62
|
};
|
|
153
63
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
//#region source/lib/integration-auth/schema.ts
|
|
157
|
-
/**
|
|
158
|
-
* Creates a validation schema for a required Commerce Integration string parameter.
|
|
159
|
-
* @param name The name of the parameter for error messages.
|
|
160
|
-
* @returns A validation pipeline that ensures the parameter is a non-empty string.
|
|
161
|
-
*/
|
|
162
|
-
const integrationAuthParameter = (name) => pipe(string(`Expected a string value for the Commerce Integration parameter ${name}`), nonEmpty(`Expected a non-empty string value for the Commerce Integration parameter ${name}`));
|
|
163
|
-
/** Validation schema for the Adobe Commerce endpoint base URL. */
|
|
164
|
-
const BaseUrlSchema = pipe(string("Expected a string for the Adobe Commerce endpoint"), nonEmpty("Expected a non-empty string for the Adobe Commerce endpoint"), url("Expected a valid url for the Adobe Commerce endpoint"));
|
|
165
|
-
/** Validation schema that accepts either a URL string or URL instance and normalizes to string. */
|
|
166
|
-
const UrlSchema = pipe(union([BaseUrlSchema, instance(URL)]), transform((url$1) => {
|
|
167
|
-
if (url$1 instanceof URL) return url$1.toString();
|
|
168
|
-
return url$1;
|
|
169
|
-
}));
|
|
170
|
-
/**
|
|
171
|
-
* The schema for the Commerce Integration parameters.
|
|
172
|
-
* This is used to validate the parameters passed to the Commerce Integration provider.
|
|
173
|
-
*/
|
|
64
|
+
const integrationAuthParameter = (name) => pipe(string(`Expected a string value for the Commerce Integration parameter ${name}`), nonEmpty(`Expected a non-empty string value for the Commerce Integration parameter ${name}`)), BaseUrlSchema = pipe(string("Expected a string for the Adobe Commerce endpoint"), nonEmpty("Expected a non-empty string for the Adobe Commerce endpoint"), url("Expected a valid url for the Adobe Commerce endpoint"));
|
|
65
|
+
pipe(union([BaseUrlSchema, instance(URL)]), transform((url$1) => url$1 instanceof URL ? url$1.toString() : url$1));
|
|
174
66
|
const IntegrationAuthParamsSchema = nonOptional(object({
|
|
175
67
|
consumerKey: integrationAuthParameter("consumerKey"),
|
|
176
68
|
consumerSecret: integrationAuthParameter("consumerSecret"),
|
|
177
69
|
accessToken: integrationAuthParameter("accessToken"),
|
|
178
70
|
accessTokenSecret: integrationAuthParameter("accessTokenSecret")
|
|
179
71
|
}));
|
|
180
|
-
|
|
181
|
-
//#endregion
|
|
182
|
-
//#region source/lib/integration-auth/provider.ts
|
|
183
|
-
/**
|
|
184
|
-
* Asserts the provided configuration for an Adobe Commerce integration authentication provider. {@link IntegrationAuthParams}
|
|
185
|
-
* {@link IntegrationAuthProvider}
|
|
186
|
-
* @param config {Record<PropertyKey, unknown>} The configuration to validate.
|
|
187
|
-
* @throws {CommerceSdkValidationError} If the configuration is invalid.
|
|
188
|
-
* @example
|
|
189
|
-
* ```typescript
|
|
190
|
-
* const config = {
|
|
191
|
-
* consumerKey: "your-consumer-key",
|
|
192
|
-
* consumerSecret: "your-consumer-secret",
|
|
193
|
-
* accessToken: "your-access-token",
|
|
194
|
-
* accessTokenSecret: "your-access-token-secret"
|
|
195
|
-
* };
|
|
196
|
-
*
|
|
197
|
-
* // This will validate the config and throw if invalid
|
|
198
|
-
* assertIntegrationAuthParams(config);
|
|
199
|
-
* ```
|
|
200
|
-
* @example
|
|
201
|
-
* ```typescript
|
|
202
|
-
* // Example of a failing assert:
|
|
203
|
-
* try {
|
|
204
|
-
* assertIntegrationAuthParams({
|
|
205
|
-
* consumerKey: "valid-consumer-key",
|
|
206
|
-
* // Missing required fields like consumerSecret, accessToken, accessTokenSecret
|
|
207
|
-
* });
|
|
208
|
-
* } catch (error) {
|
|
209
|
-
* console.error(error.message); // "Invalid IntegrationAuthProvider configuration"
|
|
210
|
-
* console.error(error.issues); // Array of validation issues
|
|
211
|
-
* }
|
|
212
|
-
* ```
|
|
213
|
-
*/
|
|
214
72
|
function assertIntegrationAuthParams(config) {
|
|
215
|
-
|
|
73
|
+
let result = safeParse(IntegrationAuthParamsSchema, config);
|
|
216
74
|
if (!result.success) throw new CommerceSdkValidationError("Invalid IntegrationAuthProvider configuration", { issues: result.issues });
|
|
217
75
|
}
|
|
218
|
-
/**
|
|
219
|
-
* Creates an {@link IntegrationAuthProvider} based on the provided configuration.
|
|
220
|
-
* @param config {IntegrationAuthParams} The configuration for the integration.
|
|
221
|
-
* @returns An {@link IntegrationAuthProvider} instance that can be used to get auth headers.
|
|
222
|
-
* @example
|
|
223
|
-
* ```typescript
|
|
224
|
-
* const config = {
|
|
225
|
-
* consumerKey: "your-consumer-key",
|
|
226
|
-
* consumerSecret: "your-consumer-secret",
|
|
227
|
-
* accessToken: "your-access-token",
|
|
228
|
-
* accessTokenSecret: "your-access-token-secret"
|
|
229
|
-
* };
|
|
230
|
-
*
|
|
231
|
-
* const authProvider = getIntegrationAuthProvider(config);
|
|
232
|
-
*
|
|
233
|
-
* // Get OAuth headers for a REST API call
|
|
234
|
-
* const headers = authProvider.getHeaders("GET", "https://your-store.com/rest/V1/products");
|
|
235
|
-
* console.log(headers); // { Authorization: "OAuth oauth_consumer_key=..., oauth_signature=..." }
|
|
236
|
-
*
|
|
237
|
-
* // Can also be used with URL objects
|
|
238
|
-
* const url = new URL("https://your-store.com/rest/V1/customers");
|
|
239
|
-
* const postHeaders = authProvider.getHeaders("POST", url);
|
|
240
|
-
* ```
|
|
241
|
-
*/
|
|
242
76
|
function getIntegrationAuthProvider(authParams) {
|
|
243
|
-
|
|
77
|
+
let oauth = new OAuth1a({
|
|
244
78
|
consumer: {
|
|
245
79
|
key: authParams.consumerKey,
|
|
246
80
|
secret: authParams.consumerSecret
|
|
247
81
|
},
|
|
248
82
|
signature_method: "HMAC-SHA256",
|
|
249
83
|
hash_function: (baseString, key) => crypto.createHmac("sha256", key).update(baseString).digest("base64")
|
|
250
|
-
})
|
|
251
|
-
const oauthToken = {
|
|
84
|
+
}), oauthToken = {
|
|
252
85
|
key: authParams.accessToken,
|
|
253
86
|
secret: authParams.accessTokenSecret
|
|
254
87
|
};
|
|
255
88
|
return { getHeaders: (method, url$1) => {
|
|
256
|
-
|
|
89
|
+
let urlString = url$1 instanceof URL ? url$1.toString() : url$1;
|
|
257
90
|
return oauth.toHeader(oauth.authorize({
|
|
258
91
|
url: urlString,
|
|
259
92
|
method
|
|
260
93
|
}, oauthToken));
|
|
261
94
|
} };
|
|
262
95
|
}
|
|
263
|
-
|
|
264
|
-
//#endregion
|
|
265
|
-
export { IMS_AUTH_ENV, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };
|
|
96
|
+
export { IMS_AUTH_ENV, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/aio-commerce-lib-auth",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.3.0",
|
|
5
|
-
"private": false,
|
|
6
4
|
"author": "Adobe Inc.",
|
|
5
|
+
"version": "0.3.2",
|
|
6
|
+
"private": false,
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=20 <=24"
|
|
9
9
|
},
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"description": "Authentication utilities for Adobe Commerce apps deployed in Adobe App Builder.",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
24
|
-
"url": "https://github.com/adobe/aio-commerce-sdk.git",
|
|
24
|
+
"url": "git+https://github.com/adobe/aio-commerce-sdk.git",
|
|
25
25
|
"directory": "packages/aio-commerce-lib-auth"
|
|
26
26
|
},
|
|
27
27
|
"main": "./dist/cjs/index.cjs",
|
|
@@ -51,25 +51,29 @@
|
|
|
51
51
|
"ansis": "^4.1.0",
|
|
52
52
|
"oauth-1.0a": "^2.2.6",
|
|
53
53
|
"valibot": "^1.1.0",
|
|
54
|
-
"@adobe/aio-commerce-lib-core": "0.
|
|
54
|
+
"@adobe/aio-commerce-lib-core": "0.4.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"
|
|
57
|
+
"@aio-commerce-sdk/config-tsdown": "1.0.0",
|
|
58
|
+
"@aio-commerce-sdk/config-typedoc": "1.0.0",
|
|
58
59
|
"@aio-commerce-sdk/config-typescript": "1.0.0",
|
|
59
|
-
"@aio-commerce-sdk/config-
|
|
60
|
+
"@aio-commerce-sdk/config-vitest": "1.0.0"
|
|
60
61
|
},
|
|
61
62
|
"sideEffects": false,
|
|
62
63
|
"scripts": {
|
|
63
64
|
"build": "tsdown",
|
|
64
|
-
"
|
|
65
|
-
"assist
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"format
|
|
69
|
-
"
|
|
70
|
-
"
|
|
65
|
+
"docs": "typedoc && prettier --write '**/*.md'",
|
|
66
|
+
"assist": "biome check --formatter-enabled=false --linter-enabled=false --assist-enabled=true --no-errors-on-unmatched",
|
|
67
|
+
"assist:apply": "biome check --write --formatter-enabled=false --linter-enabled=false --assist-enabled=true --no-errors-on-unmatched",
|
|
68
|
+
"check:ci": "biome ci --formatter-enabled=true --linter-enabled=true --assist-enabled=true --no-errors-on-unmatched",
|
|
69
|
+
"format": "biome format --write --no-errors-on-unmatched",
|
|
70
|
+
"format:markdown": "prettier --no-error-on-unmatched-pattern --write '**/*.md' \"!**/{CODE_OF_CONDUCT.md,COPYRIGHT,LICENSE,SECURITY.md,CONTRIBUTING.md}\"",
|
|
71
|
+
"format:check": "biome format --no-errors-on-unmatched",
|
|
72
|
+
"lint": "biome lint --no-errors-on-unmatched",
|
|
73
|
+
"lint:fix": "biome lint --write --no-errors-on-unmatched",
|
|
71
74
|
"typecheck": "tsc --noEmit && echo '✅ No type errors found.'",
|
|
72
|
-
"test": "vitest run",
|
|
73
|
-
"test:watch": "vitest"
|
|
75
|
+
"test": "vitest run --coverage",
|
|
76
|
+
"test:watch": "vitest --coverage",
|
|
77
|
+
"test:ui": "vitest --ui"
|
|
74
78
|
}
|
|
75
79
|
}
|