UNPKG

@commercelayer/js-auth

Version:

A JavaScript library designed to simplify authentication when interacting with the Commerce Layer API.

2 lines 9.46 kB
"use strict";var I=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var X=(e,t)=>{for(var o in t)I(e,o,{get:t[o],enumerable:!0})},Y=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of F(t))!Z.call(e,n)&&n!==o&&I(e,n,{get:()=>t[n],enumerable:!(r=Q(t,n))||r.enumerable});return e};var ee=e=>Y(I({},"__esModule",{value:!0}),e);var ie={};X(ie,{InvalidTokenError:()=>u,TokenError:()=>l,TokenExpiredError:()=>T,authenticate:()=>x,createAssertion:()=>M,createCompositeStorage:()=>O,getCoreApiBaseEndpoint:()=>V,getProvisioningApiBaseEndpoint:()=>N,jwtDecode:()=>c,jwtIsDashboard:()=>L,jwtIsIntegration:()=>K,jwtIsSalesChannel:()=>$,jwtIsUser:()=>E,jwtIsWebApp:()=>B,jwtVerify:()=>H,makeIntegration:()=>U,makeSalesChannel:()=>q,revoke:()=>A});module.exports=ee(ie);var l=class extends Error{constructor(t){super(t),this.name="TokenError"}};var u=class extends l{constructor(t){super(t),this.name="InvalidTokenError"}};function z(e,t){if(typeof btoa<"u"){let o=e;if(t==="utf-8"){let r=new TextEncoder().encode(e);o=String.fromCharCode(...r)}return btoa(o).replaceAll("=","").replaceAll("+","-").replaceAll("/","_")}return Buffer.from(e,t).toString("base64url")}function w(e,t){if(typeof atob<"u"){let o=atob(e.replaceAll("-","+").replaceAll("_","/").padEnd(e.length+(4-e.length%4)%4,"="));if(t==="utf-8"){let r=new Uint8Array([...o].map(n=>n.charCodeAt(0)));return new TextDecoder().decode(r)}return o}return Buffer.from(e,"base64url").toString(t)}function c(e){let[t,o,r]=`${e}`.split(".");if(t==null||o==null||r==null)throw new u("Invalid token format");return{header:JSON.parse(w(t,"binary")),payload:JSON.parse(w(o,"utf-8")),signature:r}}function E(e){return e.application.kind==="user"}function L(e){return e.application.kind==="dashboard"}function K(e){return e.application.kind==="integration"}function $(e){return e.application.kind==="sales_channel"}function B(e){return e.application.kind==="webapp"}function v(e){return e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function y(e){return e?.payload?.iss?.startsWith("https://auth.")?e.payload.iss:"https://auth.commercelayer.io"}function k(e,t){return Object.keys(e).reduce((o,r)=>{let n=t(r);return o[n]=e[r],o},{})}async function A(e){let t=k(e,v),o=c(e.token),r=y(o);return await(await fetch(`${r}/oauth/revoke`,{method:"POST",cache:"no-store",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)})).json()}function C(e){return"owner"in e&&e.owner?.id!=null}function _(e){return e.replace(/([-_][a-z])/g,t=>t.toUpperCase().replace("-","").replace("_",""))}async function x(e,{domain:t="commercelayer.io",headers:o,...r}){let n=k({grant_type:e,...r},v),s=await(await fetch(`https://auth.${t}/oauth/token`,{method:"POST",cache:"no-store",headers:{"Content-Type":"application/json",Accept:"application/json",...o},body:JSON.stringify(n)})).json();return s.errors==null&&(s.expires=new Date(Date.now()+s.expires_in*1e3)),s.errors!=null&&!Array.isArray(s.errors)&&(s.errors=[s.errors]),k(s,_)}var D=e=>{let t=new Map;return function(...o){return new Promise((r,n)=>{let i=JSON.stringify(o),s=t.get(i);s===void 0?(t.set(i,{requestQueue:[]}),Promise.resolve(e.apply(this,o)).then(m=>{let d=t.get(i)?.requestQueue??[];t.delete(i),r(m);for(let h of d)h.resolve(m)}).catch(m=>{let d=t.get(i)?.requestQueue??[];t.delete(i),n(m);for(let h of d)h.reject(m)})):s.requestQueue.push({resolve:r,reject:n})})}};function R(e,t,{logPrefix:o,guestOnly:r=!1}){let n={...e,scope:e.scope??"market:all"};function i(p,...a){n.debug===!0&&console.log(`[CommerceLayer \u2022 auth.js] [${o}] ${p}`,...a)}let s=t.getKey??((p,a)=>`cl_${a}-${p.clientId}-${p.scope}`),m=async()=>{try{if(r===!1){let P=await s({clientId:n.clientId,scope:n.scope},"customer");i("Checking for customer key:",P);let g=b(await(t.customerStorage??t.storage).getItem(P));if(g?.ownerType==="customer"){if(g.expiresIn>=600)return i("Found customer authorization in storage",g),g;if(i("Customer authorization expired",g),g.refreshToken!=null){let W=await x("refresh_token",{...n,refreshToken:g.refreshToken}),j=await d({accessToken:W.accessToken,scope:W.scope,refreshToken:W.refreshToken});return i("Refreshed customer authorization",j),j}}}let a=await s({clientId:n.clientId,scope:n.scope},"guest");i("Checking for guest key:",a);let f=b(await t.storage.getItem(a));if(f?.ownerType==="guest"&&f.expiresIn>=600)return i("Found guest authorization in storage",f),f;i("No valid authorization found, requesting a new guest token");let S=await x("client_credentials",n);return await d({accessToken:S.accessToken,scope:S.scope})}catch(a){throw i("Error getting the authorization.",a),a}},d=async p=>{let a=b(p),f=await s({clientId:n.clientId,scope:p.scope},a.ownerType),S={accessToken:a.accessToken,scope:a.scope,refreshToken:a.ownerType==="customer"?a.refreshToken:void 0};return await(a.ownerType==="customer"?t.customerStorage??t.storage:t.storage).setItem(f,S),i("Stored authorization in storage",a),a},h=async p=>{let a=await s({clientId:n.clientId,scope:n.scope},p);await(p==="customer"?t.customerStorage??t.storage:t.storage).removeItem(a),i(`Removed "${p}" authorization from storage`,a)};return{options:n,getAuthorization:D(m),setAuthorization:d,removeAuthorization:h}}function b(e){if(e==null)return null;let t=c(e.accessToken);if(C(t.payload)&&t.payload.owner.type.toLowerCase()!=="customer")throw new Error("The provided access token does not contain a valid customer owner.");let o=C(t.payload)?{ownerType:"customer",ownerId:t.payload.owner.id,refreshToken:e.refreshToken}:{ownerType:"guest"},r=Math.round(t.payload.exp-Date.now()/1e3);return{...o,tokenType:"bearer",createdAt:t.payload.iat,scope:e.scope,accessToken:e.accessToken,expiresIn:r,expires:new Date(Date.now()+r*1e3)}}function O(e){return{async getItem(t){for(let o of e){let r=await o.getItem(t);if(r!==null){for(let n of e.slice(0,e.indexOf(o)))await n.setItem(t,r);return r}}return null},async setItem(t,o){await Promise.all(e.map(r=>r.setItem(t,o)))},async removeItem(t){await Promise.all(e.map(o=>o.removeItem(t)))},async dispose(){await Promise.all(e.map(t=>t.dispose?.()))}}}function U(e,t){let o=R(e,t,{logPrefix:"integration",guestOnly:!0});return{options:e,getAuthorization:o.getAuthorization,removeAuthorization:async()=>await o.removeAuthorization("guest"),revokeAuthorization:async()=>{let{ownerType:r,accessToken:n}=await o.getAuthorization();return r==="guest"?(await o.removeAuthorization("guest"),await A({clientId:e.clientId,clientSecret:e.clientSecret,token:n})):{}}}}function q(e,t){let o=R(e,t,{logPrefix:"sales_channel"});return{options:e,getAuthorization:o.getAuthorization,removeAuthorization:async(r="all")=>{if(r==="all"){await o.removeAuthorization("customer"),await o.removeAuthorization("guest");return}return o.removeAuthorization(r)},setCustomer:async r=>{let n=c(r.accessToken);if(C(n.payload))return await o.setAuthorization(r);throw new Error("The provided access token does not contain a valid customer owner.")},logoutCustomer:async()=>{let{ownerType:r,accessToken:n}=await o.getAuthorization();return r==="customer"?(await o.removeAuthorization("customer"),await A({clientId:e.clientId,token:n})):{}}}}var T=class extends l{constructor(){super("Token expired"),this.name="TokenExpiredError"}};function V(e,t={}){let{shouldThrow:o=!0}=t,r=c(e);if(!("organization"in r.payload)){if(o)throw new u("Invalid token format");return null}return y(r).replace("auth",r.payload.organization.slug)}function N(e,t={}){let{shouldThrow:o=!0}=t,r=c(e);if(!r?.payload?.scope?.includes("provisioning-api")){if(o)throw new u("Invalid token format");return null}return y(r).replace("auth","provisioning")}async function M({payload:e}){return await te(e,"cl")}async function te(e,t){let r=z(JSON.stringify({alg:"HS512",typ:"JWT"}),"binary"),n=z(JSON.stringify({...e,iat:Math.floor(Date.now()/1e3)}),"utf-8"),i=`${r}.${n}`,s=await oe(i,t);return`${i}.${s}`}async function oe(e,t){let o=new TextEncoder,r={name:"HMAC",hash:"SHA-512"},n=await crypto.subtle.importKey("raw",o.encode(t),r,!1,["sign","verify"]),i=await crypto.subtle.sign(r.name,n,o.encode(e));return z(String.fromCharCode(...new Uint8Array(i)),"binary")}function G(e){return Date.now()>=e.payload.exp*1e3}async function H(e,{ignoreExpiration:t=!1,jwk:o}={}){let r=c(e),n=o??await re(r);if(n==null||n.kid!==r.header.kid)throw new u('Invalid token "kid"');if(!t&&G(r))throw new T;let i={name:"RSASSA-PKCS1-v1_5",hash:"SHA-512"},s=await crypto.subtle.importKey("jwk",n,i,!0,["verify"]),m=new Uint8Array(Array.from(w(r.signature,"binary"),p=>p.charCodeAt(0))),d=new TextEncoder().encode(e.split(".").slice(0,2).join("."));if(!await crypto.subtle.verify(i,s,m,d))throw new u("Invalid signature");return r}var J={};async function re(e){let{kid:t}=e.header;if(J[t]!=null)return J[t];let o=await ne(e);return J[t]=o.find(r=>r.kid===t),J[t]}async function ne(e){let t=`${y(e)}/.well-known/jwks.json`,o=await fetch(t).then(async r=>await r.json());if(o.keys==null)throw new l(`Invalid jwks response from "${t}": ${JSON.stringify(o)}`);return o.keys}0&&(module.exports={InvalidTokenError,TokenError,TokenExpiredError,authenticate,createAssertion,createCompositeStorage,getCoreApiBaseEndpoint,getProvisioningApiBaseEndpoint,jwtDecode,jwtIsDashboard,jwtIsIntegration,jwtIsSalesChannel,jwtIsUser,jwtIsWebApp,jwtVerify,makeIntegration,makeSalesChannel,revoke}); //# sourceMappingURL=index.cjs.map