azirid-react 0.13.0 → 0.13.2

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/dist/index.d.cts CHANGED
@@ -774,6 +774,29 @@ interface HandoffCallbackProps {
774
774
  loadingText?: string;
775
775
  errorText?: string;
776
776
  }
777
+ /**
778
+ * Standalone component for handling impersonation handoff redirects.
779
+ *
780
+ * Does NOT require AziridProvider — works independently by reading the
781
+ * API URL from the `&api=` query parameter and exchanging the handoff
782
+ * code directly. After exchanging, stores tokens in sessionStorage so
783
+ * AziridProvider picks them up on the next page load.
784
+ *
785
+ * Usage:
786
+ * ```tsx
787
+ * // app/auth/handoff/page.tsx
788
+ * import { HandoffCallback } from 'azirid-react'
789
+ *
790
+ * export default function HandoffPage() {
791
+ * return (
792
+ * <HandoffCallback
793
+ * onSuccess={() => window.location.href = '/'}
794
+ * onError={() => window.location.href = '/login'}
795
+ * />
796
+ * )
797
+ * }
798
+ * ```
799
+ */
777
800
  declare function HandoffCallback({ onSuccess, onError, loadingText, errorText, }: HandoffCallbackProps): react_jsx_runtime.JSX.Element;
778
801
 
779
802
  declare global {
@@ -914,7 +937,7 @@ interface AccessClient {
914
937
  /** Deduplicated bootstrap — safe to call from Strict Mode double-mounts */
915
938
  bootstrapSession: <T = unknown>() => Promise<T>;
916
939
  /** Exchange a one-time handoff code for session tokens (cross-domain impersonation) */
917
- exchangeHandoff: (code: string) => Promise<{
940
+ exchangeHandoff: (code: string, apiUrl?: string) => Promise<{
918
941
  user: unknown;
919
942
  }>;
920
943
  }
package/dist/index.d.ts CHANGED
@@ -774,6 +774,29 @@ interface HandoffCallbackProps {
774
774
  loadingText?: string;
775
775
  errorText?: string;
776
776
  }
777
+ /**
778
+ * Standalone component for handling impersonation handoff redirects.
779
+ *
780
+ * Does NOT require AziridProvider — works independently by reading the
781
+ * API URL from the `&api=` query parameter and exchanging the handoff
782
+ * code directly. After exchanging, stores tokens in sessionStorage so
783
+ * AziridProvider picks them up on the next page load.
784
+ *
785
+ * Usage:
786
+ * ```tsx
787
+ * // app/auth/handoff/page.tsx
788
+ * import { HandoffCallback } from 'azirid-react'
789
+ *
790
+ * export default function HandoffPage() {
791
+ * return (
792
+ * <HandoffCallback
793
+ * onSuccess={() => window.location.href = '/'}
794
+ * onError={() => window.location.href = '/login'}
795
+ * />
796
+ * )
797
+ * }
798
+ * ```
799
+ */
777
800
  declare function HandoffCallback({ onSuccess, onError, loadingText, errorText, }: HandoffCallbackProps): react_jsx_runtime.JSX.Element;
778
801
 
779
802
  declare global {
@@ -914,7 +937,7 @@ interface AccessClient {
914
937
  /** Deduplicated bootstrap — safe to call from Strict Mode double-mounts */
915
938
  bootstrapSession: <T = unknown>() => Promise<T>;
916
939
  /** Exchange a one-time handoff code for session tokens (cross-domain impersonation) */
917
- exchangeHandoff: (code: string) => Promise<{
940
+ exchangeHandoff: (code: string, apiUrl?: string) => Promise<{
918
941
  user: unknown;
919
942
  }>;
920
943
  }
package/dist/index.js CHANGED
@@ -384,7 +384,8 @@ function createAccessClient(config, appContext) {
384
384
  }
385
385
  return json;
386
386
  }
387
- async function exchangeHandoff(code) {
387
+ async function exchangeHandoff(code, apiUrl) {
388
+ const exchangeBase = apiUrl?.replace(/\/+$/, "") ?? baseUrl;
388
389
  const headers = {
389
390
  "Content-Type": "application/json",
390
391
  ...config.headers
@@ -394,7 +395,7 @@ function createAccessClient(config, appContext) {
394
395
  }
395
396
  const devId = getOrCreateDeviceId();
396
397
  if (devId) headers["X-Device-Id"] = devId;
397
- const res = await fetch(`${baseUrl}/v1/users/auth/handoff/exchange`, {
398
+ const res = await fetch(`${exchangeBase}/users/auth/handoff/exchange`, {
398
399
  method: "POST",
399
400
  headers,
400
401
  credentials: "include",
@@ -4005,7 +4006,6 @@ function HandoffCallback({
4005
4006
  loadingText = "Signing you in...",
4006
4007
  errorText = "Failed to complete sign-in. The link may have expired."
4007
4008
  }) {
4008
- const client = useAccessClient();
4009
4009
  const [status, setStatus] = useState("loading");
4010
4010
  const [errorMessage, setErrorMessage] = useState(null);
4011
4011
  const attempted = useRef(false);
@@ -4014,21 +4014,49 @@ function HandoffCallback({
4014
4014
  attempted.current = true;
4015
4015
  const params = new URLSearchParams(window.location.search);
4016
4016
  const code = params.get("code");
4017
+ const apiUrl = params.get("api");
4017
4018
  if (!code) {
4018
4019
  setStatus("error");
4019
4020
  setErrorMessage("No handoff code provided");
4020
4021
  onError?.(new Error("No handoff code provided"));
4021
4022
  return;
4022
4023
  }
4023
- client.exchangeHandoff(code).then((result) => {
4024
- onSuccess?.(result.user);
4024
+ if (!apiUrl) {
4025
+ setStatus("error");
4026
+ setErrorMessage("No API URL provided");
4027
+ onError?.(new Error("No API URL in handoff link"));
4028
+ return;
4029
+ }
4030
+ const exchangeUrl = `${apiUrl.replace(/\/+$/, "")}/users/auth/handoff/exchange`;
4031
+ fetch(exchangeUrl, {
4032
+ method: "POST",
4033
+ headers: { "Content-Type": "application/json" },
4034
+ credentials: "include",
4035
+ body: JSON.stringify({ code })
4036
+ }).then(async (res) => {
4037
+ if (!res.ok) {
4038
+ const body = await res.json().catch(() => null);
4039
+ throw new Error(body?.error?.message ?? body?.message ?? "Handoff exchange failed");
4040
+ }
4041
+ return res.json();
4042
+ }).then((raw) => {
4043
+ const json = raw && typeof raw === "object" && "data" in raw && "meta" in raw ? raw.data : raw;
4044
+ json.at ?? json.accessToken;
4045
+ const refreshToken = json.rt ?? json.refreshToken;
4046
+ const csrfToken = json.xc ?? json.csrfToken;
4047
+ try {
4048
+ if (refreshToken) sessionStorage.setItem("__azrt", refreshToken);
4049
+ if (csrfToken) sessionStorage.setItem("__azxc", csrfToken);
4050
+ } catch {
4051
+ }
4052
+ onSuccess?.(json.user);
4025
4053
  }).catch((err) => {
4026
4054
  setStatus("error");
4027
4055
  const error = err instanceof Error ? err : new Error("Handoff exchange failed");
4028
4056
  setErrorMessage(error.message);
4029
4057
  onError?.(error);
4030
4058
  });
4031
- }, [client, onSuccess, onError]);
4059
+ }, [onSuccess, onError]);
4032
4060
  if (status === "error") {
4033
4061
  return /* @__PURE__ */ jsx("div", { style: wrapperStyle, children: /* @__PURE__ */ jsx("p", { style: { ...messageStyle2, color: "#ef4444" }, children: errorMessage || errorText }) });
4034
4062
  }
@@ -4845,7 +4873,7 @@ function usePasswordToggle() {
4845
4873
  }
4846
4874
 
4847
4875
  // src/index.ts
4848
- var SDK_VERSION = "0.13.0";
4876
+ var SDK_VERSION = "0.13.2";
4849
4877
 
4850
4878
  export { AuthForm, AziridProvider, BASE_PATHS, CheckoutButton, ForgotPasswordForm, HandoffCallback, InvoiceList, LoginForm, PATHS, PayButton, PayphoneCallback, PayphoneWidgetRenderer, PricingTable, ReferralCard, ReferralStats, ResetPasswordForm, SDK_VERSION, SignupForm, SubscriptionBadge, buildPaths, changePasswordSchema, cn, createAccessClient, createForgotPasswordSchema, createLoginSchema, createMutationHook, createResetPasswordConfirmSchema, createSignupSchema, en, es, forgotPasswordSchema, isAuthError, loginSchema, magicLinkRequestSchema, magicLinkVerifySchema, passkeyRegisterStartSchema, removeStyles, resetPasswordConfirmSchema, resolveMessages, signupSchema, socialLoginSchema, useAccessClient, useAzirid, useBootstrap, useBranches, useBranding, useChangePassword, useCheckout, useFormState, useInvoices, useLogin, useLogout, useMagicLink, useMessages, usePasskeys, usePasswordReset, usePasswordToggle, usePayButton, usePaymentMethods, usePaymentProviders, usePayphoneCheckout, usePayphoneConfirm, usePlans, useReferral, useReferralStats, useRefresh, useSession, useSignup, useSocialLogin, useSubmitTransferProof, useSubscription, useSwitchTenant, useTenantMembers, useTenants, useTransferPayment, useTransferProofs, useUploadTransferProof };
4851
4879
  //# sourceMappingURL=index.js.map