@joai/sdk 14.1.0 → 14.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -2
- package/dist/index.d.mts +72 -1
- package/dist/index.mjs +122 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,9 +95,9 @@ Set `compression: false` or `dimensions: false` to disable only that stage, or `
|
|
|
95
95
|
|
|
96
96
|
## Session storage
|
|
97
97
|
|
|
98
|
-
`useContentSession` and `createSessionTokenStore` are exported for custom shells. A custom `SessionTokenStore` can be injected when a host needs a different persistence mechanism. The
|
|
98
|
+
`useContentSession` and `createSessionTokenStore` are exported for custom shells. A custom `SessionTokenStore` can be injected when a host needs a different persistence mechanism. The one-time authorization code is removed from the URL before the session token is persisted.
|
|
99
99
|
|
|
100
|
-
The managed editor
|
|
100
|
+
The managed editor starts the app authorization-code flow for reauthentication and stores the PKCE secret in local storage. Override `reauthenticateUrl` only when a host has a dedicated login callback.
|
|
101
101
|
|
|
102
102
|
`createContentDraftStore` uses `sessionStorage` by default. `ManagedContentEditor` wires it automatically so unsaved values survive refreshes and expired-session reauthentication without being shared across browser sessions.
|
|
103
103
|
|
|
@@ -113,3 +113,27 @@ The managed editor automatically adds `platform=app` to its reauthentication ret
|
|
|
113
113
|
- Expired authorization offers a sign-in action and restores locally persisted edits afterwards.
|
|
114
114
|
- Version conflicts load the latest version while preserving local edits.
|
|
115
115
|
- Public content cache entries are invalidated after authenticated mutations.
|
|
116
|
+
|
|
117
|
+
## App authorization code
|
|
118
|
+
|
|
119
|
+
Apps that keep the bearer token on their server can use the SDK's PKCE helpers instead of implementing the flow themselves:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { createAppAuthRequest, exchangeAppAuthCode } from '@joai/sdk'
|
|
123
|
+
|
|
124
|
+
const auth = await createAppAuthRequest({
|
|
125
|
+
callbackUrl: 'https://app.example/api/auth/callback',
|
|
126
|
+
team: 'team-slug',
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// Store auth.state and auth.codeVerifier in a short-lived HttpOnly cookie,
|
|
130
|
+
// then redirect the browser to auth.url.
|
|
131
|
+
|
|
132
|
+
const response = await exchangeAppAuthCode({
|
|
133
|
+
code: callbackCode,
|
|
134
|
+
redirectUri: auth.redirectUri,
|
|
135
|
+
codeVerifier: storedVerifier,
|
|
136
|
+
})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The callback origin must be registered for the team. The code is single-use, short-lived, bound to the canonical `redirectUri`, and verified with PKCE `S256`.
|
package/dist/index.d.mts
CHANGED
|
@@ -806,6 +806,9 @@ type AuthApiTokenResponse = {
|
|
|
806
806
|
type AuthPortalSessionResponse = {
|
|
807
807
|
url: string;
|
|
808
808
|
};
|
|
809
|
+
type AuthAppTokenResponse = {
|
|
810
|
+
token: string;
|
|
811
|
+
};
|
|
809
812
|
declare class AuthResource {
|
|
810
813
|
private http;
|
|
811
814
|
constructor(http: IHttpService);
|
|
@@ -817,6 +820,7 @@ declare class AuthResource {
|
|
|
817
820
|
}): Promise<IAppResponse$1<AuthLoginResponse>>;
|
|
818
821
|
loginWithSocialAccessToken(provider: NativeSocialAuthProvider, accessToken: string): Promise<IAppResponse$1<AuthLoginResponse>>;
|
|
819
822
|
exchangeNativeSession(token: string): Promise<IAppResponse$1<AuthNativeSessionResponse>>;
|
|
823
|
+
exchangeAppAuthCode(code: string, redirectUri: string, codeVerifier: string): Promise<IAppResponse$1<AuthAppTokenResponse>>;
|
|
820
824
|
me(): Promise<IAppResponse$1<AuthUser$1>>;
|
|
821
825
|
logout(): Promise<IAppResponse$1<void>>;
|
|
822
826
|
createApiToken(): Promise<IAppResponse$1<AuthApiTokenResponse>>;
|
|
@@ -1993,6 +1997,7 @@ declare class SitesResource {
|
|
|
1993
1997
|
resolve(teamSlug: string, brandSlug?: string): Promise<_$_joai_core0.IAppResponse<Site>>;
|
|
1994
1998
|
resolveByDomain(domain: string): Promise<_$_joai_core0.IAppResponse<Site>>;
|
|
1995
1999
|
uptime(siteId: HashidInput$1): Promise<_$_joai_core0.IAppResponse<SiteUptime>>;
|
|
2000
|
+
verifyCustomDomain(siteId: HashidInput$1): Promise<_$_joai_core0.IAppResponse<Site>>;
|
|
1996
2001
|
update(siteId: HashidInput$1, data: {
|
|
1997
2002
|
customDomain?: string | null;
|
|
1998
2003
|
enabled?: boolean;
|
|
@@ -2733,6 +2738,72 @@ declare class CachedHttpService implements IHttpService {
|
|
|
2733
2738
|
private bust;
|
|
2734
2739
|
}
|
|
2735
2740
|
//#endregion
|
|
2741
|
+
//#region src/auth/browser-app-code.d.ts
|
|
2742
|
+
declare const DEFAULT_BROWSER_APP_AUTH_STORAGE_KEY = "joai:app-auth";
|
|
2743
|
+
type BeginBrowserAppAuthOptions = {
|
|
2744
|
+
callbackUrl: string;
|
|
2745
|
+
env?: AppEnv$1;
|
|
2746
|
+
team?: string;
|
|
2747
|
+
brand?: string;
|
|
2748
|
+
storageKey?: string;
|
|
2749
|
+
};
|
|
2750
|
+
type CompleteBrowserAppAuthOptions = {
|
|
2751
|
+
url: string;
|
|
2752
|
+
env?: AppEnv$1;
|
|
2753
|
+
storageKey?: string;
|
|
2754
|
+
};
|
|
2755
|
+
/** Starts a browser app authorization-code flow and persists the PKCE secret in localStorage. */
|
|
2756
|
+
declare const beginBrowserAppAuth: ({
|
|
2757
|
+
callbackUrl,
|
|
2758
|
+
env,
|
|
2759
|
+
team,
|
|
2760
|
+
brand,
|
|
2761
|
+
storageKey
|
|
2762
|
+
}: BeginBrowserAppAuthOptions) => Promise<string>;
|
|
2763
|
+
/** Completes a browser app authorization-code flow and returns the exchanged bearer token. */
|
|
2764
|
+
declare const completeBrowserAppAuth: ({
|
|
2765
|
+
url,
|
|
2766
|
+
env,
|
|
2767
|
+
storageKey
|
|
2768
|
+
}: CompleteBrowserAppAuthOptions) => Promise<string | null>;
|
|
2769
|
+
//#endregion
|
|
2770
|
+
//#region src/auth/app-code.d.ts
|
|
2771
|
+
type AppAuthRequest = {
|
|
2772
|
+
/** JoAi login URL to navigate to. */url: string; /** Canonical callback URL that must be sent to the token exchange. */
|
|
2773
|
+
redirectUri: string;
|
|
2774
|
+
state: string;
|
|
2775
|
+
codeVerifier: string;
|
|
2776
|
+
};
|
|
2777
|
+
type CreateAppAuthRequestOptions = {
|
|
2778
|
+
callbackUrl: string;
|
|
2779
|
+
env?: AppEnv$1;
|
|
2780
|
+
team?: string;
|
|
2781
|
+
brand?: string;
|
|
2782
|
+
};
|
|
2783
|
+
type ExchangeAppAuthCodeOptions = {
|
|
2784
|
+
code: string;
|
|
2785
|
+
redirectUri: string;
|
|
2786
|
+
codeVerifier: string;
|
|
2787
|
+
env?: AppEnv$1;
|
|
2788
|
+
};
|
|
2789
|
+
/**
|
|
2790
|
+
* Creates a PKCE authorization-code request for a browser app with a server-side callback.
|
|
2791
|
+
* The callback origin must be a registered JoAi app origin.
|
|
2792
|
+
*/
|
|
2793
|
+
declare const createAppAuthRequest: ({
|
|
2794
|
+
callbackUrl,
|
|
2795
|
+
env,
|
|
2796
|
+
team,
|
|
2797
|
+
brand
|
|
2798
|
+
}: CreateAppAuthRequestOptions) => Promise<AppAuthRequest>;
|
|
2799
|
+
/** Exchanges a one-time app authorization code for a bearer token. */
|
|
2800
|
+
declare const exchangeAppAuthCode: ({
|
|
2801
|
+
code,
|
|
2802
|
+
redirectUri,
|
|
2803
|
+
codeVerifier,
|
|
2804
|
+
env
|
|
2805
|
+
}: ExchangeAppAuthCodeOptions) => Promise<IAppResponse$1<AuthAppTokenResponse>>;
|
|
2806
|
+
//#endregion
|
|
2736
2807
|
//#region src/auth/portal.d.ts
|
|
2737
2808
|
declare const getAuthFragmentToken: (url: string) => string | null;
|
|
2738
2809
|
declare const isPortalCallbackUrl: (url: string, env?: AppEnv$1) => boolean;
|
|
@@ -2766,4 +2837,4 @@ declare class DistributionResource {
|
|
|
2766
2837
|
private fetchDistribution;
|
|
2767
2838
|
}
|
|
2768
2839
|
//#endregion
|
|
2769
|
-
export { type AddressInput, AddressesResource, AgentsResource, AlertsResource, AnalyticsResource, ApiTokensResource, type AppEnv, type AppointmentAvailabilitySlot, AppointmentsResource, type AttachedMedia, type AuditLogEvent, type AuditLogListParams, AuditLogsResource, type AuthConfirmCodeRequest, type AuthConfirmCodeResponse, type AuthNativeSessionResponse, type AuthPortalSessionResponse, AuthResource, type AuthSendCodeRequest, type AuthUser, AutomationsResource, type BackendWarp, type BackendWarpBrand, BillingResource, BlueprintsResource, type CacheConfig, CachedHttpService, CampaignsResource, CardsResource, type Cart, type CartItem, CartsResource, type CatalogExportFormat, type CatalogExportRequest, type CatalogExportResource, ChangelogResource, CharactersResource, CheckoutResource, type CheckoutSnapshot, type CheckoutSnapshotRequest, CommerceResource, ContactsResource, ContentResource, ContractsResource, type CreateEmptyGuestCheckoutOptions, type CreateHookPayload, type CreateInboundHookPayload, type CreateInternalHookPayload, type CreateWarpLinkedHookPayload, type CreateWebHookPayload, type DeleteUserParams, DeskResource, DistributionResource, DocumentsResource, ElementsResource, EntitiesResource, ExportsResource, FlowsResource, FollowsResource, type FulfillmentLocation, type FulfillmentLocationInput, FulfillmentsResource, GoalsResource, type GuestBuyer, type GuestCartAmounts, type GuestCheckoutCartItem, type GuestCheckoutClient, type GuestCheckoutDraft, GuestCheckoutError, type GuestCheckoutErrorCode, type GuestCheckoutSnapshotResult, type GuestCheckoutState, type GuestCommerceStorage, type GuestCommerceStorageOptions, type GuestCouponClient, GuestCouponError, type GuestCouponErrorCode, type GuestCouponPreview, type GuestOrderAccess, type HashidInput, type Hook, type HookSample, type HookTrigger, type HookTriggerCondition, type HookTriggerInput, HooksResource, type IAppResponse, IngestionsResource, InquiriesResource, InstallsResource, IntegrationsResource, IntentsResource, type ItemListParams, ItemsResource, JoAiClient, type JoAiClientConfig, KvResource, LinksResource, LoyaltyResource, McpResource, type MediaUploadType, MeetingsResource, MemoriesResource, MessagesResource, MetricsResource, MissionsResource, NotificationsResource, OfficeResource, type OpenPortalSessionOptions, type OpeningHoursEntry, type OpeningHoursFormatOptions, type Order, type OrderPriceMode, type OrderStatus, OrdersResource, PersonaResource, type PlaceCheckoutOrderRequest, type PlaceGuestCheckoutOrderResult, type Product, type ProductCategories, type ProductDetailSection, type ProductDetailText, type ProductFacets, type ProductRelationType, type ProductVariation, type ProductsListParams, ProductsResource, type ProductsSort, ProjectsResource, type ProposalListParams, ProposalsResource, type RecentlyViewedStorage, type RecentlyViewedStorageOptions, RemindersResource, ReturnsResource, type RevalidateGuestCouponResult, SegmentsResource, type ServicesListParams, ServicesResource, type ShippingRate, type ShippingRateInput, ShippingResource, type ShippingZoneInput, ShortcutsResource, SitesResource, SkillsResource, SocialPostsResource, StatsResource, StoreResource, SubscriptionsResource, SwarmsResource, TagsResource, TasksResource, type TaxClassInput, TaxClassesResource, type TeamInviteInfo, TeamsResource, type TranslatableValue, UpdatesResource, UpgradesResource, UsersResource, VoiceResource, WalletsResource, WarpsResource, type WebHookTriggerEvent, WorkspaceResource, assertGuestCheckoutReady, assertGuestPickupSlotReady, buildGuestCheckoutSnapshotRequest, buildGuestOrderReturnUrl, completePortalSession, createClient, createEmptyGuestCheckoutState, createGuestCheckoutSnapshot, createGuestCommerceStorage, createRecentlyViewedStorage, formatOpeningHours, formatPickupSlotLabel, getAuthFragmentToken, getRecentlyViewedSlugs, guestCartAmounts, guestCouponMessageFromErrors, isAllowedRedirectUrl, isGuestCheckoutError, isGuestCouponError, isPortalCallbackUrl, openPortalSession, placeGuestCheckoutOrder, readGuestOrderReturnAccess, revalidateGuestCoupon, sanitizePortalCallbackUrl, stripGuestOrderReturnToken, toGuestCheckoutDraft, trackRecentlyViewed, validateGuestCoupon };
|
|
2840
|
+
export { type AddressInput, AddressesResource, AgentsResource, AlertsResource, AnalyticsResource, ApiTokensResource, type AppAuthRequest, type AppEnv, type AppointmentAvailabilitySlot, AppointmentsResource, type AttachedMedia, type AuditLogEvent, type AuditLogListParams, AuditLogsResource, type AuthAppTokenResponse, type AuthConfirmCodeRequest, type AuthConfirmCodeResponse, type AuthNativeSessionResponse, type AuthPortalSessionResponse, AuthResource, type AuthSendCodeRequest, type AuthUser, AutomationsResource, type BackendWarp, type BackendWarpBrand, type BeginBrowserAppAuthOptions, BillingResource, BlueprintsResource, type CacheConfig, CachedHttpService, CampaignsResource, CardsResource, type Cart, type CartItem, CartsResource, type CatalogExportFormat, type CatalogExportRequest, type CatalogExportResource, ChangelogResource, CharactersResource, CheckoutResource, type CheckoutSnapshot, type CheckoutSnapshotRequest, CommerceResource, type CompleteBrowserAppAuthOptions, ContactsResource, ContentResource, ContractsResource, type CreateAppAuthRequestOptions, type CreateEmptyGuestCheckoutOptions, type CreateHookPayload, type CreateInboundHookPayload, type CreateInternalHookPayload, type CreateWarpLinkedHookPayload, type CreateWebHookPayload, DEFAULT_BROWSER_APP_AUTH_STORAGE_KEY, type DeleteUserParams, DeskResource, DistributionResource, DocumentsResource, ElementsResource, EntitiesResource, type ExchangeAppAuthCodeOptions, ExportsResource, FlowsResource, FollowsResource, type FulfillmentLocation, type FulfillmentLocationInput, FulfillmentsResource, GoalsResource, type GuestBuyer, type GuestCartAmounts, type GuestCheckoutCartItem, type GuestCheckoutClient, type GuestCheckoutDraft, GuestCheckoutError, type GuestCheckoutErrorCode, type GuestCheckoutSnapshotResult, type GuestCheckoutState, type GuestCommerceStorage, type GuestCommerceStorageOptions, type GuestCouponClient, GuestCouponError, type GuestCouponErrorCode, type GuestCouponPreview, type GuestOrderAccess, type HashidInput, type Hook, type HookSample, type HookTrigger, type HookTriggerCondition, type HookTriggerInput, HooksResource, type IAppResponse, IngestionsResource, InquiriesResource, InstallsResource, IntegrationsResource, IntentsResource, type ItemListParams, ItemsResource, JoAiClient, type JoAiClientConfig, KvResource, LinksResource, LoyaltyResource, McpResource, type MediaUploadType, MeetingsResource, MemoriesResource, MessagesResource, MetricsResource, MissionsResource, NotificationsResource, OfficeResource, type OpenPortalSessionOptions, type OpeningHoursEntry, type OpeningHoursFormatOptions, type Order, type OrderPriceMode, type OrderStatus, OrdersResource, PersonaResource, type PlaceCheckoutOrderRequest, type PlaceGuestCheckoutOrderResult, type Product, type ProductCategories, type ProductDetailSection, type ProductDetailText, type ProductFacets, type ProductRelationType, type ProductVariation, type ProductsListParams, ProductsResource, type ProductsSort, ProjectsResource, type ProposalListParams, ProposalsResource, type RecentlyViewedStorage, type RecentlyViewedStorageOptions, RemindersResource, ReturnsResource, type RevalidateGuestCouponResult, SegmentsResource, type ServicesListParams, ServicesResource, type ShippingRate, type ShippingRateInput, ShippingResource, type ShippingZoneInput, ShortcutsResource, SitesResource, SkillsResource, SocialPostsResource, StatsResource, StoreResource, SubscriptionsResource, SwarmsResource, TagsResource, TasksResource, type TaxClassInput, TaxClassesResource, type TeamInviteInfo, TeamsResource, type TranslatableValue, UpdatesResource, UpgradesResource, UsersResource, VoiceResource, WalletsResource, WarpsResource, type WebHookTriggerEvent, WorkspaceResource, assertGuestCheckoutReady, assertGuestPickupSlotReady, beginBrowserAppAuth, buildGuestCheckoutSnapshotRequest, buildGuestOrderReturnUrl, completeBrowserAppAuth, completePortalSession, createAppAuthRequest, createClient, createEmptyGuestCheckoutState, createGuestCheckoutSnapshot, createGuestCommerceStorage, createRecentlyViewedStorage, exchangeAppAuthCode, formatOpeningHours, formatPickupSlotLabel, getAuthFragmentToken, getRecentlyViewedSlugs, guestCartAmounts, guestCouponMessageFromErrors, isAllowedRedirectUrl, isGuestCheckoutError, isGuestCouponError, isPortalCallbackUrl, openPortalSession, placeGuestCheckoutOrder, readGuestOrderReturnAccess, revalidateGuestCoupon, sanitizePortalCallbackUrl, stripGuestOrderReturnToken, toGuestCheckoutDraft, trackRecentlyViewed, validateGuestCoupon };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpService, cartLineTotal, cartPayableTotal, firstValidationMessage, getApiBaseUrl, getCortexBaseUrl, isCompleteAddressInput, validationMessageFor } from "@joai/core";
|
|
1
|
+
import { HttpService, cartLineTotal, cartPayableTotal, firstValidationMessage, getApiBaseUrl, getCortexBaseUrl, getLoginUrl, isCompleteAddressInput, validationMessageFor } from "@joai/core";
|
|
2
2
|
import { WarpClient } from "@joai/warps";
|
|
3
3
|
//#region src/resources/agents.ts
|
|
4
4
|
var AgentsResource = class {
|
|
@@ -1157,6 +1157,13 @@ var AuthResource = class {
|
|
|
1157
1157
|
exchangeNativeSession(token) {
|
|
1158
1158
|
return this.http.post("auth/verify", { token });
|
|
1159
1159
|
}
|
|
1160
|
+
exchangeAppAuthCode(code, redirectUri, codeVerifier) {
|
|
1161
|
+
return this.http.post("auth/app/token", {
|
|
1162
|
+
code,
|
|
1163
|
+
redirect_uri: redirectUri,
|
|
1164
|
+
code_verifier: codeVerifier
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1160
1167
|
me() {
|
|
1161
1168
|
return this.http.get("auth/me");
|
|
1162
1169
|
}
|
|
@@ -2807,6 +2814,9 @@ var SitesResource = class {
|
|
|
2807
2814
|
uptime(siteId) {
|
|
2808
2815
|
return this.http.get(`sites/${siteId}/uptime`);
|
|
2809
2816
|
}
|
|
2817
|
+
verifyCustomDomain(siteId) {
|
|
2818
|
+
return this.http.post(`sites/${siteId}/custom-domain/verify`);
|
|
2819
|
+
}
|
|
2810
2820
|
update(siteId, data) {
|
|
2811
2821
|
return this.http.put(`sites/${siteId}`, data);
|
|
2812
2822
|
}
|
|
@@ -4030,6 +4040,116 @@ function createClient(config) {
|
|
|
4030
4040
|
return new JoAiClient(config);
|
|
4031
4041
|
}
|
|
4032
4042
|
//#endregion
|
|
4043
|
+
//#region src/auth/app-code.ts
|
|
4044
|
+
const CONTROL_PARAMS = [
|
|
4045
|
+
"code",
|
|
4046
|
+
"state",
|
|
4047
|
+
"joai_auth",
|
|
4048
|
+
"code_challenge",
|
|
4049
|
+
"code_challenge_method"
|
|
4050
|
+
];
|
|
4051
|
+
const base64Url = (bytes) => {
|
|
4052
|
+
let binary = "";
|
|
4053
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
4054
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
4055
|
+
};
|
|
4056
|
+
const random = (bytes) => crypto.getRandomValues(new Uint8Array(bytes));
|
|
4057
|
+
const sha256 = async (value) => new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)));
|
|
4058
|
+
/**
|
|
4059
|
+
* Creates a PKCE authorization-code request for a browser app with a server-side callback.
|
|
4060
|
+
* The callback origin must be a registered JoAi app origin.
|
|
4061
|
+
*/
|
|
4062
|
+
const createAppAuthRequest = async ({ callbackUrl, env = "mainnet", team, brand }) => {
|
|
4063
|
+
const callback = new URL(callbackUrl);
|
|
4064
|
+
callback.hash = "";
|
|
4065
|
+
for (const param of CONTROL_PARAMS) callback.searchParams.delete(param);
|
|
4066
|
+
const redirectUri = callback.toString();
|
|
4067
|
+
const state = base64Url(random(24));
|
|
4068
|
+
const codeVerifier = base64Url(random(48));
|
|
4069
|
+
const codeChallenge = base64Url(await sha256(codeVerifier));
|
|
4070
|
+
callback.searchParams.set("joai_auth", "code");
|
|
4071
|
+
callback.searchParams.set("state", state);
|
|
4072
|
+
callback.searchParams.set("code_challenge", codeChallenge);
|
|
4073
|
+
callback.searchParams.set("code_challenge_method", "S256");
|
|
4074
|
+
return {
|
|
4075
|
+
url: getLoginUrl(env, callback.toString(), team ? {
|
|
4076
|
+
team,
|
|
4077
|
+
brand
|
|
4078
|
+
} : void 0),
|
|
4079
|
+
redirectUri,
|
|
4080
|
+
state,
|
|
4081
|
+
codeVerifier
|
|
4082
|
+
};
|
|
4083
|
+
};
|
|
4084
|
+
/** Exchanges a one-time app authorization code for a bearer token. */
|
|
4085
|
+
const exchangeAppAuthCode = ({ code, redirectUri, codeVerifier, env = "mainnet" }) => createClient({
|
|
4086
|
+
env,
|
|
4087
|
+
cache: { enabled: false }
|
|
4088
|
+
}).auth.exchangeAppAuthCode(code, redirectUri, codeVerifier);
|
|
4089
|
+
//#endregion
|
|
4090
|
+
//#region src/auth/browser-app-code.ts
|
|
4091
|
+
const DEFAULT_BROWSER_APP_AUTH_STORAGE_KEY = "joai:app-auth";
|
|
4092
|
+
const storage = () => {
|
|
4093
|
+
if (typeof window === "undefined") return null;
|
|
4094
|
+
try {
|
|
4095
|
+
return window.localStorage;
|
|
4096
|
+
} catch {
|
|
4097
|
+
return null;
|
|
4098
|
+
}
|
|
4099
|
+
};
|
|
4100
|
+
const stateKey = (storageKey, state) => `${storageKey}:${state}`;
|
|
4101
|
+
const readState = (key) => {
|
|
4102
|
+
try {
|
|
4103
|
+
const raw = storage()?.getItem(key);
|
|
4104
|
+
if (!raw) return null;
|
|
4105
|
+
const parsed = JSON.parse(raw);
|
|
4106
|
+
if (!parsed.redirectUri || !parsed.state || !parsed.codeVerifier) return null;
|
|
4107
|
+
return parsed;
|
|
4108
|
+
} catch {
|
|
4109
|
+
return null;
|
|
4110
|
+
}
|
|
4111
|
+
};
|
|
4112
|
+
/** Starts a browser app authorization-code flow and persists the PKCE secret in localStorage. */
|
|
4113
|
+
const beginBrowserAppAuth = async ({ callbackUrl, env, team, brand, storageKey = DEFAULT_BROWSER_APP_AUTH_STORAGE_KEY }) => {
|
|
4114
|
+
const auth = await createAppAuthRequest({
|
|
4115
|
+
callbackUrl,
|
|
4116
|
+
env,
|
|
4117
|
+
team,
|
|
4118
|
+
brand
|
|
4119
|
+
});
|
|
4120
|
+
const target = storage();
|
|
4121
|
+
if (!target) throw new Error("Local storage is unavailable.");
|
|
4122
|
+
target.setItem(stateKey(storageKey, auth.state), JSON.stringify({
|
|
4123
|
+
redirectUri: auth.redirectUri,
|
|
4124
|
+
state: auth.state,
|
|
4125
|
+
codeVerifier: auth.codeVerifier
|
|
4126
|
+
}));
|
|
4127
|
+
return auth.url;
|
|
4128
|
+
};
|
|
4129
|
+
/** Completes a browser app authorization-code flow and returns the exchanged bearer token. */
|
|
4130
|
+
const completeBrowserAppAuth = async ({ url, env, storageKey = DEFAULT_BROWSER_APP_AUTH_STORAGE_KEY }) => {
|
|
4131
|
+
const parsed = new URL(url);
|
|
4132
|
+
const code = parsed.searchParams.get("code");
|
|
4133
|
+
if (!code) return null;
|
|
4134
|
+
const state = parsed.searchParams.get("state");
|
|
4135
|
+
if (!state) throw new Error("Invalid app auth state.");
|
|
4136
|
+
const key = stateKey(storageKey, state);
|
|
4137
|
+
const stored = readState(key);
|
|
4138
|
+
if (!stored || state !== stored.state) {
|
|
4139
|
+
storage()?.removeItem(key);
|
|
4140
|
+
throw new Error("Invalid app auth state.");
|
|
4141
|
+
}
|
|
4142
|
+
const response = await exchangeAppAuthCode({
|
|
4143
|
+
code,
|
|
4144
|
+
redirectUri: stored.redirectUri,
|
|
4145
|
+
codeVerifier: stored.codeVerifier,
|
|
4146
|
+
env
|
|
4147
|
+
});
|
|
4148
|
+
storage()?.removeItem(key);
|
|
4149
|
+
if (!response.ok || !response.data?.token) throw new Error("App auth code exchange failed.");
|
|
4150
|
+
return response.data.token;
|
|
4151
|
+
};
|
|
4152
|
+
//#endregion
|
|
4033
4153
|
//#region src/auth/portal.ts
|
|
4034
4154
|
const getAuthFragmentToken = (url) => {
|
|
4035
4155
|
try {
|
|
@@ -4120,4 +4240,4 @@ var DistributionResource = class {
|
|
|
4120
4240
|
}
|
|
4121
4241
|
};
|
|
4122
4242
|
//#endregion
|
|
4123
|
-
export { AddressesResource, AgentsResource, AlertsResource, AnalyticsResource, ApiTokensResource, AppointmentsResource, AuditLogsResource, AuthResource, AutomationsResource, BillingResource, BlueprintsResource, CachedHttpService, CampaignsResource, CardsResource, CartsResource, ChangelogResource, CharactersResource, CheckoutResource, CommerceResource, ContactsResource, ContentResource, ContractsResource, DeskResource, DistributionResource, DocumentsResource, ElementsResource, EntitiesResource, ExportsResource, FlowsResource, FollowsResource, FulfillmentsResource, GoalsResource, GuestCheckoutError, GuestCouponError, HooksResource, IngestionsResource, InquiriesResource, InstallsResource, IntegrationsResource, IntentsResource, ItemsResource, JoAiClient, KvResource, LinksResource, LoyaltyResource, McpResource, MeetingsResource, MemoriesResource, MessagesResource, MetricsResource, MissionsResource, NotificationsResource, OfficeResource, OrdersResource, PersonaResource, ProductsResource, ProjectsResource, ProposalsResource, RemindersResource, ReturnsResource, SegmentsResource, ServicesResource, ShippingResource, ShortcutsResource, SitesResource, SkillsResource, SocialPostsResource, StatsResource, StoreResource, SubscriptionsResource, SwarmsResource, TagsResource, TasksResource, TaxClassesResource, TeamsResource, UpdatesResource, UpgradesResource, UsersResource, VoiceResource, WalletsResource, WarpsResource, WorkspaceResource, assertGuestCheckoutReady, assertGuestPickupSlotReady, buildGuestCheckoutSnapshotRequest, buildGuestOrderReturnUrl, completePortalSession, createClient, createEmptyGuestCheckoutState, createGuestCheckoutSnapshot, createGuestCommerceStorage, createRecentlyViewedStorage, formatOpeningHours, formatPickupSlotLabel, getAuthFragmentToken, getRecentlyViewedSlugs, guestCartAmounts, guestCouponMessageFromErrors, isAllowedRedirectUrl, isGuestCheckoutError, isGuestCouponError, isPortalCallbackUrl, openPortalSession, placeGuestCheckoutOrder, readGuestOrderReturnAccess, revalidateGuestCoupon, sanitizePortalCallbackUrl, stripGuestOrderReturnToken, toGuestCheckoutDraft, trackRecentlyViewed, validateGuestCoupon };
|
|
4243
|
+
export { AddressesResource, AgentsResource, AlertsResource, AnalyticsResource, ApiTokensResource, AppointmentsResource, AuditLogsResource, AuthResource, AutomationsResource, BillingResource, BlueprintsResource, CachedHttpService, CampaignsResource, CardsResource, CartsResource, ChangelogResource, CharactersResource, CheckoutResource, CommerceResource, ContactsResource, ContentResource, ContractsResource, DEFAULT_BROWSER_APP_AUTH_STORAGE_KEY, DeskResource, DistributionResource, DocumentsResource, ElementsResource, EntitiesResource, ExportsResource, FlowsResource, FollowsResource, FulfillmentsResource, GoalsResource, GuestCheckoutError, GuestCouponError, HooksResource, IngestionsResource, InquiriesResource, InstallsResource, IntegrationsResource, IntentsResource, ItemsResource, JoAiClient, KvResource, LinksResource, LoyaltyResource, McpResource, MeetingsResource, MemoriesResource, MessagesResource, MetricsResource, MissionsResource, NotificationsResource, OfficeResource, OrdersResource, PersonaResource, ProductsResource, ProjectsResource, ProposalsResource, RemindersResource, ReturnsResource, SegmentsResource, ServicesResource, ShippingResource, ShortcutsResource, SitesResource, SkillsResource, SocialPostsResource, StatsResource, StoreResource, SubscriptionsResource, SwarmsResource, TagsResource, TasksResource, TaxClassesResource, TeamsResource, UpdatesResource, UpgradesResource, UsersResource, VoiceResource, WalletsResource, WarpsResource, WorkspaceResource, assertGuestCheckoutReady, assertGuestPickupSlotReady, beginBrowserAppAuth, buildGuestCheckoutSnapshotRequest, buildGuestOrderReturnUrl, completeBrowserAppAuth, completePortalSession, createAppAuthRequest, createClient, createEmptyGuestCheckoutState, createGuestCheckoutSnapshot, createGuestCommerceStorage, createRecentlyViewedStorage, exchangeAppAuthCode, formatOpeningHours, formatPickupSlotLabel, getAuthFragmentToken, getRecentlyViewedSlugs, guestCartAmounts, guestCouponMessageFromErrors, isAllowedRedirectUrl, isGuestCheckoutError, isGuestCouponError, isPortalCallbackUrl, openPortalSession, placeGuestCheckoutOrder, readGuestOrderReturnAccess, revalidateGuestCoupon, sanitizePortalCallbackUrl, stripGuestOrderReturnToken, toGuestCheckoutDraft, trackRecentlyViewed, validateGuestCoupon };
|