UNPKG

@adobe/aio-commerce-lib-auth

Version:

Authentication utilities for Adobe Commerce apps deployed in Adobe App Builder.

97 lines (96 loc) 4.98 kB
/** * @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 };