@drmhse/authos-react 0.2.1 → 0.2.3

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 CHANGED
@@ -146,10 +146,14 @@ Registration form for new users.
146
146
  <SignUp
147
147
  onSuccess={() => console.log('Check your email!')}
148
148
  onError={(error) => console.error(error)}
149
- orgSlug="my-org" // Optional: pre-fill organization
149
+ orgSlug="my-org" // Optional: override provider config
150
+ serviceSlug="my-app" // Optional: override provider config
150
151
  />
151
152
  ```
152
153
 
154
+ > [!NOTE]
155
+ > The `orgSlug` and `serviceSlug` props are optional and will fallback to the values configured in `AuthOSProvider`. Only use these props if you need to override the provider configuration for a specific use case.
156
+
153
157
  ### MagicLinkSignIn
154
158
 
155
159
  Sign-in component for Magic Links (passwordless).
@@ -228,6 +232,31 @@ Individual OAuth provider button. Requires `org` and `service` in provider confi
228
232
  <OAuthButton provider="google">Continue with Google</OAuthButton>
229
233
  ```
230
234
 
235
+ ### Callback
236
+
237
+ Required for OAuth flows. Handles the redirect from the identity provider by parsing tokens from the URL fragment and setting the session.
238
+
239
+ ```tsx
240
+ import { Callback } from '@drmhse/authos-react';
241
+
242
+ function CallbackPage() {
243
+ const router = useRouter();
244
+
245
+ return (
246
+ <Callback
247
+ onSuccess={() => router.push('/')}
248
+ onError={(error) => console.error(error)}
249
+ />
250
+ );
251
+ }
252
+ ```
253
+
254
+ **Props:**
255
+ | Prop | Type | Default | Description |
256
+ |------|------|---------|-------------|
257
+ | `onSuccess` | `() => void` | - | Callback after session is successfully set |
258
+ | `onError` | `(error: Error) => void` | - | Callback on error |
259
+
231
260
  ## Hooks
232
261
 
233
262
  ### useAuthOS
package/dist/index.d.mts CHANGED
@@ -283,6 +283,19 @@ interface SignedOutProps {
283
283
  /** Content to render when user is signed out */
284
284
  children: React.ReactNode;
285
285
  }
286
+ /**
287
+ * Props for the Callback component
288
+ */
289
+ interface CallbackProps {
290
+ /** Callback when session is successfully set */
291
+ onSuccess?: () => void;
292
+ /** Callback when session setting fails */
293
+ onError?: (error: Error) => void;
294
+ /** Custom render function for the callback state */
295
+ children?: (props: {
296
+ error: string | null;
297
+ }) => React.ReactNode;
298
+ }
286
299
 
287
300
  /**
288
301
  * Provider component that wraps your app and provides AuthOS context.
@@ -723,4 +736,6 @@ interface PasskeySignInProps {
723
736
  */
724
737
  declare function PasskeySignIn({ onSuccess, onError, className, showPasswordSignIn, }: PasskeySignInProps): react_jsx_runtime.JSX.Element;
725
738
 
