@adobe/aio-commerce-lib-auth 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +90 -79
- package/dist/cjs/index.cjs +186 -122
- package/dist/cjs/index.d.cts +34 -57
- package/dist/es/index.d.ts +30 -53
- package/dist/es/index.js +185 -121
- package/package.json +9 -3
- package/.turbo/turbo-build.log +0 -18
- package/source/index.ts +0 -35
- package/source/lib/ims-auth/provider.ts +0 -160
- package/source/lib/ims-auth/schema.ts +0 -87
- package/source/lib/integration-auth/provider.ts +0 -145
- package/source/lib/integration-auth/schema.ts +0 -87
- package/test/ims-auth.test.ts +0 -147
- package/test/integration-auth.test.ts +0 -124
- package/tsconfig.json +0 -15
- package/tsdown.config.ts +0 -7
- package/vitest.config.ts +0 -16
package/dist/es/index.js
CHANGED
|
@@ -1,38 +1,55 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core/error";
|
|
2
2
|
import { context, getToken } from "@adobe/aio-lib-ims";
|
|
3
|
-
import { array, enum as enum$1, instance,
|
|
3
|
+
import { array, email, enum as enum$1, instance, minLength, nonEmpty, nonOptional, object, optional, pipe, safeParse, string, transform, union, url } from "valibot";
|
|
4
4
|
import crypto from "node:crypto";
|
|
5
5
|
import OAuth1a from "oauth-1.0a";
|
|
6
6
|
|
|
7
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
|
+
*/
|
|
8
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}`));
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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}`));
|
|
12
21
|
};
|
|
13
22
|
/** The environments accepted by the IMS auth service. */
|
|
14
23
|
const IMS_AUTH_ENV = {
|
|
15
24
|
PROD: "prod",
|
|
16
25
|
STAGE: "stage"
|
|
17
26
|
};
|
|
27
|
+
/** Validation schema for IMS auth environment values. */
|
|
18
28
|
const ImsAuthEnvSchema = enum$1(IMS_AUTH_ENV);
|
|
19
29
|
/** Defines the schema to validate the necessary parameters for the IMS auth service. */
|
|
20
30
|
const ImsAuthParamsSchema = object({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
clientId: imsAuthParameter("clientId"),
|
|
32
|
+
clientSecrets: pipe(stringArray("clientSecrets"), minLength(1, "Expected at least one client secret for IMS auth")),
|
|
33
|
+
technicalAccountId: imsAuthParameter("technicalAccountId"),
|
|
34
|
+
technicalAccountEmail: pipe(string("Expected a string value for the IMS auth parameter technicalAccountEmail"), email("Expected a valid email format for technicalAccountEmail")),
|
|
35
|
+
imsOrgId: imsAuthParameter("imsOrgId"),
|
|
36
|
+
environment: pipe(optional(ImsAuthEnvSchema, IMS_AUTH_ENV.PROD)),
|
|
37
|
+
context: pipe(optional(string(), "aio-commerce-sdk-creds")),
|
|
38
|
+
scopes: pipe(stringArray("scopes"), minLength(1, "Expected at least one scope for IMS auth"))
|
|
29
39
|
});
|
|
30
40
|
|
|
31
41
|
//#endregion
|
|
32
42
|
//#region source/lib/ims-auth/provider.ts
|
|
33
|
-
|
|
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
|
+
function toImsAuthConfig(config) {
|
|
34
49
|
return {
|
|
35
|
-
|
|
50
|
+
scopes: config.scopes,
|
|
51
|
+
env: config?.environment ?? "prod",
|
|
52
|
+
context: config.context,
|
|
36
53
|
client_id: config.clientId,
|
|
37
54
|
client_secrets: config.clientSecrets,
|
|
38
55
|
technical_account_id: config.technicalAccountId,
|
|
@@ -40,90 +57,112 @@ function snakeCaseImsAuthConfig(config) {
|
|
|
40
57
|
ims_org_id: config.imsOrgId
|
|
41
58
|
};
|
|
42
59
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
+
function assertImsAuthParams(config) {
|
|
96
|
+
const result = safeParse(ImsAuthParamsSchema, config);
|
|
97
|
+
if (!result.success) throw new CommerceSdkValidationError("Invalid ImsAuthProvider configuration", { issues: result.issues });
|
|
76
98
|
}
|
|
77
99
|
/**
|
|
78
100
|
* Creates an {@link ImsAuthProvider} based on the provided configuration.
|
|
79
|
-
* @param config
|
|
101
|
+
* @param config An {@link ImsAuthParams} parameter that contains the configuration for the IMS auth provider.
|
|
80
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
|
+
* ```
|
|
81
135
|
*/
|
|
82
|
-
function getImsAuthProvider(
|
|
136
|
+
function getImsAuthProvider(authParams) {
|
|
83
137
|
const getAccessToken = async () => {
|
|
84
|
-
const
|
|
85
|
-
await context.set(
|
|
86
|
-
return
|
|
138
|
+
const imsAuthConfig = toImsAuthConfig(authParams);
|
|
139
|
+
await context.set(authParams.context, imsAuthConfig);
|
|
140
|
+
return getToken(authParams.context, {});
|
|
87
141
|
};
|
|
88
142
|
const getHeaders = async () => {
|
|
89
|
-
const
|
|
90
|
-
return
|
|
143
|
+
const accessToken = await getAccessToken();
|
|
144
|
+
return {
|
|
91
145
|
Authorization: `Bearer ${accessToken}`,
|
|
92
|
-
"x-api-key":
|
|
93
|
-
}
|
|
146
|
+
"x-api-key": authParams.clientId
|
|
147
|
+
};
|
|
94
148
|
};
|
|
95
149
|
return {
|
|
96
150
|
getAccessToken,
|
|
97
151
|
getHeaders
|
|
98
152
|
};
|
|
99
153
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Tries to create an {@link ImsAuthProvider} based on the provided parameters.
|
|
102
|
-
* @param params The parameters required to create the IMS Auth Provider.
|
|
103
|
-
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
104
|
-
*/
|
|
105
|
-
function tryGetImsAuthProvider(params) {
|
|
106
|
-
const validation = safeParse(ImsAuthParamsSchema, params);
|
|
107
|
-
if (!validation.success) return err(makeImsAuthValidationError("Failed to validate the provided IMS parameters", validation.issues));
|
|
108
|
-
return ok(getImsAuthProvider(fromParams$1(validation.output)));
|
|
109
|
-
}
|
|
110
154
|
|
|
111
155
|
//#endregion
|
|
112
156
|
//#region source/lib/integration-auth/schema.ts
|
|
113
157
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
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.
|
|
116
161
|
*/
|
|
117
|
-
const AllowedHttpMethod = [
|
|
118
|
-
"GET",
|
|
119
|
-
"POST",
|
|
120
|
-
"PUT",
|
|
121
|
-
"PATCH",
|
|
122
|
-
"DELETE"
|
|
123
|
-
];
|
|
124
|
-
const HttpMethodSchema = picklist(AllowedHttpMethod);
|
|
125
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. */
|
|
126
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. */
|
|
127
166
|
const UrlSchema = pipe(union([BaseUrlSchema, instance(URL)]), transform((url$1) => {
|
|
128
167
|
if (url$1 instanceof URL) return url$1.toString();
|
|
129
168
|
return url$1;
|
|
@@ -133,69 +172,94 @@ const UrlSchema = pipe(union([BaseUrlSchema, instance(URL)]), transform((url$1)
|
|
|
133
172
|
* This is used to validate the parameters passed to the Commerce Integration provider.
|
|
134
173
|
*/
|
|
135
174
|
const IntegrationAuthParamsSchema = nonOptional(object({
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
175
|
+
consumerKey: integrationAuthParameter("consumerKey"),
|
|
176
|
+
consumerSecret: integrationAuthParameter("consumerSecret"),
|
|
177
|
+
accessToken: integrationAuthParameter("accessToken"),
|
|
178
|
+
accessTokenSecret: integrationAuthParameter("accessTokenSecret")
|
|
140
179
|
}));
|
|
141
180
|
|
|
142
181
|
//#endregion
|
|
143
182
|
//#region source/lib/integration-auth/provider.ts
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
+
function assertIntegrationAuthParams(config) {
|
|
215
|
+
const result = safeParse(IntegrationAuthParamsSchema, config);
|
|
216
|
+
if (!result.success) throw new CommerceSdkValidationError("Invalid IntegrationAuthProvider configuration", { issues: result.issues });
|
|
158
217
|
}
|
|
159
218
|
/**
|
|
160
219
|
* Creates an {@link IntegrationAuthProvider} based on the provided configuration.
|
|
161
|
-
* @param config The configuration for the integration.
|
|
220
|
+
* @param config {IntegrationAuthParams} The configuration for the integration.
|
|
162
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
|
+
* ```
|
|
163
241
|
*/
|
|
164
|
-
function getIntegrationAuthProvider(
|
|
242
|
+
function getIntegrationAuthProvider(authParams) {
|
|
165
243
|
const oauth = new OAuth1a({
|
|
166
244
|
consumer: {
|
|
167
|
-
key:
|
|
168
|
-
secret:
|
|
245
|
+
key: authParams.consumerKey,
|
|
246
|
+
secret: authParams.consumerSecret
|
|
169
247
|
},
|
|
170
248
|
signature_method: "HMAC-SHA256",
|
|
171
249
|
hash_function: (baseString, key) => crypto.createHmac("sha256", key).update(baseString).digest("base64")
|
|
172
250
|
});
|
|
173
251
|
const oauthToken = {
|
|
174
|
-
key:
|
|
175
|
-
secret:
|
|
252
|
+
key: authParams.accessToken,
|
|
253
|
+
secret: authParams.accessTokenSecret
|
|
176
254
|
};
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const headers = oauth.toHeader(oauth.authorize({
|
|
182
|
-
url: finalUrl,
|
|
255
|
+
return { getHeaders: (method, url$1) => {
|
|
256
|
+
const urlString = url$1 instanceof URL ? url$1.toString() : url$1;
|
|
257
|
+
return oauth.toHeader(oauth.authorize({
|
|
258
|
+
url: urlString,
|
|
183
259
|
method
|
|
184
260
|
}, oauthToken));
|
|
185
|
-
|
|
186
|
-
};
|
|
187
|
-
return { getHeaders };
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Tries to create an {@link IntegrationAuthProvider} based on the provided parameters.
|
|
191
|
-
* @param params The parameters required for integration authentication.
|
|
192
|
-
* @returns An {@link IntegrationAuthProvider} instance that can be used to get auth headers.
|
|
193
|
-
*/
|
|
194
|
-
function tryGetIntegrationAuthProvider(params) {
|
|
195
|
-
const validation = safeParse(IntegrationAuthParamsSchema, params);
|
|
196
|
-
if (!validation.success) return err(makeIntegrationAuthValidationError("Failed to validate the provided integration parameters", validation.issues));
|
|
197
|
-
return ok(getIntegrationAuthProvider(fromParams(validation.output)));
|
|
261
|
+
} };
|
|
198
262
|
}
|
|
199
263
|
|
|
200
264
|
//#endregion
|
|
201
|
-
export { IMS_AUTH_ENV,
|
|
265
|
+
export { IMS_AUTH_ENV, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/aio-commerce-lib-auth",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Adobe Inc.",
|
|
7
7
|
"engines": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"main": "./dist/cjs/index.cjs",
|
|
28
28
|
"module": "./dist/es/index.js",
|
|
29
|
-
"types": "./dist/
|
|
29
|
+
"types": "./dist/cjs/index.d.cts",
|
|
30
30
|
"exports": {
|
|
31
31
|
".": {
|
|
32
32
|
"import": {
|
|
@@ -40,12 +40,18 @@
|
|
|
40
40
|
},
|
|
41
41
|
"./package.json": "./package.json"
|
|
42
42
|
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"package.json",
|
|
46
|
+
"CHANGELOG.md",
|
|
47
|
+
"README.md"
|
|
48
|
+
],
|
|
43
49
|
"dependencies": {
|
|
44
50
|
"@adobe/aio-lib-ims": "^8.1.0",
|
|
45
51
|
"ansis": "^4.1.0",
|
|
46
52
|
"oauth-1.0a": "^2.2.6",
|
|
47
53
|
"valibot": "^1.1.0",
|
|
48
|
-
"@adobe/aio-commerce-lib-core": "0.
|
|
54
|
+
"@adobe/aio-commerce-lib-core": "0.3.0"
|
|
49
55
|
},
|
|
50
56
|
"devDependencies": {
|
|
51
57
|
"vitest": "^3.2.4",
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
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
|
-
> tsdown
|
|
4
|
-
|
|
5
|
-
[34mℹ[39m tsdown [2mv0.12.9[22m powered by rolldown [2mv1.0.0-beta.24[22m
|
|
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
|
-
[34mℹ[39m entry: [34msource/index.ts[39m
|
|
8
|
-
[34mℹ[39m target: [34mnode22.0.0[39m
|
|
9
|
-
[34mℹ[39m tsconfig: [34mtsconfig.json[39m
|
|
10
|
-
[34mℹ[39m Build start
|
|
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/source/index.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
export {
|
|
14
|
-
getImsAuthProvider,
|
|
15
|
-
type ImsAuthConfig,
|
|
16
|
-
type ImsAuthError,
|
|
17
|
-
type ImsAuthProvider,
|
|
18
|
-
tryGetImsAuthProvider,
|
|
19
|
-
} from "./lib/ims-auth/provider";
|
|
20
|
-
|
|
21
|
-
export {
|
|
22
|
-
IMS_AUTH_ENV,
|
|
23
|
-
type ImsAuthEnv,
|
|
24
|
-
type ImsAuthParams,
|
|
25
|
-
} from "./lib/ims-auth/schema";
|
|
26
|
-
|
|
27
|
-
export {
|
|
28
|
-
getIntegrationAuthProvider,
|
|
29
|
-
type IntegrationAuthError,
|
|
30
|
-
type IntegrationAuthProvider,
|
|
31
|
-
type IntegrationConfig,
|
|
32
|
-
tryGetIntegrationAuthProvider,
|
|
33
|
-
} from "./lib/integration-auth/provider";
|
|
34
|
-
|
|
35
|
-
export type { IntegrationAuthParams } from "./lib/integration-auth/schema";
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type ErrorType,
|
|
3
|
-
err,
|
|
4
|
-
map,
|
|
5
|
-
ok,
|
|
6
|
-
type Result,
|
|
7
|
-
} from "@adobe/aio-commerce-lib-core/result";
|
|
8
|
-
|
|
9
|
-
import type { ValidationErrorType } from "@adobe/aio-commerce-lib-core/validation";
|
|
10
|
-
import { context, getToken } from "@adobe/aio-lib-ims";
|
|
11
|
-
import type { SnakeCasedProperties } from "type-fest";
|
|
12
|
-
import { type InferInput, type InferIssue, safeParse } from "valibot";
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
type ImsAuthEnv,
|
|
16
|
-
type ImsAuthParams,
|
|
17
|
-
ImsAuthParamsSchema,
|
|
18
|
-
} from "./schema";
|
|
19
|
-
|
|
20
|
-
type ImsAccessToken = string;
|
|
21
|
-
type ImsAuthHeader = "Authorization" | "x-api-key";
|
|
22
|
-
type ImsAuthHeaders = Record<ImsAuthHeader, string>;
|
|
23
|
-
|
|
24
|
-
/** Defines a validation error type for the IMS auth service. */
|
|
25
|
-
export type ImsAuthValidationError = ValidationErrorType<
|
|
26
|
-
"ImsAuthValidationError",
|
|
27
|
-
InferIssue<typeof ImsAuthParamsSchema>[]
|
|
28
|
-
>;
|
|
29
|
-
|
|
30
|
-
/** Defines an error type for the IMS auth service. */
|
|
31
|
-
export type ImsAuthError<TError = unknown> = ErrorType<
|
|
32
|
-
"ImsAuthError",
|
|
33
|
-
{
|
|
34
|
-
message: string;
|
|
35
|
-
error: TError;
|
|
36
|
-
}
|
|
37
|
-
>;
|
|
38
|
-
|
|
39
|
-
/** Defines the configuration options to create an {@link ImsAuthProvider}. */
|
|
40
|
-
export interface ImsAuthConfig {
|
|
41
|
-
clientId: string;
|
|
42
|
-
clientSecrets: string[];
|
|
43
|
-
technicalAccountId: string;
|
|
44
|
-
technicalAccountEmail: string;
|
|
45
|
-
imsOrgId: string;
|
|
46
|
-
scopes: string[];
|
|
47
|
-
environment: ImsAuthEnv;
|
|
48
|
-
context: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Defines an authentication provider for Adobe IMS. */
|
|
52
|
-
export interface ImsAuthProvider {
|
|
53
|
-
getAccessToken: () => Promise<Result<ImsAccessToken, ImsAuthError>>;
|
|
54
|
-
getHeaders: () => Promise<Result<ImsAuthHeaders, ImsAuthError>>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function snakeCaseImsAuthConfig(
|
|
58
|
-
config: ImsAuthConfig,
|
|
59
|
-
): SnakeCasedProperties<ImsAuthConfig> {
|
|
60
|
-
return {
|
|
61
|
-
...config,
|
|
62
|
-
client_id: config.clientId,
|
|
63
|
-
client_secrets: config.clientSecrets,
|
|
64
|
-
technical_account_id: config.technicalAccountId,
|
|
65
|
-
technical_account_email: config.technicalAccountEmail,
|
|
66
|
-
ims_org_id: config.imsOrgId,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function makeImsAuthValidationError(
|
|
71
|
-
message: string,
|
|
72
|
-
issues: InferIssue<typeof ImsAuthParamsSchema>[],
|
|
73
|
-
) {
|
|
74
|
-
return {
|
|
75
|
-
_tag: "ImsAuthValidationError",
|
|
76
|
-
message,
|
|
77
|
-
issues,
|
|
78
|
-
} satisfies ImsAuthValidationError;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function makeImsAuthError(message: string, error: unknown) {
|
|
82
|
-
return {
|
|
83
|
-
_tag: "ImsAuthError",
|
|
84
|
-
message,
|
|
85
|
-
error,
|
|
86
|
-
} satisfies ImsAuthError;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function fromParams(params: ImsAuthParams) {
|
|
90
|
-
return {
|
|
91
|
-
clientId: params.AIO_COMMERCE_IMS_CLIENT_ID,
|
|
92
|
-
clientSecrets: params.AIO_COMMERCE_IMS_CLIENT_SECRETS,
|
|
93
|
-
technicalAccountId: params.AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_ID,
|
|
94
|
-
technicalAccountEmail: params.AIO_COMMERCE_IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
95
|
-
imsOrgId: params.AIO_COMMERCE_IMS_IMS_ORG_ID,
|
|
96
|
-
scopes: params.AIO_COMMERCE_IMS_SCOPES,
|
|
97
|
-
environment: params.AIO_COMMERCE_IMS_ENV,
|
|
98
|
-
context: params.AIO_COMMERCE_IMS_CTX,
|
|
99
|
-
} satisfies ImsAuthConfig;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async function tryGetAccessToken(
|
|
103
|
-
contextName: string,
|
|
104
|
-
): Promise<Result<ImsAccessToken, ImsAuthError>> {
|
|
105
|
-
try {
|
|
106
|
-
const accessToken = await getToken(contextName, {});
|
|
107
|
-
return ok(accessToken);
|
|
108
|
-
} catch (error) {
|
|
109
|
-
return err(makeImsAuthError("Failed to retrieve IMS access token", error));
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Creates an {@link ImsAuthProvider} based on the provided configuration.
|
|
115
|
-
* @param config The configuration for the IMS Auth Provider.
|
|
116
|
-
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
117
|
-
*/
|
|
118
|
-
export function getImsAuthProvider(config: ImsAuthConfig): ImsAuthProvider {
|
|
119
|
-
const getAccessToken = async () => {
|
|
120
|
-
const snakeCasedConfig = snakeCaseImsAuthConfig(config);
|
|
121
|
-
|
|
122
|
-
await context.set(config.context, snakeCasedConfig);
|
|
123
|
-
return tryGetAccessToken(config.context);
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const getHeaders = async () => {
|
|
127
|
-
const result = await getAccessToken();
|
|
128
|
-
return map(result, (accessToken) => ({
|
|
129
|
-
Authorization: `Bearer ${accessToken}`,
|
|
130
|
-
"x-api-key": config.clientId,
|
|
131
|
-
}));
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
getAccessToken,
|
|
136
|
-
getHeaders,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Tries to create an {@link ImsAuthProvider} based on the provided parameters.
|
|
142
|
-
* @param params The parameters required to create the IMS Auth Provider.
|
|
143
|
-
* @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers.
|
|
144
|
-
*/
|
|
145
|
-
export function tryGetImsAuthProvider(
|
|
146
|
-
params: InferInput<typeof ImsAuthParamsSchema>,
|
|
147
|
-
): Result<ImsAuthProvider, ImsAuthValidationError> {
|
|
148
|
-
const validation = safeParse(ImsAuthParamsSchema, params);
|
|
149
|
-
|
|
150
|
-
if (!validation.success) {
|
|
151
|
-
return err(
|
|
152
|
-
makeImsAuthValidationError(
|
|
153
|
-
"Failed to validate the provided IMS parameters",
|
|
154
|
-
validation.issues,
|
|
155
|
-
),
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return ok(getImsAuthProvider(fromParams(validation.output)));
|
|
160
|
-
}
|