@drmhse/authos-react 0.1.3 → 0.1.5

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.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createContext, useRef, useEffect, useState, useCallback, useMemo, useContext } from 'react';
2
2
  import { SsoClient, SsoApiError } from '@drmhse/sso-sdk';
3
3
  export { AuthErrorCodes, SsoApiError, SsoClient } from '@drmhse/sso-sdk';
4
- import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  // src/context.tsx
7
7
  var AuthOSContext = createContext(null);
@@ -49,6 +49,7 @@ function AuthOSProvider({ config, children, client: externalClient, initialSessi
49
49
  const contextValue = useMemo(
50
50
  () => ({
51
51
  client,
52
+ config,
52
53
  user,
53
54
  isAuthenticated: !!user,
54
55
  isLoading,
@@ -57,7 +58,7 @@ function AuthOSProvider({ config, children, client: externalClient, initialSessi
57
58
  setOrganization,
58
59
  refreshUser
59
60
  }),
60
- [client, user, isLoading, organization, refreshUser]
61
+ [client, config, user, isLoading, organization, refreshUser]
61
62
  );
62
63
  return /* @__PURE__ */ jsx(AuthOSContext.Provider, { value: contextValue, children });
63
64
  }
@@ -84,8 +85,12 @@ function useOrganization() {
84
85
  const { client, organization, setOrganization, refreshUser } = useAuthOSContext();
85
86
  const switchOrganization = useCallback(
86
87
  async (slug) => {
87
- const orgResponse = await client.organizations.get(slug);
88
- setOrganization(orgResponse.organization);
88
+ const result = await client.organizations.select(slug);
89
+ await client.setSession({
90
+ access_token: result.access_token,
91
+ refresh_token: result.refresh_token
92
+ });
93
+ setOrganization(result.organization);
89
94
  await refreshUser();
90
95
  },
91
96
  [client, setOrganization, refreshUser]
@@ -113,15 +118,71 @@ function useAllPermissions(permissions) {
113
118
  return permissions.every((perm) => user.permissions.includes(perm));
114
119
  }, [user?.permissions, permissions]);
115
120
  }
121
+ var PROVIDER_NAMES = {
122
+ github: "GitHub",
123
+ google: "Google",
124
+ microsoft: "Microsoft"
125
+ };
126
+ function OAuthButton({
127
+ provider,
128
+ children,
129
+ className,
130
+ onRedirect,
131
+ disabled = false
132
+ }) {
133
+ const { client, config } = useAuthOSContext();
134
+ const handleClick = useCallback(() => {
135
+ if (!config.org || !config.service) {
136
+ console.error(
137
+ `[AuthOS] OAuth login requires "org" and "service" in AuthOSProvider config.
138
+ Current config: { org: ${config.org ? `"${config.org}"` : "undefined"}, service: ${config.service ? `"${config.service}"` : "undefined"} }
139
+
140
+ Example:
141
+ <AuthOSProvider config={{
142
+ baseURL: "${config.baseURL}",
143
+ org: "your-org-slug",
144
+ service: "your-service-slug",
145
+ }}>
146
+
147
+ See: https://docs.authos.dev/react/oauth-setup`
148
+ );
149
+ return;
150
+ }
151
+ const redirectUri = config.redirectUri ?? (typeof window !== "undefined" ? window.location.origin + "/callback" : void 0);
152
+ const url = client.auth.getLoginUrl(provider, {
153
+ org: config.org,
154
+ service: config.service,
155
+ redirect_uri: redirectUri
156
+ });
157
+ onRedirect?.();
158
+ window.location.href = url;
159
+ }, [client, config, provider, onRedirect]);
160
+ return /* @__PURE__ */ jsx(
161
+ "button",
162
+ {
163
+ type: "button",
164
+ onClick: handleClick,
165
+ className,
166
+ disabled,
167
+ "data-authos-oauth": "",
168
+ "data-provider": provider,
169
+ children: children ?? `Continue with ${PROVIDER_NAMES[provider]}`
170
+ }
171
+ );
172
+ }
116
173
  var MFA_PREAUTH_EXPIRY = 300;
117
174
  function SignIn({
118
175
  onSuccess,
119
176
  onError,
120
177
  showForgotPassword = true,
121
178
  showSignUp = true,
122
- className
179
+ className,
180
+ providers = false,
181
+ showDivider = true
123
182
  }) {
124
- const { client, setUser } = useAuthOSContext();
183
+ const { client, config, setUser } = useAuthOSContext();
184
+ const hasOAuthConfig = !!(config.org && config.service);
185
+ const oauthProviders = providers && Array.isArray(providers) ? providers : [];
125
186
  const [state, setState] = useState("credentials");
126
187
  const [email, setEmail] = useState("");
127
188
  const [password, setPassword] = useState("");
@@ -135,7 +196,12 @@ function SignIn({
135
196
  setError(null);
136
197
  setIsLoading(true);
137
198
  try {
138
- const result = await client.auth.login({ email, password });
199
+ const result = await client.auth.login({
200
+ email,
201
+ password,
202
+ org_slug: config.org,
203
+ service_slug: config.service
204
+ });
139
205
  if (result.expires_in === MFA_PREAUTH_EXPIRY) {
140
206
  setPreauthToken(result.access_token);
141
207
  setState("mfa");
@@ -152,7 +218,7 @@ function SignIn({
152
218
  setIsLoading(false);
153
219
  }
154
220
  },
155
- [client, email, password, setUser, onSuccess, onError]
221
+ [client, email, password, config.org, config.service, setUser, onSuccess, onError]
156
222
  );
157
223
  const handleMfaSubmit = useCallback(
158
224
  async (e) => {
@@ -204,49 +270,63 @@ function SignIn({
204
270
  /* @__PURE__ */ jsx("button", { type: "button", onClick: handleBackToCredentials, "data-authos-back": "", children: "Back to login" })
205
271
  ] }) });
206
272
  }
207
- return /* @__PURE__ */ jsx("div", { className, "data-authos-signin": "", "data-state": "credentials", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleCredentialsSubmit, children: [
208
- /* @__PURE__ */ jsxs("div", { "data-authos-field": "email", children: [
209
- /* @__PURE__ */ jsx("label", { htmlFor: "authos-email", children: "Email" }),
210
- /* @__PURE__ */ jsx(
211
- "input",
212
- {
213
- id: "authos-email",
214
- type: "email",
215
- autoComplete: "email",
216
- value: email,
217
- onChange: (e) => setEmail(e.target.value),
218
- placeholder: "Enter your email",
219
- required: true,
220
- disabled: isLoading
221
- }
222
- )
223
- ] }),
224
- /* @__PURE__ */ jsxs("div", { "data-authos-field": "password", children: [
225
- /* @__PURE__ */ jsx("label", { htmlFor: "authos-password", children: "Password" }),
226
- /* @__PURE__ */ jsx(
227
- "input",
273
+ return /* @__PURE__ */ jsxs("div", { className, "data-authos-signin": "", "data-state": "credentials", children: [
274
+ oauthProviders.length > 0 && /* @__PURE__ */ jsxs("div", { "data-authos-oauth-section": "", children: [
275
+ oauthProviders.map((provider) => /* @__PURE__ */ jsx(
276
+ OAuthButton,
228
277
  {
229
- id: "authos-password",
230
- type: "password",
231
- autoComplete: "current-password",
232
- value: password,
233
- onChange: (e) => setPassword(e.target.value),
234
- placeholder: "Enter your password",
235
- required: true,
236
- disabled: isLoading
237
- }
238
- )
278
+ provider,
279
+ disabled: isLoading || !hasOAuthConfig
280
+ },
281
+ provider
282
+ )),
283
+ !hasOAuthConfig && /* @__PURE__ */ jsx("p", { "data-authos-oauth-warning": "", style: { color: "orange", fontSize: "0.875rem" }, children: "OAuth requires org and service in AuthOSProvider config" })
239
284
  ] }),
240
- error && /* @__PURE__ */ jsx("div", { "data-authos-error": true, children: error }),
241
- /* @__PURE__ */ jsx("button", { type: "submit", disabled: isLoading, "data-authos-submit": "", children: isLoading ? "Signing in..." : "Sign In" }),
242
- showForgotPassword && /* @__PURE__ */ jsx("a", { href: "/forgot-password", "data-authos-link": "forgot-password", children: "Forgot password?" }),
243
- showSignUp && /* @__PURE__ */ jsxs("div", { "data-authos-signup-prompt": true, children: [
244
- "Don't have an account? ",
245
- /* @__PURE__ */ jsx("a", { href: "/signup", "data-authos-link": "signup", children: "Sign up" })
285
+ oauthProviders.length > 0 && showDivider && /* @__PURE__ */ jsx("div", { "data-authos-divider": "", children: /* @__PURE__ */ jsx("span", { children: "or" }) }),
286
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleCredentialsSubmit, children: [
287
+ /* @__PURE__ */ jsxs("div", { "data-authos-field": "email", children: [
288
+ /* @__PURE__ */ jsx("label", { htmlFor: "authos-email", children: "Email" }),
289
+ /* @__PURE__ */ jsx(
290
+ "input",
291
+ {
292
+ id: "authos-email",
293
+ type: "email",
294
+ autoComplete: "email",
295
+ value: email,
296
+ onChange: (e) => setEmail(e.target.value),
297
+ placeholder: "Enter your email",
298
+ required: true,
299
+ disabled: isLoading
300
+ }
301
+ )
302
+ ] }),
303
+ /* @__PURE__ */ jsxs("div", { "data-authos-field": "password", children: [
304
+ /* @__PURE__ */ jsx("label", { htmlFor: "authos-password", children: "Password" }),
305
+ /* @__PURE__ */ jsx(
306
+ "input",
307
+ {
308
+ id: "authos-password",
309
+ type: "password",
310
+ autoComplete: "current-password",
311
+ value: password,
312
+ onChange: (e) => setPassword(e.target.value),
313
+ placeholder: "Enter your password",
314
+ required: true,
315
+ disabled: isLoading
316
+ }
317
+ )
318
+ ] }),
319
+ error && /* @__PURE__ */ jsx("div", { "data-authos-error": true, children: error }),
320
+ /* @__PURE__ */ jsx("button", { type: "submit", disabled: isLoading, "data-authos-submit": "", children: isLoading ? "Signing in..." : "Sign In" }),
321
+ showForgotPassword && /* @__PURE__ */ jsx("a", { href: "/forgot-password", "data-authos-link": "forgot-password", children: "Forgot password?" }),
322
+ showSignUp && /* @__PURE__ */ jsxs("div", { "data-authos-signup-prompt": true, children: [
323
+ "Don't have an account? ",
324
+ /* @__PURE__ */ jsx("a", { href: "/signup", "data-authos-link": "signup", children: "Sign up" })
325
+ ] })
246
326
  ] })
247
- ] }) });
327
+ ] });
248
328
  }
249
- function SignUp({ onSuccess, onError, orgSlug, showSignIn = true, className }) {
329
+ function SignUp({ onSuccess, onError, orgSlug, serviceSlug, showSignIn = true, className }) {
250
330
  const { client } = useAuthOSContext();
251
331
  const [email, setEmail] = useState("");
252
332
  const [password, setPassword] = useState("");
@@ -271,7 +351,8 @@ function SignUp({ onSuccess, onError, orgSlug, showSignIn = true, className }) {
271
351
  await client.auth.register({
272
352
  email,
273
353
  password,
274
- org_slug: orgSlug
354
+ org_slug: orgSlug,
355
+ service_slug: serviceSlug
275
356
  });
276
357
  setIsSuccess(true);
277
358
  onSuccess?.();
@@ -283,7 +364,7 @@ function SignUp({ onSuccess, onError, orgSlug, showSignIn = true, className }) {
283
364
  setIsLoading(false);
284
365
  }
285
366
  },
286
- [client, email, password, confirmPassword, orgSlug, onSuccess, onError]
367
+ [client, email, password, confirmPassword, orgSlug, serviceSlug, onSuccess, onError]
287
368
  );
288
369
  if (isSuccess) {
289
370
  return /* @__PURE__ */ jsx("div", { className, "data-authos-signup": true, "data-state": "success", children: /* @__PURE__ */ jsxs("div", { "data-authos-success": true, children: [
@@ -533,5 +614,159 @@ function Protect({ permission, role, fallback = null, children }) {
533
614
  };
534
615
  return /* @__PURE__ */ jsx("div", { "data-authos-protect": true, children: renderContent() });
535
616
  }
617
+ function SignedIn({ children }) {
618
+ const { isAuthenticated, isLoading } = useAuthOSContext();
619
+ if (isLoading) {
620
+ return null;
621
+ }
622
+ if (!isAuthenticated) {
623
+ return null;
624
+ }
625
+ return /* @__PURE__ */ jsx(Fragment, { children });
626
+ }
627
+ function SignedOut({ children }) {
628
+ const { isAuthenticated, isLoading } = useAuthOSContext();
629
+ if (isLoading) {
630
+ return null;
631
+ }
632
+ if (isAuthenticated) {
633
+ return null;
634
+ }
635
+ return /* @__PURE__ */ jsx(Fragment, { children });
636
+ }
637
+ function MagicLinkSignIn({
638
+ onSuccess,
639
+ onError,
640
+ className,
641
+ showPasswordSignIn = true
642
+ }) {
643
+ const { client } = useAuthOSContext();
644
+ const [email, setEmail] = useState("");
645
+ const [isLoading, setIsLoading] = useState(false);
646
+ const [error, setError] = useState(null);
647
+ const [isSent, setIsSent] = useState(false);
648
+ const handleSubmit = useCallback(
649
+ async (e) => {
650
+ e.preventDefault();
651
+ setError(null);
652
+ setIsLoading(true);
653
+ try {
654
+ await client.magicLinks.request({ email });
655
+ setIsSent(true);
656
+ onSuccess?.();
657
+ } catch (err) {
658
+ const message = err instanceof SsoApiError ? err.message : "Failed to send magic link";
659
+ setError(message);
660
+ onError?.(err instanceof Error ? err : new Error(message));
661
+ } finally {
662
+ setIsLoading(false);
663
+ }
664
+ },
665
+ [client, email, onSuccess, onError]
666
+ );
667
+ if (isSent) {
668
+ return /* @__PURE__ */ jsxs("div", { className, "data-authos-magic-link": "", "data-state": "sent", children: [
669
+ /* @__PURE__ */ jsxs("div", { "data-authos-success": "", children: [
670
+ /* @__PURE__ */ jsx("p", { children: "Check your email!" }),
671
+ /* @__PURE__ */ jsxs("p", { children: [
672
+ "We sent a login link to ",
673
+ /* @__PURE__ */ jsx("strong", { children: email })
674
+ ] })
675
+ ] }),
676
+ /* @__PURE__ */ jsx(
677
+ "button",
678
+ {
679
+ type: "button",
680
+ onClick: () => setIsSent(false),
681
+ "data-authos-back": "",
682
+ children: "Use a different email"
683
+ }
684
+ )
685
+ ] });
686
+ }
687
+ return /* @__PURE__ */ jsx("div", { className, "data-authos-magic-link": "", "data-state": "form", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
688
+ /* @__PURE__ */ jsxs("div", { "data-authos-field": "email", children: [
689
+ /* @__PURE__ */ jsx("label", { htmlFor: "authos-magic-email", children: "Email" }),
690
+ /* @__PURE__ */ jsx(
691
+ "input",
692
+ {
693
+ id: "authos-magic-email",
694
+ type: "email",
695
+ autoComplete: "email",
696
+ value: email,
697
+ onChange: (e) => setEmail(e.target.value),
698
+ placeholder: "Enter your email",
699
+ required: true,
700
+ disabled: isLoading
701
+ }
702
+ )
703
+ ] }),
704
+ error && /* @__PURE__ */ jsx("div", { "data-authos-error": "", children: error }),
705
+ /* @__PURE__ */ jsx("button", { type: "submit", disabled: isLoading, "data-authos-submit": "", children: isLoading ? "Sending..." : "Send Magic Link" }),
706
+ showPasswordSignIn && /* @__PURE__ */ jsx("div", { "data-authos-signin-prompt": "", children: /* @__PURE__ */ jsx("a", { href: "/signin", "data-authos-link": "signin", children: "Sign in with password" }) })
707
+ ] }) });
708
+ }
709
+ function PasskeySignIn({
710
+ onSuccess,
711
+ onError,
712
+ className,
713
+ showPasswordSignIn = true
714
+ }) {
715
+ const { client, setUser } = useAuthOSContext();
716
+ const [email, setEmail] = useState("");
717
+ const [isLoading, setIsLoading] = useState(false);
718
+ const [error, setError] = useState(null);
719
+ const [isSupported, setIsSupported] = useState(true);
720
+ useEffect(() => {
721
+ setIsSupported(client.passkeys.isSupported());
722
+ }, [client]);
723
+ const handleSubmit = useCallback(
724
+ async (e) => {
725
+ e.preventDefault();
726
+ setError(null);
727
+ setIsLoading(true);
728
+ try {
729
+ await client.passkeys.login(email);
730
+ const profile = await client.user.getProfile();
731
+ setUser(profile);
732
+ onSuccess?.();
733
+ } catch (err) {
734
+ const message = err instanceof SsoApiError ? err.message : err instanceof Error ? err.message : "Passkey authentication failed";
735
+ setError(message);
736
+ onError?.(err instanceof Error ? err : new Error(message));
737
+ } finally {
738
+ setIsLoading(false);
739
+ }
740
+ },
741
+ [client, email, setUser, onSuccess, onError]
742
+ );
743
+ if (!isSupported) {
744
+ return /* @__PURE__ */ jsxs("div", { className, "data-authos-passkey": "", "data-state": "unsupported", children: [
745
+ /* @__PURE__ */ jsx("div", { "data-authos-error": "", children: "Passkeys are not supported in this browser." }),
746
+ showPasswordSignIn && /* @__PURE__ */ jsx("a", { href: "/signin", "data-authos-link": "signin", children: "Sign in with password" })
747
+ ] });
748
+ }
749
+ return /* @__PURE__ */ jsx("div", { className, "data-authos-passkey": "", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
750
+ /* @__PURE__ */ jsxs("div", { "data-authos-field": "email", children: [
751
+ /* @__PURE__ */ jsx("label", { htmlFor: "authos-passkey-email", children: "Email" }),
752
+ /* @__PURE__ */ jsx(
753
+ "input",
754
+ {
755
+ id: "authos-passkey-email",
756
+ type: "email",
757
+ autoComplete: "email webauthn",
758
+ value: email,
759
+ onChange: (e) => setEmail(e.target.value),
760
+ placeholder: "Enter your email",
761
+ required: true,
762
+ disabled: isLoading
763
+ }
764
+ )
765
+ ] }),
766
+ error && /* @__PURE__ */ jsx("div", { "data-authos-error": "", children: error }),
767
+ /* @__PURE__ */ jsx("button", { type: "submit", disabled: isLoading, "data-authos-submit": "", children: isLoading ? "Authenticating..." : "Sign in with Passkey" }),
768
+ showPasswordSignIn && /* @__PURE__ */ jsx("div", { "data-authos-signin-prompt": "", children: /* @__PURE__ */ jsx("a", { href: "/signin", "data-authos-link": "signin", children: "Sign in with password" }) })
769
+ ] }) });
770
+ }
536
771
 
537
- export { AuthOSProvider, OrganizationSwitcher, Protect, SignIn, SignUp, UserButton, useAllPermissions, useAnyPermission, useAuthOS, useAuthOSContext, useOrganization, usePermission, useUser };
772
+ export { AuthOSProvider, MagicLinkSignIn, OAuthButton, OrganizationSwitcher, PasskeySignIn, Protect, SignIn, SignUp, SignedIn, SignedOut, UserButton, useAllPermissions, useAnyPermission, useAuthOS, useAuthOSContext, useOrganization, usePermission, useUser };
package/dist/nextjs.d.mts CHANGED
@@ -226,4 +226,33 @@ declare function createAuthOSClient(options: CreateAuthOSClientOptions): SsoClie
226
226
  */
227
227
  declare function createServerClient(token: string, baseURL: string): SsoClient;
228
228
 
229
- export { type AuthMiddlewareConfig, type AuthState, type AuthUser, type CreateAuthOSClientOptions, auth, authMiddleware, createAuthOSClient, createServerClient, currentUser, getToken };
229
+ /**
230
+ * Utility functions for Next.js integration
231
+ */
232
+ /**
233
+ * Construct the JWKS URL from a base URL.
234
+ *
235
+ * This helper simplifies middleware configuration by deriving the JWKS URL
236
+ * from the same base URL used in your client-side configuration.
237
+ *
238
+ * @param baseURL - The base URL of your AuthOS instance
239
+ * @returns The full JWKS URL
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * // middleware.ts
244
+ * import { getJwksUrl, authMiddleware } from '@drmhse/authos-react/nextjs';
245
+ *
246
+ * export default authMiddleware({
247
+ * jwksUrl: getJwksUrl(process.env.NEXT_PUBLIC_AUTHOS_URL!),
248
+ * protectedRoutes: ['/dashboard/*'],
249
+ * });
250
+ * ```
251
+ */
252
+ declare function getJwksUrl(baseURL: string): string;
253
+ /**
254
+ * Get the base URL without trailing slash
255
+ */
256
+ declare function normalizeBaseUrl(baseURL: string): string;
257
+
258
+ export { type AuthMiddlewareConfig, type AuthState, type AuthUser, type CreateAuthOSClientOptions, auth, authMiddleware, createAuthOSClient, createServerClient, currentUser, getJwksUrl, getToken, normalizeBaseUrl };
package/dist/nextjs.d.ts CHANGED
@@ -226,4 +226,33 @@ declare function createAuthOSClient(options: CreateAuthOSClientOptions): SsoClie
226
226
  */
227
227
  declare function createServerClient(token: string, baseURL: string): SsoClient;
228
228
 
229
- export { type AuthMiddlewareConfig, type AuthState, type AuthUser, type CreateAuthOSClientOptions, auth, authMiddleware, createAuthOSClient, createServerClient, currentUser, getToken };
229
+ /**
230
+ * Utility functions for Next.js integration
231
+ */
232
+ /**
233
+ * Construct the JWKS URL from a base URL.
234
+ *
235
+ * This helper simplifies middleware configuration by deriving the JWKS URL
236
+ * from the same base URL used in your client-side configuration.
237
+ *
238
+ * @param baseURL - The base URL of your AuthOS instance
239
+ * @returns The full JWKS URL
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * // middleware.ts
244
+ * import { getJwksUrl, authMiddleware } from '@drmhse/authos-react/nextjs';
245
+ *
246
+ * export default authMiddleware({
247
+ * jwksUrl: getJwksUrl(process.env.NEXT_PUBLIC_AUTHOS_URL!),
248
+ * protectedRoutes: ['/dashboard/*'],
249
+ * });
250
+ * ```
251
+ */
252
+ declare function getJwksUrl(baseURL: string): string;
253
+ /**
254
+ * Get the base URL without trailing slash
255
+ */
256
+ declare function normalizeBaseUrl(baseURL: string): string;
257
+
258
+ export { type AuthMiddlewareConfig, type AuthState, type AuthUser, type CreateAuthOSClientOptions, auth, authMiddleware, createAuthOSClient, createServerClient, currentUser, getJwksUrl, getToken, normalizeBaseUrl };
package/dist/nextjs.js CHANGED
@@ -5903,9 +5903,20 @@ function createServerClient(token, baseURL) {
5903
5903
  });
5904
5904
  }
5905
5905
 
5906
+ // src/nextjs/utils.ts
5907
+ function getJwksUrl(baseURL) {
5908
+ const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
5909
+ return `${base}/.well-known/jwks.json`;
5910
+ }
5911
+ function normalizeBaseUrl(baseURL) {
5912
+ return baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
5913
+ }
5914
+
5906
5915
  exports.auth = auth;
5907
5916
  exports.authMiddleware = authMiddleware;
5908
5917
  exports.createAuthOSClient = createAuthOSClient;
5909
5918
  exports.createServerClient = createServerClient;
5910
5919
  exports.currentUser = currentUser;
5920
+ exports.getJwksUrl = getJwksUrl;
5911
5921
  exports.getToken = getToken;
5922
+ exports.normalizeBaseUrl = normalizeBaseUrl;
package/dist/nextjs.mjs CHANGED
@@ -5901,4 +5901,13 @@ function createServerClient(token, baseURL) {
5901
5901
  });
5902
5902
  }
5903
5903
 
5904
- export { auth, authMiddleware, createAuthOSClient, createServerClient, currentUser, getToken };
5904
+ // src/nextjs/utils.ts
5905
+ function getJwksUrl(baseURL) {
5906
+ const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
5907
+ return `${base}/.well-known/jwks.json`;
5908
+ }
5909
+ function normalizeBaseUrl(baseURL) {
5910
+ return baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
5911
+ }
5912
+
5913
+ export { auth, authMiddleware, createAuthOSClient, createServerClient, currentUser, getJwksUrl, getToken, normalizeBaseUrl };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drmhse/authos-react",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "React and Next.js adapter for AuthOS authentication",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -68,6 +68,6 @@
68
68
  "access": "public"
69
69
  },
70
70
  "dependencies": {
71
- "@drmhse/sso-sdk": "^0.3.4"
71
+ "@drmhse/sso-sdk": "^0.3.10"
72
72
  }
73
73
  }