726
- export { type AuthOSConfig, type AuthOSContextState, AuthOSProvider, type AuthOSProviderProps, MagicLinkSignIn, type MagicLinkSignInProps, OAuthButton, type OAuthButtonProps, OrganizationSwitcher, type OrganizationSwitcherProps, PasskeySignIn, type PasskeySignInProps, Protect, type ProtectProps, SignIn, type SignInProps, SignUp, type SignUpProps, SignedIn, type SignedInProps, SignedOut, type SignedOutProps, type SupportedOAuthProvider, UserButton, type UserButtonProps, useAllPermissions, useAnyPermission, useAuthOS, useAuthOSContext, useOrganization, usePermission, useUser };
739
+ declare function Callback({ onSuccess, onError, children }: CallbackProps): react_jsx_runtime.JSX.Element;
740
+
741
+ export { type AuthOSConfig, type AuthOSContextState, AuthOSProvider, type AuthOSProviderProps, Callback, type CallbackProps, MagicLinkSignIn, type MagicLinkSignInProps, OAuthButton, type OAuthButtonProps, OrganizationSwitcher, type OrganizationSwitcherProps, PasskeySignIn, type PasskeySignInProps, Protect, type ProtectProps, SignIn, type SignInProps, SignUp, type SignUpProps, SignedIn, type SignedInProps, SignedOut, type SignedOutProps, type SupportedOAuthProvider, UserButton, type UserButtonProps, useAllPermissions, useAnyPermission, useAuthOS, useAuthOSContext, useOrganization, usePermission, useUser };
package/dist/index.d.ts CHANGED
@@ -283,6 +283,19 @@ interface SignedOutProps {
283
283
  /** Content to render when user is signed out */
284
284
  children: React.ReactNode;
285
285
  }
286
+ /**
287
+ * Props for the Callback component
288
+ */
289
+ interface CallbackProps {
290
+ /** Callback when session is successfully set */
291
+ onSuccess?: () => void;
292
+ /** Callback when session setting fails */
293
+ onError?: (error: Error) => void;
294
+ /** Custom render function for the callback state */
295
+ children?: (props: {
296
+ error: string | null;
297
+ }) => React.ReactNode;
298
+ }
286
299
 
287
300
  /**
288
301
  * Provider component that wraps your app and provides AuthOS context.
@@ -723,4 +736,6 @@ interface PasskeySignInProps {
723
736
  */
724
737
  declare function PasskeySignIn({ onSuccess, onError, className, showPasswordSignIn, }: PasskeySignInProps): react_jsx_runtime.JSX.Element;
725
738
 
726
- export { type AuthOSConfig, type AuthOSContextState, AuthOSProvider, type AuthOSProviderProps, MagicLinkSignIn, type MagicLinkSignInProps, OAuthButton, type OAuthButtonProps, OrganizationSwitcher, type OrganizationSwitcherProps, PasskeySignIn, type PasskeySignInProps, Protect, type ProtectProps, SignIn, type SignInProps, SignUp, type SignUpProps, SignedIn, type SignedInProps, SignedOut, type SignedOutProps, type SupportedOAuthProvider, UserButton, type UserButtonProps, useAllPermissions, useAnyPermission, useAuthOS, useAuthOSContext, useOrganization, usePermission, useUser };
739
+ declare function Callback({ onSuccess, onError, children }: CallbackProps): react_jsx_runtime.JSX.Element;
740
+
741
+ export { type AuthOSConfig, type AuthOSContextState, AuthOSProvider, type AuthOSProviderProps, Callback, type CallbackProps, MagicLinkSignIn, type MagicLinkSignInProps, OAuthButton, type OAuthButtonProps, OrganizationSwitcher, type OrganizationSwitcherProps, PasskeySignIn, type PasskeySignInProps, Protect, type ProtectProps, SignIn, type SignInProps, SignUp, type SignUpProps, SignedIn, type SignedInProps, SignedOut, type SignedOutProps, type SupportedOAuthProvider, UserButton, type UserButtonProps, useAllPermissions, useAnyPermission, useAuthOS, useAuthOSContext, useOrganization, usePermission, useUser };
package/dist/index.js CHANGED
@@ -568,6 +568,16 @@ function AuthOSProvider({ config, children, client: externalClient, initialSessi
568
568
  if (config.appearance?.variables) {
569
569
  applyVariables(config.appearance.variables);
570
570
  }
571
+ if (config.org && !config.service) {
572
+ console.warn(
573
+ '[AuthOS] You provided "org" but not "service". OAuth flows may not work correctly.'
574
+ );
575
+ }
576
+ if (!config.org && config.service) {
577
+ console.warn(
578
+ '[AuthOS] You provided "service" but not "org". OAuth flows may not work correctly.'
579
+ );
580
+ }
571
581
  }, [config.appearance]);
