UNPKG

@adobe/aio-commerce-lib-auth

Version:

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

227 lines (224 loc) 11.6 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 * as valibot21 from "valibot"; import { InferOutput } from "valibot"; //#region source/lib/ims-auth/schema.d.ts /** The environments accepted by the IMS auth service. */ declare const IMS_AUTH_ENV: { readonly PROD: "prod"; readonly STAGE: "stage"; }; /** Validation schema for IMS auth environment values. */ declare const ImsAuthEnvSchema: valibot21.EnumSchema<{ readonly PROD: "prod"; readonly STAGE: "stage"; }, undefined>; /** Defines the schema to validate the necessary parameters for the IMS auth service. */ declare const ImsAuthParamsSchema: valibot21.ObjectSchema<{ 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}`>]>; 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">]>; 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}`>]>; 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">]>; 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}`>]>; readonly environment: valibot21.SchemaWithPipe<readonly [valibot21.OptionalSchema<valibot21.EnumSchema<{ readonly PROD: "prod"; readonly STAGE: "stage"; }, undefined>, "prod">]>; readonly context: valibot21.SchemaWithPipe<readonly [valibot21.OptionalSchema<valibot21.StringSchema<undefined>, undefined>]>; 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">]>; }, undefined>; /** Defines the parameters for the IMS auth service. */ type ImsAuthParams = InferOutput<typeof ImsAuthParamsSchema>; /** Defines the environments accepted by the IMS auth service. */ type ImsAuthEnv = InferOutput<typeof ImsAuthEnvSchema>; //#endregion //#region source/lib/ims-auth/provider.d.ts /** Defines the header keys used for IMS authentication. */ type ImsAuthHeader = "Authorization" | "x-api-key"; /** Defines the headers required for IMS authentication. */ type ImsAuthHeaders = Record<ImsAuthHeader, string>; /** Defines an authentication provider for Adobe IMS. */ type ImsAuthProvider = { getAccessToken: () => Promise<string>; getHeaders: () => Promise<ImsAuthHeaders>; }; /** * Asserts the provided configuration for an {@link ImsAuthProvider}. * @param config The configuration to validate. * @throws {CommerceSdkValidationError} If the configuration is invalid. * @example * ```typescript * const config = { * clientId: "your-client-id", * clientSecrets: ["your-client-secret"], * technicalAccountId: "your-technical-account-id", * technicalAccountEmail: "your-account@example.com", * imsOrgId: "your-ims-org-id@AdobeOrg", * scopes: ["AdobeID", "openid"], * environment: "prod", // or "stage" * context: "my-app-context" * }; * * // This will validate the config and throw if invalid * assertImsAuthParams(config); *``` * @example * ```typescript * // Example of a failing assert: * try { * assertImsAuthParams({ * clientId: "valid-client-id", * // Missing required fields like clientSecrets, technicalAccountId, etc. * }); * } catch (error) { * console.error(error.message); // "Invalid ImsAuthProvider configuration" * console.error(error.issues); // Array of validation issues * } * ``` */ declare function assertImsAuthParams(config: Record<PropertyKey, unknown>): asserts config is ImsAuthParams; /** * Creates an {@link ImsAuthProvider} based on the provided configuration. * @param authParams An {@link ImsAuthParams} parameter that contains the configuration for the {@link ImsAuthProvider}. * @returns An {@link ImsAuthProvider} instance that can be used to get access token and auth headers. * @example * ```typescript * const config = { * clientId: "your-client-id", * clientSecrets: ["your-client-secret"], * technicalAccountId: "your-technical-account-id", * technicalAccountEmail: "your-account@example.com", * imsOrgId: "your-ims-org-id@AdobeOrg", * scopes: ["AdobeID", "openid"], * environment: "prod", * context: "my-app-context" * }; * * const authProvider = getImsAuthProvider(config); * * // Get access token * const token = await authProvider.getAccessToken(); * console.log(token); // "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..." * * // Get headers for API requests * const headers = await authProvider.getHeaders(); * console.log(headers); * // { * // Authorization: "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...", * // "x-api-key": "your-client-id" * // } * * // Use headers in API calls * const response = await fetch('https://api.adobe.io/some-endpoint', { * headers: await authProvider.getHeaders() * }); * ``` */ declare function getImsAuthProvider(authParams: ImsAuthParams): { getAccessToken: () => Promise<string>; getHeaders: () => Promise<{ Authorization: string; "x-api-key": string; }>; }; //#endregion //#region source/lib/integration-auth/schema.d.ts /** * The HTTP methods supported by Commerce. * This is used to determine which headers to include in the signing of the authorization header. */ type HttpMethodInput = "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; /** Validation schema that accepts either a URL string or URL instance and normalizes to string. */ /** * The schema for the Commerce Integration parameters. * This is used to validate the parameters passed to the Commerce Integration provider. */ declare const IntegrationAuthParamsSchema: valibot21.NonOptionalSchema<valibot21.ObjectSchema<{ 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}`>]>; 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}`>]>; 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}`>]>; 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}`>]>; }, undefined>, undefined>; /** Defines the parameters required for Commerce Integration authentication. */ type IntegrationAuthParams = InferOutput<typeof IntegrationAuthParamsSchema>; //#endregion //#region source/lib/integration-auth/provider.d.ts /** Defines the header key used for Commerce Integration authentication. */ type IntegrationAuthHeader = "Authorization"; /** Defines the headers required for Commerce Integration authentication. */ type IntegrationAuthHeaders = Record<IntegrationAuthHeader, string>; /** Represents a URL for Adobe Commerce endpoints, accepting either string or URL object. */ type AdobeCommerceUrl = string | URL; /** Defines an authentication provider for Adobe Commerce integrations. */ type IntegrationAuthProvider = { getHeaders: (method: HttpMethodInput, url: AdobeCommerceUrl) => IntegrationAuthHeaders; }; /** * Asserts the provided configuration for an Adobe Commerce {@link IntegrationAuthProvider}. * @param config The configuration to validate. * @throws {CommerceSdkValidationError} If the configuration is invalid. * @example * ```typescript * const config = { * consumerKey: "your-consumer-key", * consumerSecret: "your-consumer-secret", * accessToken: "your-access-token", * accessTokenSecret: "your-access-token-secret" * }; * * // This will validate the config and throw if invalid * assertIntegrationAuthParams(config); * ``` * @example * ```typescript * // Example of a failing assert: * try { * assertIntegrationAuthParams({ * consumerKey: "valid-consumer-key", * // Missing required fields like consumerSecret, accessToken, accessTokenSecret * }); * } catch (error) { * console.error(error.message); // "Invalid IntegrationAuthProvider configuration" * console.error(error.issues); // Array of validation issues * } * ``` */ declare function assertIntegrationAuthParams(config: Record<PropertyKey, unknown>): asserts config is IntegrationAuthParams; /** * Creates an {@link IntegrationAuthProvider} based on the provided configuration. * @param authParams The configuration for the integration. * @returns An {@link IntegrationAuthProvider} instance that can be used to get auth headers. * @example * ```typescript * const config = { * consumerKey: "your-consumer-key", * consumerSecret: "your-consumer-secret", * accessToken: "your-access-token", * accessTokenSecret: "your-access-token-secret" * }; * * const authProvider = getIntegrationAuthProvider(config); * * // Get OAuth headers for a REST API call * const headers = authProvider.getHeaders("GET", "https://your-store.com/rest/V1/products"); * console.log(headers); // { Authorization: "OAuth oauth_consumer_key=..., oauth_signature=..." } * * // Can also be used with URL objects * const url = new URL("https://your-store.com/rest/V1/customers"); * const postHeaders = authProvider.getHeaders("POST", url); * ``` */ declare function getIntegrationAuthProvider(authParams: IntegrationAuthParams): IntegrationAuthProvider; //#endregion export { IMS_AUTH_ENV, type ImsAuthEnv, type ImsAuthParams, type ImsAuthProvider, type IntegrationAuthParams, type IntegrationAuthProvider, assertImsAuthParams, assertIntegrationAuthParams, getImsAuthProvider, getIntegrationAuthProvider };