@adobe/aio-commerce-lib-auth
Version:
Authentication utilities for Adobe Commerce apps deployed in Adobe App Builder.
97 lines (96 loc) • 4.98 kB
JavaScript
/**
* @license
*
* Copyright 2025 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core/error";
import aioLibIms from "@adobe/aio-lib-ims";
import { array, email, enum as enum$1, instance, minLength, nonEmpty, nonOptional, object, optional, pipe, safeParse, string, transform, union, url } from "valibot";
import crypto from "crypto";
import OAuth1a from "oauth-1.0a";
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 = {
PROD: "prod",
STAGE: "stage"
}, ImsAuthEnvSchema = enum$1(IMS_AUTH_ENV), ImsAuthParamsSchema = object({
clientId: imsAuthParameter("clientId"),
clientSecrets: pipe(stringArray("clientSecrets"), minLength(1, "Expected at least one client secret for IMS auth")),
technicalAccountId: imsAuthParameter("technicalAccountId"),
technicalAccountEmail: pipe(string("Expected a string value for the IMS auth parameter technicalAccountEmail"), email("Expected a valid email format for technicalAccountEmail")),
imsOrgId: imsAuthParameter("imsOrgId"),
environment: pipe(optional(ImsAuthEnvSchema, IMS_AUTH_ENV.PROD)),
context: pipe(optional(string())),
scopes: pipe(stringArray("scopes"), minLength(1, "Expected at least one scope for IMS auth"))
}), { context, getToken } = aioLibIms;
function toImsAuthConfig(config) {
return {
scopes: config.scopes,
env: config?.environment ?? "prod",
context: config.context ?? "aio-commerce-lib-auth-creds",
client_id: config.clientId,
client_secrets: config.clientSecrets,
technical_account_id: config.technicalAccountId,
technical_account_email: config.technicalAccountEmail,
ims_org_id: config.imsOrgId
};
}
function assertImsAuthParams(config) {
let result = safeParse(ImsAuthParamsSchema, config);
if (!result.success) throw new CommerceSdkValidationError("Invalid ImsAuthProvider configuration", { issues: result.issues });
}
function getImsAuthProvider(authParams) {
let getAccessToken = async () => {
let imsAuthConfig = toImsAuthConfig(authParams);
return await context.set(imsAuthConfig.context, imsAuthConfig), getToken(imsAuthConfig.context, {});
}, getHeaders = async () => {
let accessToken = await getAccessToken();
return {
Authorization: `Bearer ${accessToken}`,
"x-api-key": authParams.clientId
};
};
return {
getAccessToken,
getHeaders
};
}
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"));
pipe(union([BaseUrlSchema, instance(URL)]), transform((url$1) => url$1 instanceof URL ? url$1.toString() : url$1));
const IntegrationAuthParamsSchema = nonOptional(object({
consumerKey: integrationAuthParameter("consumerKey"),
consumerSecret: integrationAuthParameter("consumerSecret"),
accessToken: integrationAuthParameter("accessToken"),
accessTokenSecret: integrationAuthParameter("accessTokenSecret")
}));
function assertIntegrationAuthParams(config) {
let result = safeParse(IntegrationAuthParamsSchema, config);
if (!result.success) throw new CommerceSdkValidationError("Invalid IntegrationAuthProvider configuration", { issues: result.issues });
}
function getIntegrationAuthProvider(authParams) {
let oauth = new OAuth1a({
consumer: {
key: authParams.consumerKey,
secret: authParams.consumerSecret
},
signature_method: "HMAC-SHA256",
hash_function: (baseString, key) => crypto.createHmac("sha256", key).update(baseString).digest("base64")
}), oauthToken = {
key: authParams.accessToken,
secret: authParams.accessTokenSecret
};
return { getHeaders: (method, url$1) => {
let urlString = url$1 instanceof URL ? url$1.toString() : url$1;
return oauth.toHeader(oauth.authorize({
url: urlString,
method
}, oauthToken));
} };
}
export { IMS_AUTH_ENV, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };