@hono/auth-js 1.0.11 → 1.0.13

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
@@ -16,78 +16,72 @@ Before starting using the middleware you must set the following environment vari
16
16
 
17
17
  ```plain
18
18
  AUTH_SECRET=#required
19
- AUTH_URL=#optional
19
+ AUTH_URL=https://example.com/api/auth
20
20
  ```
21
21
 
22
22
  ## How to Use
23
23
 
24
24
  ```ts
25
- import { Hono, Context } from 'hono'
26
- import { authHandler, initAuthConfig, verifyAuth, type AuthConfig } from "@hono/auth-js"
27
- import GitHub from "@auth/core/providers/github"
25
+ import { Hono } from 'hono'
26
+ import { authHandler, initAuthConfig, verifyAuth } from '@hono/auth-js'
27
+ import GitHub from '@auth/core/providers/github'
28
28
 
29
29
  const app = new Hono()
30
30
 
31
- app.use("*", initAuthConfig(getAuthConfig))
31
+ app.use(
32
+ '*',
33
+ initAuthConfig((c) => ({
34
+ secret: c.env.AUTH_SECRET,
35
+ providers: [
36
+ GitHub({
37
+ clientId: c.env.GITHUB_ID,
38
+ clientSecret: c.env.GITHUB_SECRET,
39
+ }),
40
+ ],
41
+ }))
42
+ )
32
43
 
33
- app.use("/api/auth/*", authHandler())
44
+ app.use('/api/auth/*', authHandler())
34
45
 
35
46
  app.use('/api/*', verifyAuth())
36
47
 
37
48
  app.get('/api/protected', (c) => {
38
- const auth = c.get("authUser")
49
+ const auth = c.get('authUser')
39
50
  return c.json(auth)
40
51
  })
41
52
 
42
- function getAuthConfig(c: Context): AuthConfig {
43
- return {
44
- secret: c.env.AUTH_SECRET,
45
- providers: [
46
- GitHub({
47
- clientId: c.env.GITHUB_ID,
48
- clientSecret: c.env.GITHUB_SECRET
49
- }),
50
- ]
51
- }
52
- }
53
-
54
53
  export default app
55
54
  ```
56
55
 
57
56
  React component
58
- ```tsx
59
- import { SessionProvider } from "@hono/auth-js/react"
60
57
 
61
- export default function App() {
58
+ ```tsx
59
+ import { SessionProvider, useSession } from '@hono/auth-js/react'
62
60
 
61
+ export default function App() {
63
62
  return (
64
63
  <SessionProvider>
65
- <Children />
64
+ <Children />
66
65
  </SessionProvider>
67
66
  )
68
67
  }
69
68
 
70
69
  function Children() {
71
70
  const { data: session, status } = useSession()
72
- return (
73
- <div >
74
- I am {session?.user}
75
- </div>
76
- )
71
+ return <div>I am {session?.user}</div>
77
72
  }
78
73
  ```
74
+
79
75
  Default `/api/auth` path can be changed to something else but that will also require you to change path in react app.
80
76
 
81
77
  ```tsx
82
- import {SessionProvider,authConfigManager,useSession } from "@hono/auth-js/react"
78
+ import { SessionProvider, authConfigManager, useSession } from '@hono/auth-js/react'
83
79
 
84
80
  authConfigManager.setConfig({
85
- baseUrl: '', //needed for cross domain setup.
86
81
  basePath: '/custom', // if auth route is diff from /api/auth
87
- credentials:'same-origin' //needed for cross domain setup
88
- });
82
+ })
89
83
 
