@commercelayer/js-auth
Advanced tools
Comparing version 6.6.5 to 6.7.0
@@ -7,3 +7,10 @@ interface TBaseOptions { | ||
/** | ||
* The access token scope (market, stock location). | ||
* [The access token scope](https://docs.commercelayer.io/core/authentication#authorization-scopes) (market, store, and/or stock location). | ||
* | ||
* The access token scope is a string that can be composed in two ways: | ||
* * by **ID** — `{{resource_name}}:id:{{resource_id}}`\ | ||
* Where `{{resource_name}}` can be one of market, store, or stock_location, and `{{resource_id}}` is the id of the resource (e.g. `market:id:xYZkjABcde`, `store:id:bGvCXzYgNB`, `stock_location:id:WLgbSXqyoZ`).\ | ||
* | ||
* * by **code** — `{{resource_name}}:code:{{resource_code}}` | ||
* Where `{{resource_name}}` can be one of market, store, or stock_location, and `{{resource_code}}` is the code of the resource (e.g. `market:code:europe`, `store:code:outlet_ny`, `stock_location:code:eu_warehouse`). | ||
*/ | ||
@@ -60,3 +67,3 @@ scope?: string; | ||
/** | ||
* The access token scope (market, stock location). | ||
* [The access token scope](https://docs.commercelayer.io/core/authentication#authorization-scopes) (market, store, and/or stock location). | ||
*/ | ||
@@ -255,3 +262,3 @@ scope: string; | ||
} | ||
type Payload = JWTUser | JWTDashboard | JWTIntegration | JWTSalesChannel | JWTWebApp; | ||
type Payload = JWTDashboard | JWTUser | JWTSalesChannel | JWTIntegration | JWTWebApp; | ||
interface JWTBase { | ||
@@ -470,3 +477,3 @@ /** The type of credentials you're using to authenticate to the APIs. */ | ||
/** | ||
* Derive the [Core API base endpoint](https://docs.commercelayer.io/core/api-specification#base-endpoint) given a valid access token. | ||
* Derives the [Core API base endpoint](https://docs.commercelayer.io/core/api-specification#base-endpoint) given a valid access token. | ||
* | ||
@@ -479,7 +486,84 @@ * @example | ||
* The method requires a valid access token with an `organization` in the payload. | ||
* When the organization is not set (e.g., provisioning token), it throws an `InvalidTokenError` exception. | ||
* | ||
* @param accessToken - The access token to decode. | ||
* @param options - An options object to configure behavior. | ||
* @returns The core API base endpoint as a string, or `null` if the token is invalid and `shouldThrow` is `false`. | ||
* @throws InvalidTokenError - If the token is invalid and `shouldThrow` is true. | ||
*/ | ||
declare function getCoreApiBaseEndpoint(accessToken: string): string; | ||
declare function getCoreApiBaseEndpoint(accessToken: string, options?: { | ||
/** | ||
* Whether to throw an error if the token is invalid. | ||
* @default true | ||
*/ | ||
shouldThrow?: true; | ||
}): string; | ||
/** | ||
* Derives the [Core API base endpoint](https://docs.commercelayer.io/core/api-specification#base-endpoint) given a valid access token. | ||
* | ||
* @example | ||
* ```ts | ||
* getCoreApiBaseEndpoint('eyJhbGciOiJS...') //= "https://yourdomain.commercelayer.io" | ||
* ``` | ||
* | ||
* The method requires a valid access token with an `organization` in the payload. | ||
* | ||
* @param accessToken - The access token to decode. | ||
* @param options - An options object to configure behavior. | ||
* @returns The core API base endpoint as a string, or `null` if the token is invalid and `shouldThrow` is `false`. | ||
* @throws InvalidTokenError - If the token is invalid and `shouldThrow` is true. | ||
*/ | ||
declare function getCoreApiBaseEndpoint(accessToken: string, options: { | ||
/** | ||
* Whether to throw an error if the token is invalid. | ||
* @default true | ||
*/ | ||
shouldThrow: false; | ||
}): string | null; | ||
/** | ||
* Returns the [Provisioning API base endpoint](https://docs.commercelayer.io/provisioning/getting-started/api-specification#base-endpoint) given a valid access token. | ||
* | ||
* @example | ||
* ```ts | ||
* getProvisioningApiBaseEndpoint('eyJhbGciOiJS...') //= "https://provisioning.commercelayer.io" | ||
* ``` | ||
* | ||
* The method requires a valid access token for Provisioning API. | ||
* | ||
* @param accessToken - The access token to decode. | ||
* @param options - An options object to configure behavior. | ||
* @returns The provisioning API base endpoint as a string, or `null` if the token is invalid and `shouldThrow` is `false`. | ||
* @throws InvalidTokenError - If the token is invalid and `shouldThrow` is true. | ||
*/ | ||
declare function getProvisioningApiBaseEndpoint(accessToken: string, options?: { | ||
/** | ||
* Whether to throw an error if the token is invalid. | ||
* @default true | ||
*/ | ||
shouldThrow?: true; | ||
}): string; | ||
/** | ||
* Returns the [Provisioning API base endpoint](https://docs.commercelayer.io/provisioning/getting-started/api-specification#base-endpoint) given a valid access token. | ||
* | ||
* @example | ||
* ```ts | ||
* getProvisioningApiBaseEndpoint('eyJhbGciOiJS...') //= "https://provisioning.commercelayer.io" | ||
* ``` | ||
* | ||
* The method requires a valid access token for Provisioning API. | ||
* | ||
* @param accessToken - The access token to decode. | ||
* @param options - An options object to configure behavior. | ||
* @returns The provisioning API base endpoint as a string, or `null` if the token is invalid and `shouldThrow` is `false`. | ||
* @throws InvalidTokenError - If the token is invalid and `shouldThrow` is true. | ||
*/ | ||
declare function getProvisioningApiBaseEndpoint(accessToken: string, options: { | ||
/** | ||
* Whether to throw an error if the token is invalid. | ||
* @default true | ||
*/ | ||
shouldThrow: false; | ||
}): string | null; | ||
/** | ||
* A token error occurred. | ||
@@ -505,2 +589,2 @@ */ | ||
export { type AuthenticateOptions, type AuthenticateReturn, type GrantType, InvalidTokenError, type JWTDashboard, type JWTIntegration, type JWTSalesChannel, type JWTUser, type JWTWebApp, type RevokeOptions, type RevokeReturn, TokenError, TokenExpiredError, authenticate, createAssertion, getCoreApiBaseEndpoint, jwtDecode, jwtIsDashboard, jwtIsIntegration, jwtIsSalesChannel, jwtIsUser, jwtIsWebApp, jwtVerify, revoke }; | ||
export { type AuthenticateOptions, type AuthenticateReturn, type GrantType, InvalidTokenError, type JWTDashboard, type JWTIntegration, type JWTSalesChannel, type JWTUser, type JWTWebApp, type RevokeOptions, type RevokeReturn, TokenError, TokenExpiredError, authenticate, createAssertion, getCoreApiBaseEndpoint, getProvisioningApiBaseEndpoint, jwtDecode, jwtIsDashboard, jwtIsIntegration, jwtIsSalesChannel, jwtIsUser, jwtIsWebApp, jwtVerify, revoke }; |
@@ -1,2 +0,2 @@ | ||
function y(e){return e.replace(/[A-Z]/g,function(t){return"_"+t.toLowerCase()})}function l(e,t){return Object.keys(e).reduce((n,r)=>{let o=t(r);return n[o]=e[r],n},{})}function T(e){return e.replace(/([-_][a-z])/g,t=>t.toUpperCase().replace("-","").replace("_",""))}async function C(e,{domain:t="commercelayer.io",headers:n,...r}){let o=l({grant_type:e,...r},y),p=await(await fetch(`https://auth.${t}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json",...n},body:JSON.stringify(o)})).json();return p.errors==null&&(p.expires=new Date(Date.now()+p.expires_in*1e3)),l(p,T)}var s=class extends Error{constructor(t){super(t),this.name="TokenError"}};var a=class extends s{constructor(t){super(t),this.name="InvalidTokenError"}};function f(e,t){if(typeof btoa<"u"){let n=e;if(t==="utf-8"){let r=new TextEncoder().encode(e);n=String.fromCharCode(...r)}return btoa(n).replaceAll("=","").replaceAll("+","-").replaceAll("/","_")}return Buffer.from(e,t).toString("base64url")}function u(e,t){if(typeof atob<"u"){let n=atob(e.replaceAll("-","+").replaceAll("_","/").padEnd(e.length+(4-e.length%4)%4,"="));if(t==="utf-8"){let r=new Uint8Array([...n].map(o=>o.charCodeAt(0)));return new TextDecoder().decode(r)}return n}return Buffer.from(e,"base64url").toString(t)}function c(e){let[t,n,r]=`${e}`.split(".");if(t==null||n==null||r==null)throw new a("Invalid token format");return{header:JSON.parse(u(t,"binary")),payload:JSON.parse(u(n,"utf-8")),signature:r}}function x(e){return e.application.kind==="user"}function J(e){return e.application.kind==="dashboard"}function S(e){return e.application.kind==="integration"}function b(e){return e.application.kind==="sales_channel"}function W(e){return e.application.kind==="webapp"}function d(e){return e?.payload?.iss?.startsWith("https://auth.")?e.payload.iss:"https://auth.commercelayer.io"}async function A(e){let t=l(e,y),n=c(e.token),r=d(n);return await(await fetch(`${r}/oauth/revoke`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)})).json()}var m=class extends s{constructor(){super("Token expired"),this.name="TokenExpiredError"}};async function j(e,{ignoreExpiration:t=!1,jwk:n}={}){let r=c(e),o=n??await R(r);if(o==null||o.kid!==r.header.kid)throw new a('Invalid token "kid"');if(!t&&Date.now()>=r.payload.exp*1e3)throw new m;let i={name:"RSASSA-PKCS1-v1_5",hash:"SHA-512"},p=await crypto.subtle.importKey("jwk",o,i,!0,["verify"]),k=new Uint8Array(Array.from(u(r.signature,"binary"),h=>h.charCodeAt(0))),w=new TextEncoder().encode(e.split(".").slice(0,2).join("."));if(!await crypto.subtle.verify(i,p,k,w))throw new a("Invalid signature");return r}var g={};async function R(e){let{kid:t}=e.header;if(g[t]!=null)return g[t];let n=await I(e);return g[t]=n.find(r=>r.kid===t),g[t]}async function I(e){let t=`${d(e)}/.well-known/jwks.json`,n=await fetch(t).then(async r=>await r.json());if(n.keys==null)throw new s(`Invalid jwks response from "${t}": ${JSON.stringify(n)}`);return n.keys}async function P({payload:e}){return await O(e,"cl")}async function O(e,t){let r=f(JSON.stringify({alg:"HS512",typ:"JWT"}),"binary"),o=f(JSON.stringify({...e,iat:Math.floor(new Date().getTime()/1e3)}),"utf-8"),i=`${r}.${o}`,p=await L(i,t);return`${i}.${p}`}async function L(e,t){let n=new TextEncoder,r={name:"HMAC",hash:"SHA-512"},o=await crypto.subtle.importKey("raw",n.encode(t),r,!1,["sign","verify"]),i=await crypto.subtle.sign(r.name,o,n.encode(e));return f(String.fromCharCode(...new Uint8Array(i)),"binary")}function K(e){let t=c(e);if(!("organization"in t.payload))throw new a("Invalid token format");return d(t).replace("auth",t.payload.organization.slug)}export{a as InvalidTokenError,s as TokenError,m as TokenExpiredError,C as authenticate,P as createAssertion,K as getCoreApiBaseEndpoint,c as jwtDecode,J as jwtIsDashboard,S as jwtIsIntegration,b as jwtIsSalesChannel,x as jwtIsUser,W as jwtIsWebApp,j as jwtVerify,A as revoke}; | ||
function y(e){return e.replace(/[A-Z]/g,function(t){return"_"+t.toLowerCase()})}function l(e,t){return Object.keys(e).reduce((n,r)=>{let o=t(r);return n[o]=e[r],n},{})}function T(e){return e.replace(/([-_][a-z])/g,t=>t.toUpperCase().replace("-","").replace("_",""))}async function x(e,{domain:t="commercelayer.io",headers:n,...r}){let o=l({grant_type:e,...r},y),c=await(await fetch(`https://auth.${t}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json",...n},body:JSON.stringify(o)})).json();return c.errors==null&&(c.expires=new Date(Date.now()+c.expires_in*1e3)),l(c,T)}var s=class extends Error{constructor(t){super(t),this.name="TokenError"}};var a=class extends s{constructor(t){super(t),this.name="InvalidTokenError"}};function f(e,t){if(typeof btoa<"u"){let n=e;if(t==="utf-8"){let r=new TextEncoder().encode(e);n=String.fromCharCode(...r)}return btoa(n).replaceAll("=","").replaceAll("+","-").replaceAll("/","_")}return Buffer.from(e,t).toString("base64url")}function u(e,t){if(typeof atob<"u"){let n=atob(e.replaceAll("-","+").replaceAll("_","/").padEnd(e.length+(4-e.length%4)%4,"="));if(t==="utf-8"){let r=new Uint8Array([...n].map(o=>o.charCodeAt(0)));return new TextDecoder().decode(r)}return n}return Buffer.from(e,"base64url").toString(t)}function i(e){let[t,n,r]=`${e}`.split(".");if(t==null||n==null||r==null)throw new a("Invalid token format");return{header:JSON.parse(u(t,"binary")),payload:JSON.parse(u(n,"utf-8")),signature:r}}function C(e){return e.application.kind==="user"}function J(e){return e.application.kind==="dashboard"}function b(e){return e.application.kind==="integration"}function S(e){return e.application.kind==="sales_channel"}function W(e){return e.application.kind==="webapp"}function d(e){return e?.payload?.iss?.startsWith("https://auth.")?e.payload.iss:"https://auth.commercelayer.io"}async function A(e){let t=l(e,y),n=i(e.token),r=d(n);return await(await fetch(`${r}/oauth/revoke`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)})).json()}var m=class extends s{constructor(){super("Token expired"),this.name="TokenExpiredError"}};async function j(e,{ignoreExpiration:t=!1,jwk:n}={}){let r=i(e),o=n??await R(r);if(o==null||o.kid!==r.header.kid)throw new a('Invalid token "kid"');if(!t&&Date.now()>=r.payload.exp*1e3)throw new m;let p={name:"RSASSA-PKCS1-v1_5",hash:"SHA-512"},c=await crypto.subtle.importKey("jwk",o,p,!0,["verify"]),w=new Uint8Array(Array.from(u(r.signature,"binary"),k=>k.charCodeAt(0))),h=new TextEncoder().encode(e.split(".").slice(0,2).join("."));if(!await crypto.subtle.verify(p,c,w,h))throw new a("Invalid signature");return r}var g={};async function R(e){let{kid:t}=e.header;if(g[t]!=null)return g[t];let n=await I(e);return g[t]=n.find(r=>r.kid===t),g[t]}async function I(e){let t=`${d(e)}/.well-known/jwks.json`,n=await fetch(t).then(async r=>await r.json());if(n.keys==null)throw new s(`Invalid jwks response from "${t}": ${JSON.stringify(n)}`);return n.keys}async function P({payload:e}){return await v(e,"cl")}async function v(e,t){let r=f(JSON.stringify({alg:"HS512",typ:"JWT"}),"binary"),o=f(JSON.stringify({...e,iat:Math.floor(new Date().getTime()/1e3)}),"utf-8"),p=`${r}.${o}`,c=await E(p,t);return`${p}.${c}`}async function E(e,t){let n=new TextEncoder,r={name:"HMAC",hash:"SHA-512"},o=await crypto.subtle.importKey("raw",n.encode(t),r,!1,["sign","verify"]),p=await crypto.subtle.sign(r.name,o,n.encode(e));return f(String.fromCharCode(...new Uint8Array(p)),"binary")}function O(e,t={}){let{shouldThrow:n=!0}=t,r=i(e);if(!("organization"in r.payload)){if(n)throw new a("Invalid token format");return null}return d(r).replace("auth",r.payload.organization.slug)}function L(e,t={}){let{shouldThrow:n=!0}=t,r=i(e);if(!r?.payload?.scope?.includes("provisioning-api")){if(n)throw new a("Invalid token format");return null}return d(r).replace("auth","provisioning")}export{a as InvalidTokenError,s as TokenError,m as TokenExpiredError,x as authenticate,P as createAssertion,O as getCoreApiBaseEndpoint,L as getProvisioningApiBaseEndpoint,i as jwtDecode,J as jwtIsDashboard,b as jwtIsIntegration,S as jwtIsSalesChannel,C as jwtIsUser,W as jwtIsWebApp,j as jwtVerify,A as revoke}; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@commercelayer/js-auth", | ||
"version": "6.6.5", | ||
"version": "6.7.0", | ||
"description": "A JavaScript library designed to simplify authentication when interacting with the Commerce Layer API.", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -28,2 +28,3 @@ # Commerce Layer JS Auth | ||
- [Get Core API base endpoint](#get-core-api-base-endpoint) | ||
- [Get Provisioning API base endpoint](#get-provisioning-api-base-endpoint) | ||
- [Contributors guide](#contributors-guide) | ||
@@ -73,2 +74,56 @@ - [Need help?](#need-help) | ||
```mermaid | ||
flowchart TB | ||
%% Default style for nodes | ||
classDef node stroke-width:2px; | ||
%% Main nodes | ||
auth(<b>Auth API</b><br/><br/>https://<b>auth</b>.commercelayer.io) | ||
dashboard("dashboard") | ||
user("user") | ||
sales_channel("sales_channel") | ||
integration("integration") | ||
webapp("webapp") | ||
provisioningAPI(<b>Provisioning API</b><br/><br/>https://<b>provisioning</b>.commercelayer.io) | ||
coreAPI(<b>Core API</b><br/><br/>https://<<b>slug</b>>.commercelayer.io) | ||
metricsAPI(<b>Metrics API</b><br/><br/>https://<<b>slug</b>>.commercelayer.io/metrics) | ||
comingSoon(<b>Metrics API</b><br/><br/>https://<b>metrics</b>.commercelayer.io) | ||
%% Node styles | ||
style dashboard fill:#FFE6CC,stroke:#D79B00,color:#000 | ||
style user fill:#F8CECC,stroke:#B85450,color:#000 | ||
style sales_channel fill:#D5E8D4,stroke:#82B366,color:#000 | ||
style integration fill:#DAE8FC,stroke:#6C8EBF,color:#000 | ||
style webapp fill:#E1D5E7,stroke:#9673A6,color:#000 | ||
%% Connections | ||
auth --> dashboard | ||
auth --> user | ||
auth --> sales_channel | ||
auth --> integration | ||
auth --> webapp | ||
dashboard --> provisioningAPI | ||
user --> provisioningAPI | ||
user -- coming soon --> comingSoon | ||
sales_channel --> coreAPI | ||
integration --> coreAPI | ||
integration --> metricsAPI | ||
webapp --> coreAPI | ||
webapp --> metricsAPI | ||
%% Arrow Styles | ||
linkStyle default stroke-width:2px; | ||
linkStyle 5 stroke:#D79B00 | ||
linkStyle 6 stroke:#B85450 | ||
linkStyle 7 stroke:#B85450,stroke-dasharray: 5 5; | ||
linkStyle 8 stroke:#82B366 | ||
linkStyle 9 stroke:#6C8EBF | ||
linkStyle 10 stroke:#6C8EBF | ||
linkStyle 11 stroke:#9673A6 | ||
linkStyle 12 stroke:#9673A6 | ||
``` | ||
## Use cases | ||
@@ -344,2 +399,14 @@ | ||
### Get Provisioning API base endpoint | ||
It returns the [Provisioning API base endpoint](https://docs.commercelayer.io/provisioning/getting-started/api-specification#base-endpoint) given a valid access token. | ||
```ts | ||
import { getProvisioningApiBaseEndpoint } from '@commercelayer/js-auth' | ||
getProvisioningApiBaseEndpoint('a-valid-access-token') //= "https://provisioning.commercelayer.io" | ||
``` | ||
The method requires a valid access token (the token can be used with Provisioning API). When the token is not valid (e.g., core api token), it throws an `InvalidTokenError` exception. | ||
--- | ||
@@ -346,0 +413,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
138156
605
436