From c19b51baaf396647f2d6b021e38f083768328b74 Mon Sep 17 00:00:00 2001
From: Divyam <47589864+divyam234@users.noreply.github.com>
Date: Mon, 21 Oct 2024 03:53:51 +0530
Subject: [PATCH] refactor(auth-js): session provider (#775)
* refactor: session provider
* format
---
.changeset/rotten-tips-camp.md | 5 +
packages/auth-js/README.md | 106 +++---
packages/auth-js/src/client.ts | 70 ++--
packages/auth-js/src/index.ts | 45 ++-
packages/auth-js/src/react.tsx | 531 +++++++++++++---------------
packages/auth-js/test/index.test.ts | 13 +-
6 files changed, 362 insertions(+), 408 deletions(-)
create mode 100644 .changeset/rotten-tips-camp.md
diff --git a/.changeset/rotten-tips-camp.md b/.changeset/rotten-tips-camp.md
new file mode 100644
index 000000000..542427d50
--- /dev/null
+++ b/.changeset/rotten-tips-camp.md
@@ -0,0 +1,5 @@
+---
+'@hono/auth-js': patch
+---
+
+refactor session provider
diff --git a/packages/auth-js/README.md b/packages/auth-js/README.md
index bfac2668e..d86661bf4 100644
--- a/packages/auth-js/README.md
+++ b/packages/auth-js/README.md
@@ -16,78 +16,72 @@ Before starting using the middleware you must set the following environment vari
```plain
AUTH_SECRET=#required
-AUTH_URL=#optional
+AUTH_URL=https://example.com/api/auth
```
## How to Use
```ts
-import { Hono, Context } from 'hono'
-import { authHandler, initAuthConfig, verifyAuth, type AuthConfig } from "@hono/auth-js"
-import GitHub from "@auth/core/providers/github"
+import { Hono } from 'hono'
+import { authHandler, initAuthConfig, verifyAuth } from '@hono/auth-js'
+import GitHub from '@auth/core/providers/github'
const app = new Hono()
-app.use("*", initAuthConfig(getAuthConfig))
+app.use(
+ '*',
+ initAuthConfig((c) => ({
+ secret: c.env.AUTH_SECRET,
+ providers: [
+ GitHub({
+ clientId: c.env.GITHUB_ID,
+ clientSecret: c.env.GITHUB_SECRET,
+ }),
+ ],
+ }))
+)
-app.use("/api/auth/*", authHandler())
+app.use('/api/auth/*', authHandler())
app.use('/api/*', verifyAuth())
app.get('/api/protected', (c) => {
- const auth = c.get("authUser")
+ const auth = c.get('authUser')
return c.json(auth)
})
-function getAuthConfig(c: Context): AuthConfig {
- return {
- secret: c.env.AUTH_SECRET,
- providers: [
- GitHub({
- clientId: c.env.GITHUB_ID,
- clientSecret: c.env.GITHUB_SECRET
- }),
- ]
- }
-}
-
export default app
```
React component
-```tsx
-import { SessionProvider } from "@hono/auth-js/react"
-export default function App() {
+```tsx
+import { SessionProvider, useSession } from '@hono/auth-js/react'
+export default function App() {
return (
, - options?: SignInOptions, - authorizationParams?: SignInAuthorizationParams + options: SignInOptions = {}, + authorizationParams: SignInAuthorizationParams = {} ): Promise
{
- const { callbackUrl = window.location.href, redirect = true } = options ?? {}
+ const { callbackUrl = window.location.href, redirect = true, ...opts } = options
- const __AUTHJS: AuthClientConfig = authConfigManager.getConfig()
+ const config = authConfigManager.getConfig()
- const href = `${__AUTHJS.baseUrl}${__AUTHJS.basePath}`
+ const href = `${config.baseUrl}${config.basePath}`
const providers = await getProviders()
-
if (!providers) {
window.location.href = `${href}/error`
return
}
if (!provider || !(provider in providers)) {
- window.location.href = `${href}/signin?${new URLSearchParams({
- callbackUrl,
- })}`
+ window.location.href = `${href}/signin?${new URLSearchParams({ callbackUrl })}`
return
}
const isCredentials = providers[provider].type === 'credentials'
const isEmail = providers[provider].type === 'email'
- const isSupportingReturn = isCredentials || isEmail
const signInUrl = `${href}/${isCredentials ? 'callback' : 'signin'}/${provider}`
const csrfToken = await getCsrfToken()
const res = await fetch(`${signInUrl}?${new URLSearchParams(authorizationParams)}`, {
- method: 'post',
+ method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Auth-Return-Redirect': '1',
},
- // @ts-expect-error TODO: Fix this
- body: new URLSearchParams({ ...options, csrfToken, callbackUrl }),
- credentials: __AUTHJS.credentials,
+ body: new URLSearchParams({ ...opts, csrfToken, callbackUrl }),
+ credentials: config.credentials,
})
- const data = await res.json()
+ const data = (await res.json()) as { url: string }
- // TODO: Do not redirect for Credentials and Email providers by default in next major
- if (redirect || !isSupportingReturn) {
- const url = (data as any).url ?? callbackUrl
+ if (redirect) {
+ const url = data.url ?? callbackUrl
window.location.href = url
- // If url contains a hash, the browser does not reload the page. We reload manually
+
if (url.includes('#')) {
window.location.reload()
}
return
}
- const error = new URL((data as any).url).searchParams.get('error')
+ const error = new URL(data.url).searchParams.get('error')
if (res.ok) {
- await __AUTHJS._getSession({ event: 'storage' })
+ await config.fetchSession?.({ event: 'storage' })
}
return {
error,
status: res.status,
ok: res.ok,
- url: error ? null : (data as any).url,
- } as any
+ url: error ? null : data.url,
+ } as P extends RedirectableProviderType ? SignInResponse : undefined
}
-/**
- * Initiate a signout, by destroying the current session.
- * Handles CSRF protection.
- */
export async function signOut