572
582
  const hasInitialToken = react.useRef(!!initialSessionToken);
573
583
  react.useEffect(() => {
@@ -946,8 +956,8 @@ function SignUp({
946
956
  await client.auth.register({
947
957
  email,
948
958
  password,
949
- org_slug: orgSlug,
950
- service_slug: serviceSlug
959
+ org_slug: orgSlug ?? config.org,
960
+ service_slug: serviceSlug ?? config.service
951
961
  });
952
962
  setIsSuccess(true);
953
963
  onSuccess?.();
@@ -1377,6 +1387,51 @@ function PasskeySignIn({
1377
1387
  showPasswordSignIn && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-authos-signin-prompt": "", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: "/signin", "data-authos-link": "signin", children: "Sign in with password" }) })
1378
1388
  ] }) });
1379
1389
  }
1390
+ function Callback({ onSuccess, onError, children }) {
1391
+ const { client } = useAuthOSContext();
1392
+ const [error, setError] = react.useState(null);
1393
+ const processedRef = react.useRef(false);
1394
+ react.useEffect(() => {
1395
+ if (processedRef.current || !client) return;
1396
+ const processCallback = async () => {
1397
+ processedRef.current = true;
1398
+ const hash = window.location.hash.substring(1);
1399
+ const params = new URLSearchParams(hash);
1400
+ const accessToken = params.get("access_token");
1401
+ const refreshToken = params.get("refresh_token");
1402
+ const errorParam = params.get("error");
1403
+ const errorDescription = params.get("error_description");
1404
+ if (errorParam) {
1405
+ const msg = errorDescription || errorParam;
1406
+ setError(msg);
1407
+ onError?.(new Error(msg));
1408
+ return;
1409
+ }
1410
+ if (accessToken) {
1411
+ try {
1412
+ await client.setSession({
1413
+ access_token: accessToken,
1414
+ refresh_token: refreshToken || void 0
1415
+ });
1416
+ onSuccess?.();
1417
+ } catch (err) {
1418
+ const message = err.message || "Failed to set session";
1419
+ setError(message);
1420
+ onError?.(err instanceof Error ? err : new Error(message));
1421
+ }
1422
+ } else {
1423
+ const message = "No authentication tokens found in callback URL.";
1424
+ setError(message);
1425
+ onError?.(new Error(message));
1426
+ }
1427
+ };
1428
+ processCallback();
1429
+ }, [client, onSuccess, onError]);
1430
+ if (children) {
1431
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children({ error }) });
1432
+ }
1433
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-authos-callback": "", children: error ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-authos-error": "", children: error }) : /* @__PURE__ */ jsxRuntime.jsx("div", { "data-authos-loading": "", children: "Completing sign in..." }) });
1434
+ }
1380
1435
 