90
- export default function App() {
84
+ export default function App() {
91
85
  return (
92
86
  <SessionProvider>
93
87
  <Children />
@@ -97,47 +91,28 @@ export default function App() {
97
91
 
98
92
  function Children() {
99
93
  const { data: session, status } = useSession()
100
- return (
101
- <div >
102
- I am {session?.user}
103
- </div>
104
- )
94
+ return <div>I am {session?.user}</div>
105
95
  }
106
96
  ```
107
- For cross domain setup as mentioned above you need to set these cors headers in hono along with change in same site cookie attribute.[Read More Here](https://next-auth.js.org/configuration/options#cookies)
108
- ``` ts
109
- app.use(
110
- "*",
111
- cors({
112
- origin: (origin) => origin,
113
- allowHeaders: ["Content-Type"],
114
- credentials: true,
115
- })
116
- )
117
- ```
118
-
119
97
 
120
- SessionProvider is not needed with react query.This wrapper is enough
98
+ SessionProvider is not needed with react query.Use useQuery hook to fetch session data.
121
99
 
122
100
  ```ts
123
- const useSession = ()=>{
124
- const { data ,status } = useQuery({
125
- queryKey: ["session"],
126
- queryFn: async () => {
127
- const res = await fetch("/api/auth/session")
128
- return res.json();
129
- },
130
- staleTime: 5 * (60 * 1000),
131
- gcTime: 10 * (60 * 1000),
132
- refetchOnWindowFocus: true,
133
- })
134
- return { session:data, status }
101
+ const useSession = () => {
102
+ const { data, status } = useQuery({
103
+ queryKey: ['session'],
104
+ queryFn: async () => {
105
+ const res = await fetch('/api/auth/session')
106
+ return res.json()
107
+ },
108
+ staleTime: 5 * (60 * 1000),
109
+ gcTime: 10 * (60 * 1000),
110
+ refetchOnWindowFocus: true,
111
+ })
112
+ return { session: data, status }
135
113
  }
136
114
  ```
137
- > [!WARNING]
138
- > You can't use event updates which SessionProvider provides and session will not be in sync across tabs if you use react query wrapper but in RQ5 you can enable this using Broadcast channel (see RQ docs).
139
-
140
- Working example repo https://github.com/divyam234/next-auth-hono-react
115
+ For more details on how to Popup Oauth Login see [example](https://github.com/divyam234/next-auth-hono-react)
141
116
 
142
117
  ## Author
143
118
 
package/dist/index.d.mts CHANGED
@@ -25,7 +25,7 @@ interface AuthConfig extends Omit<AuthConfig$1, 'raw'> {
25
25
  }
26
26
  type ConfigHandler = (c: Context) => AuthConfig;
27
27
  declare function setEnvDefaults(env: AuthEnv, config: AuthConfig): void;
28
- declare function reqWithEnvUrl(req: Request, authUrl?: string): Promise<Request>;
28
+ declare function reqWithEnvUrl(req: Request, authUrl?: string): Request;
29
29
  declare function getAuthUser(c: Context): Promise<AuthUser | null>;
30
30
  declare function verifyAuth(): MiddlewareHandler;
31
31
  declare function initAuthConfig(cb: ConfigHandler): MiddlewareHandler;
package/dist/index.d.ts CHANGED
@@ -25,7 +25,7 @@ interface AuthConfig extends Omit<AuthConfig$1, 'raw'> {
25
25
  }
26
26
  type ConfigHandler = (c: Context) => AuthConfig;
27
27
  declare function setEnvDefaults(env: AuthEnv, config: AuthConfig): void;
28
- declare function reqWithEnvUrl(req: Request, authUrl?: string): Promise<Request>;
28
+ declare function reqWithEnvUrl(req: Request, authUrl?: string): Request;
29
29
  declare function getAuthUser(c: Context): Promise<AuthUser | null>;
30
30
  declare function verifyAuth(): MiddlewareHandler;
31
31
  declare function initAuthConfig(cb: ConfigHandler): MiddlewareHandler;
package/dist/index.js CHANGED
@@ -36,61 +36,41 @@ function setEnvDefaults(env2, config) {
36
36
  config.secret ??= env2.AUTH_SECRET;
37
37
  (0, import_core2.setEnvDefaults)(env2, config);
38
38
  }
39
- async function cloneRequest(input, request, headers) {
40
- if ((0, import_adapter.getRuntimeKey)() === "bun") {
41
- return new Request(input, {
42
- method: request.method,
43
- headers: headers ?? new Headers(request.headers),
44
- body: request.method === "GET" || request.method === "HEAD" ? void 0 : await request.blob(),
45
- // @ts-ignore: TS2353
46
- referrer: "referrer" in request ? request.referrer : void 0,
47
- // deno-lint-ignore no-explicit-any
48
- referrerPolicy: request.referrerPolicy,
49
- mode: request.mode,
50
- credentials: request.credentials,
51
- // @ts-ignore: TS2353
52
- cache: request.cache,
53
- redirect: request.redirect,
54
- integrity: request.integrity,
55
- keepalive: request.keepalive,
56
- signal: request.signal
57
- });
58
- }
59
- return new Request(input, request);
60
- }
61
- async function reqWithEnvUrl(req, authUrl) {
39
+ function reqWithEnvUrl(req, authUrl) {
62
40
  if (authUrl) {
63
41
  const reqUrlObj = new URL(req.url);
64
42
  const authUrlObj = new URL(authUrl);
65
43
  const props = ["hostname", "protocol", "port", "password", "username"];
66
- props.forEach((prop) => reqUrlObj[prop] = authUrlObj[prop]);
67
- return cloneRequest(reqUrlObj.href, req);
68
- } else {
69
- const url = new URL(req.url);
70
- const headers = new Headers(req.headers);
71
- const proto = headers.get("x-forwarded-proto");
72
- const host = headers.get("x-forwarded-host") ?? headers.get("host");
73
- if (proto != null)
74
- url.protocol = proto.endsWith(":") ? proto : proto + ":";
75
- if (host != null) {
76
- url.host = host;
77
- const portMatch = host.match(/:(\d+)$/);
78
- if (portMatch)
79
- url.port = portMatch[1];
80
- else
81
- url.port = "";
82
- headers.delete("x-forwarded-host");
83
- headers.delete("Host");
84
- headers.set("Host", host);
44
+ for (const prop of props) {
45
+ if (authUrlObj[prop])
46
+ reqUrlObj[prop] = authUrlObj[prop];
85
47
  }
86
- return cloneRequest(url.href, req, headers);
48
+ return new Request(reqUrlObj.href, req);
49
+ }
50
+ const newReq = new Request(req);
51
+ const url = new URL(newReq.url);
52
+ const proto = newReq.headers.get("x-forwarded-proto");
53
+ const host = newReq.headers.get("x-forwarded-host") ?? newReq.headers.get("host");
54
+ if (proto != null)
55
+ url.protocol = proto.endsWith(":") ? proto : `${proto}:`;
56
+ if (host != null) {
57
+ url.host = host;
58
+ const portMatch = host.match(/:(\d+)$/);
59
+ if (portMatch)
60
+ url.port = portMatch[1];
61
+ else
62
+ url.port = "";
63
+ newReq.headers.delete("x-forwarded-host");
64
+ newReq.headers.delete("Host");
65
+ newReq.headers.set("Host", host);
87
66
  }
67
+ return new Request(url.href, newReq);
88
68
  }
89
69
  async function getAuthUser(c) {
90
70
  const config = c.get("authConfig");
91
71
  const ctxEnv = (0, import_adapter.env)(c);
92
72
  setEnvDefaults(ctxEnv, config);
93
- const authReq = await reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL);
73
+ const authReq = reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL);
94
74
  const origin = new URL(authReq.url).origin;
95
75
  const request = new Request(`${origin}${config.basePath}/session`, {
96
76
  headers: { cookie: c.req.header("cookie") ?? "" }
@@ -109,7 +89,7 @@ async function getAuthUser(c) {
109
89
  }
110
90
  });
111
91
  const session = await response.json();
112
- return session && session.user ? authUser : null;
92
+ return session?.user ? authUser : null;
113
93
  }
114
94
  function verifyAuth() {
115
95
  return async (c, next) => {
@@ -120,9 +100,8 @@ function verifyAuth() {
120
100
  status: 401
121
101
  });
122
102
  throw new import_http_exception.HTTPException(401, { res });
123
- } else {
124
- c.set("authUser", authUser);
125
103
  }
104
+ c.set("authUser", authUser);
126
105
  await next();
127
106
  };
128
107
  }
@@ -141,8 +120,7 @@ function authHandler() {
141
120
  if (!config.secret || config.secret.length === 0) {
142
121
  throw new import_http_exception.HTTPException(500, { message: "Missing AUTH_SECRET" });
143
122
  }
144
- const authReq = await reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL);
145
- const res = await (0, import_core.Auth)(authReq, config);
123
+ const res = await (0, import_core.Auth)(reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL), config);
146
124
  return new Response(res.body, res);
147
125
  };
148
126
  }
package/dist/index.mjs CHANGED
@@ -1,67 +1,47 @@
1
1
  // src/index.ts
2
2
  import { Auth } from "@auth/core";
3
- import { env, getRuntimeKey } from "hono/adapter";
3
+ import { env } from "hono/adapter";
4
4
  import { HTTPException } from "hono/http-exception";
5
5
  import { setEnvDefaults as coreSetEnvDefaults } from "@auth/core";
6
6
  function setEnvDefaults(env2, config) {
7
7
  config.secret ??= env2.AUTH_SECRET;
8
8
  coreSetEnvDefaults(env2, config);
9
9
  }
10
- async function cloneRequest(input, request, headers) {
11
- if (getRuntimeKey() === "bun") {
12
- return new Request(input, {
13
- method: request.method,
14
- headers: headers ?? new Headers(request.headers),
15
- body: request.method === "GET" || request.method === "HEAD" ? void 0 : await request.blob(),
16
- // @ts-ignore: TS2353
17
- referrer: "referrer" in request ? request.referrer : void 0,
18
- // deno-lint-ignore no-explicit-any
19
- referrerPolicy: request.referrerPolicy,
20
- mode: request.mode,
21
- credentials: request.credentials,
22
- // @ts-ignore: TS2353
23
- cache: request.cache,
24
- redirect: request.redirect,
25
- integrity: request.integrity,
26
- keepalive: request.keepalive,
27
- signal: request.signal
28
- });
29
- }
30
- return new Request(input, request);
31
- }
32
- async function reqWithEnvUrl(req, authUrl) {
10
+ function reqWithEnvUrl(req, authUrl) {
33
11
  if (authUrl) {
34
12
  const reqUrlObj = new URL(req.url);
35
13
  const authUrlObj = new URL(authUrl);
36
14
  const props = ["hostname", "protocol", "port", "password", "username"];
37
- props.forEach((prop) => reqUrlObj[prop] = authUrlObj[prop]);
38
- return cloneRequest(reqUrlObj.href, req);
39
- } else {
40
- const url = new URL(req.url);
41
- const headers = new Headers(req.headers);
42
- const proto = headers.get("x-forwarded-proto");
43
- const host = headers.get("x-forwarded-host") ?? headers.get("host");
44
- if (proto != null)
45
- url.protocol = proto.endsWith(":") ? proto : proto + ":";
46
- if (host != null) {
47
- url.host = host;
48
- const portMatch = host.match(/:(\d+)$/);
49
- if (portMatch)
50
- url.port = portMatch[1];
51
- else
52
- url.port = "";
53
- headers.delete("x-forwarded-host");
54
- headers.delete("Host");
55
- headers.set("Host", host);
15
+ for (const prop of props) {
16
+ if (authUrlObj[prop])
17
+ reqUrlObj[prop] = authUrlObj[prop];
56
18
  }
57
- return cloneRequest(url.href, req, headers);
19
+ return new Request(reqUrlObj.href, req);
20
+ }
21
+ const newReq = new Request(req);
22
+ const url = new URL(newReq.url);
23
+ const proto = newReq.headers.get("x-forwarded-proto");
24
+ const host = newReq.headers.get("x-forwarded-host") ?? newReq.headers.get("host");
25
+ if (proto != null)
26
+ url.protocol = proto.endsWith(":") ? proto : `${proto}:`;
27
+ if (host != null) {
28
+ url.host = host;
29
+ const portMatch = host.match(/:(\d+)$/);
30
+ if (portMatch)
31
+ url.port = portMatch[1];
32
+ else
33
+ url.port = "";
34
+ newReq.headers.delete("x-forwarded-host");
35
+ newReq.headers.delete("Host");
36
+ newReq.headers.set("Host", host);
58
37
  }
38
+ return new Request(url.href, newReq);
59
39
  }
60
40
  async function getAuthUser(c) {
61
41
  const config = c.get("authConfig");
62
42
  const ctxEnv = env(c);
63
43
  setEnvDefaults(ctxEnv, config);
64
- const authReq = await reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL);
44
+ const authReq = reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL);
65
45
  const origin = new URL(authReq.url).origin;
66
46
  const request = new Request(`${origin}${config.basePath}/session`, {
67
47
  headers: { cookie: c.req.header("cookie") ?? "" }
@@ -80,7 +60,7 @@ async function getAuthUser(c) {
80
60
  }
81
61
  });
82
62
  const session = await response.json();
83
- return session && session.user ? authUser : null;
63
+ return session?.user ? authUser : null;
84
64
  }
85
65
  function verifyAuth() {
86
66
  return async (c, next) => {
@@ -91,9 +71,8 @@ function verifyAuth() {
91
71
  status: 401
92
72
  });
93
73
  throw new HTTPException(401, { res });
94
- } else {
95
- c.set("authUser", authUser);
96
74
  }
75
+ c.set("authUser", authUser);
97
76
  await next();
98
77
  };
99
78
  }
@@ -112,8 +91,7 @@ function authHandler() {
112
91
  if (!config.secret || config.secret.length === 0) {
113
92
  throw new HTTPException(500, { message: "Missing AUTH_SECRET" });
114
93
  }
115
- const authReq = await reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL);
116
- const res = await Auth(authReq, config);
94
+ const res = await Auth(reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL), config);
117
95
  return new Response(res.body, res);
118
96
  };
119
97
  }
package/dist/react.d.mts CHANGED
@@ -1,14 +1,18 @@
1
1
  import { BuiltInProviderType, ProviderType, RedirectableProviderType } from '@auth/core/providers';
2
2
  import { Session } from '@auth/core/types';
3
- import * as React from 'react';
3
+ import * as React$1 from 'react';
4
4
 
5
+ interface GetSessionParams {
6
+ event?: 'storage' | 'timer' | 'hidden' | string;
7
+ triggerEvent?: boolean;
8
+ }
5
9
  interface AuthClientConfig {
6
10
  baseUrl: string;
7
11
  basePath: string;
8
- credentials?: RequestCredentials;
9
- _session?: Session | null | undefined;
10
- _lastSync: number;
11
- _getSession: (...args: any[]) => any;
12
+ credentials: RequestCredentials;
13
+ lastSync: number;
14
+ session: Session | null;
15
+ fetchSession: (params?: GetSessionParams) => Promise<void>;
12
16
  }
13
17
  interface UseSessionOptions<R extends boolean> {
14
18
  required: R;
@@ -23,13 +27,7 @@ interface ClientSafeProvider {
23
27
  callbackUrl: string;
24
28
  }
25
29
  interface SignInOptions extends Record<string, unknown> {
26
- /**
27
- * Specify to which URL the user will be redirected after signing in. Defaults to the page URL the sign-in is initiated from.
28
- *
29
- * [Documentation](https://next-auth.js.org/getting-started/client#specifying-a-callbackurl)
30
- */
31
30
  callbackUrl?: string;
32
- /** [Documentation](https://next-auth.js.org/getting-started/client#using-the-redirect-false-option) */
33
31
  redirect?: boolean;
34
32
  }
35
33
  interface SignInResponse {
@@ -43,29 +41,16 @@ interface SignOutResponse {
43
41
  url: string;
44
42
  }
45
43
  interface SignOutParams<R extends boolean = true> {
46
- /** [Documentation](https://next-auth.js.org/getting-started/client#specifying-a-callbackurl-1) */
47
44
  callbackUrl?: string;
48
- /** [Documentation](https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */
49
45
  redirect?: R;
50
46
  }
51
47
  interface SessionProviderProps {
52
48
  children: React.ReactNode;
53
49
  session?: Session | null;
54
- baseUrl?: string;
55
- basePath?: string;
56
50
  refetchInterval?: number;
57
51
  refetchOnWindowFocus?: boolean;
58
52
  refetchWhenOffline?: false;
59
53
  }
60
-
61
- declare class AuthConfigManager {
62
- private static instance;
63
- _config: AuthClientConfig;
64
- static getInstance(): AuthConfigManager;
65
- setConfig(userConfig: Partial<AuthClientConfig>): void;
66
- getConfig(): AuthClientConfig;
67
- }
68
- declare const authConfigManager: AuthConfigManager;
69
54
  type UpdateSession = (data?: any) => Promise<Session | null>;
70
55
  type SessionContextValue<R extends boolean = false> = R extends true ? {
71
56
  update: UpdateSession;
@@ -84,31 +69,49 @@ type SessionContextValue<R extends boolean = false> = R extends true ? {
84
69
  data: null;
85
70
  status: 'unauthenticated' | 'loading';
86
71
  };
87
- declare const SessionContext: React.Context<{
72
+ type WindowProps = {
73
+ url: string;
74
+ title: string;
75
+ width: number;
76
+ height: number;
77
+ };
78
+
79
+ declare class AuthConfigManager {
80
+ private static instance;
81
+ private config;
82
+ private constructor();
83
+ private createDefaultConfig;
84
+ static getInstance(): AuthConfigManager;
85
+ setConfig(userConfig: Partial<AuthClientConfig>): void;
86
+ getConfig(): AuthClientConfig;
87
+ initializeConfig(hasInitialSession: boolean): void;
88
+ }
89
+ declare const authConfigManager: AuthConfigManager;
90
+ declare const SessionContext: React$1.Context<{
88
91
  update: UpdateSession;
89
92
  data: Session;
90
- status: 'authenticated';
93
+ status: "authenticated";
91
94
  } | {
92
95
  update: UpdateSession;
93
96
  data: null;
94
- status: 'unauthenticated' | 'loading';
97
+ status: "loading" | "unauthenticated";
95
98
  } | undefined>;
96
- declare function useSession<R extends boolean>(options?: UseSessionOptions<R>): SessionContextValue<R>;
97
- interface GetSessionParams {
98
- event?: 'storage' | 'timer' | 'hidden' | string;
99
- triggerEvent?: boolean;
100
- broadcast?: boolean;
101
- }
102
99
  declare function getSession(params?: GetSessionParams): Promise<Session | null>;
103
100
  declare function getCsrfToken(): Promise<string>;
101
+ declare function SessionProvider(props: SessionProviderProps): React$1.JSX.Element;
102
+ declare function useSession<R extends boolean>(options?: UseSessionOptions<R>): SessionContextValue<R>;
104
103
  type ProvidersType = Record<LiteralUnion<BuiltInProviderType>, ClientSafeProvider>;
105
104
  declare function getProviders(): Promise<ProvidersType | null>;
106
105
  declare function signIn<P extends RedirectableProviderType | undefined = undefined>(provider?: LiteralUnion<P extends RedirectableProviderType ? P | BuiltInProviderType : BuiltInProviderType>, options?: SignInOptions, authorizationParams?: SignInAuthorizationParams): Promise<P extends RedirectableProviderType ? SignInResponse | undefined : undefined>;
107
- /**
108
- * Initiate a signout, by destroying the current session.
109
- * Handles CSRF protection.
110
- */
111
106
  declare function signOut<R extends boolean = true>(options?: SignOutParams<R>): Promise<R extends true ? undefined : SignOutResponse>;
112
- declare function SessionProvider(props: SessionProviderProps): React.JSX.Element;
107
+ interface PopupLoginOptions extends Partial<Omit<WindowProps, 'url'>> {
108
+ onSuccess?: () => void;
109
+ callbackUrl?: string;
110
+ }
111
+ declare const useOauthPopupLogin: (provider: Parameters<typeof signIn>[0], options?: PopupLoginOptions) => {
112
+ status: "loading" | "success" | "errored";
113
+ error?: string | undefined;
114
+ popUpSignin: () => Promise<void>;
115
+ };
113
116
 
114
- export { type GetSessionParams, type LiteralUnion, SessionContext, type SessionContextValue, SessionProvider, type SessionProviderProps, type SignInAuthorizationParams, type SignInOptions, type SignInResponse, type SignOutParams, type UpdateSession, authConfigManager, getCsrfToken, getProviders, getSession, signIn, signOut, useSession };
117
+ export { SessionContext, SessionProvider, authConfigManager, getCsrfToken, getProviders, getSession, signIn, signOut, useOauthPopupLogin, useSession };