1381
1436
  Object.defineProperty(exports, "AuthErrorCodes", {
1382
1437
  enumerable: true,
@@ -1391,6 +1446,7 @@ Object.defineProperty(exports, "SsoClient", {
1391
1446
  get: function () { return ssoSdk.SsoClient; }
1392
1447
  });
1393
1448
  exports.AuthOSProvider = AuthOSProvider;
1449
+ exports.Callback = Callback;
1394
1450
  exports.MagicLinkSignIn = MagicLinkSignIn;
1395
1451
  exports.OAuthButton = OAuthButton;
1396
1452
  exports.OrganizationSwitcher = OrganizationSwitcher;
package/dist/index.mjs CHANGED
@@ -567,6 +567,16 @@ function AuthOSProvider({ config, children, client: externalClient, initialSessi
567
567
  if (config.appearance?.variables) {
568
568
  applyVariables(config.appearance.variables);
569
569
  }
570
+ if (config.org && !config.service) {
571
+ console.warn(
572
+ '[AuthOS] You provided "org" but not "service". OAuth flows may not work correctly.'
573
+ );
574
+ }
575
+ if (!config.org && config.service) {
576
+ console.warn(
577
+ '[AuthOS] You provided "service" but not "org". OAuth flows may not work correctly.'
578
+ );
579
+ }
570
580
  }, [config.appearance]);
571
581
  const hasInitialToken = useRef(!!initialSessionToken);
572
582
  useEffect(() => {
@@ -945,8 +955,8 @@ function SignUp({
945
955
  await client.auth.register({
946
956
  email,
947
957
  password,
948
- org_slug: orgSlug,
949
- service_slug: serviceSlug
958
+ org_slug: orgSlug ?? config.org,
959
+ service_slug: serviceSlug ?? config.service
950
960
  });
951
961
  setIsSuccess(true);
952
962
  onSuccess?.();
@@ -1376,5 +1386,50 @@ function PasskeySignIn({
1376
1386
  showPasswordSignIn && /* @__PURE__ */ jsx("div", { "data-authos-signin-prompt": "", children: /* @__PURE__ */ jsx("a", { href: "/signin", "data-authos-link": "signin", children: "Sign in with password" }) })
1377
1387
  ] }) });
1378
1388
  }
1389
+ function Callback({ onSuccess, onError, children }) {
1390
+ const { client } = useAuthOSContext();
1391
+ const [error, setError] = useState(null);
1392
+ const processedRef = useRef(false);
1393
+ useEffect(() => {
1394
+ if (processedRef.current || !client) return;
1395
+ const processCallback = async () => {
1396
+ processedRef.current = true;
1397
+ const hash = window.location.hash.substring(1);
1398
+ const params = new URLSearchParams(hash);
1399
+ const accessToken = params.get("access_token");
1400
+ const refreshToken = params.get("refresh_token");
1401
+ const errorParam = params.get("error");
1402
+ const errorDescription = params.get("error_description");
1403
+ if (errorParam) {
1404
+ const msg = errorDescription || errorParam;
1405
+ setError(msg);
1406
+ onError?.(new Error(msg));
1407
+ return;
1408
+ }
1409
+ if (accessToken) {
1410
+ try {
1411
+ await client.setSession({
1412
+ access_token: accessToken,
1413
+ refresh_token: refreshToken || void 0
1414
+ });
1415
+ onSuccess?.();
1416
+ } catch (err) {
1417
+ const message = err.message || "Failed to set session";
1418
+ setError(message);
1419
+ onError?.(err instanceof Error ? err : new Error(message));
1420
+ }
1421
+ } else {
1422
+ const message = "No authentication tokens found in callback URL.";
1423
+ setError(message);
1424
+ onError?.(new Error(message));
1425
+ }
1426
+ };
1427
+ processCallback();
1428
+ }, [client, onSuccess, onError]);
1429
+ if (children) {
1430
+ return /* @__PURE__ */ jsx(Fragment, { children: children({ error }) });
1431
+ }
1432
+ return /* @__PURE__ */ jsx("div", { "data-authos-callback": "", children: error ? /* @__PURE__ */ jsx("div", { "data-authos-error": "", children: error }) : /* @__PURE__ */ jsx("div", { "data-authos-loading": "", children: "Completing sign in..." }) });
1433
+ }
1379
1434
 
1380
- export { AuthOSProvider, MagicLinkSignIn, OAuthButton, OrganizationSwitcher, PasskeySignIn, Protect, SignIn, SignUp, SignedIn, SignedOut, UserButton, useAllPermissions, useAnyPermission, useAuthOS, useAuthOSContext, useOrganization, usePermission, useUser };
1435
+ export { AuthOSProvider, Callback, MagicLinkSignIn, OAuthButton, OrganizationSwitcher, PasskeySignIn, Protect, SignIn, SignUp, SignedIn, SignedOut, UserButton, useAllPermissions, useAnyPermission, useAuthOS, useAuthOSContext, useOrganization, usePermission, useUser };