fix(auth-js): use HonoRequest.blob() instead of HonoRequest.raw.body() (#1170)

* fix(auth-js): use HonoRequest.blob() instead of HonoRequest.raw.body()

* lint fix and format fix

---------

Co-authored-by: Yusuke Wada <yusuke@kamawada.com>
pull/1172/head
Danial Hanif 2025-05-17 10:17:28 +08:00 committed by GitHub
parent 7a45d5749d
commit 7585969171
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 149 additions and 1 deletions

View File

@ -0,0 +1,5 @@
---
'@hono/auth-js': patch
---
fix(auth-js): use HonoRequest.blob() instead of HonoRequest.raw.body()

View File

@ -2,6 +2,7 @@ import { skipCSRFCheck } from '@auth/core'
import type { Adapter } from '@auth/core/adapters'
import Credentials from '@auth/core/providers/credentials'
import { Hono } from 'hono'
import { validator } from 'hono/validator'
import { describe, expect, it, vi } from 'vitest'
import type { AuthConfig } from '.'
import { authHandler, verifyAuth, initAuthConfig, reqWithEnvUrl } from '.'
@ -80,6 +81,128 @@ describe('reqWithEnvUrl()', async () => {
it('Should rewrite the base path', () => {
expect(newReq.url.toString()).toBe('https://auth-url-base/request-path')
})
const mockAdapter: Adapter = {
createVerificationToken: vi.fn(),
useVerificationToken: vi.fn(),
getUserByEmail: vi.fn(),
createUser: vi.fn(),
getUser: vi.fn(),
getUserByAccount: vi.fn(),
updateUser: vi.fn(),
linkAccount: vi.fn(),
createSession: vi.fn(),
getSessionAndUser: vi.fn(),
updateSession: vi.fn(),
deleteSession: vi.fn(),
}
globalThis.process.env = {
AUTH_SECRET: 'secret',
}
const user = { email: 'hono@hono.hono', name: 'Hono' }
const credentials = Credentials({
credentials: {
password: {},
},
authorize: (credentials) => {
if (credentials.password === 'password') {
return user
}
return null
},
})
function getAuthConfig(): AuthConfig {
return {
secret: 'secret',
providers: [credentials],
adapter: mockAdapter,
basePath: '/api/auth',
callbacks: {
jwt: ({ token, user }) => {
if (user) {
token.id = user.id
}
return token
},
},
session: {
strategy: 'jwt',
},
}
}
let cookie = ['']
it('Should be able to instantiate new Request after passing through validator', async () => {
const app = new Hono()
app.use('*', initAuthConfig(getAuthConfig))
app.use(
'/api/auth/*',
validator('form', (value, _) => {
const csrfToken = value['csrfToken']
return {
csrfToken,
}
}),
authHandler()
)
let csrfRes = await app.request('http://localhost/api/auth/csrf', {
method: 'GET',
})
let { csrfToken } = await csrfRes.json()
cookie = csrfRes.headers.getSetCookie()
let headers = new Headers()
headers.append('cookie', cookie[0])
const signInRes = await app.request('http://localhost/api/auth/callback/credentials', {
method: 'POST',
headers,
body: new URLSearchParams({
csrfToken,
password: 'password',
}),
})
expect(signInRes.status).toBe(302)
expect(signInRes.headers.get('location')).toBe('http://localhost')
cookie = signInRes.headers.getSetCookie()
const sessionCookie = cookie[1]
headers = new Headers()
headers.append('cookie', cookie[1])
headers.append('Content-Type', 'application/json')
csrfRes = await app.request('http://localhost/api/auth/csrf', {
method: 'GET',
})
;({ csrfToken } = await csrfRes.json())
cookie = csrfRes.headers.getSetCookie()
headers = new Headers()
headers.append('cookie', cookie[0])
headers.append('cookie', sessionCookie)
const req = new Request('http://localhost/api/auth/signout', {
method: 'POST',
body: new URLSearchParams({
csrfToken,
password: 'password',
}),
headers,
})
const res = await app.request(req)
expect(res.status).toBe(302)
})
})
describe('Credentials Provider', () => {

View File

@ -135,7 +135,27 @@ export function authHandler(): MiddlewareHandler {
throw new HTTPException(500, { message: 'Missing AUTH_SECRET' })
}
const res = await Auth(reqWithEnvUrl(c.req.raw, ctxEnv.AUTH_URL), config)
const body = c.req.raw.body ? await c.req.blob() : undefined
const res = await Auth(
reqWithEnvUrl(
new Request(c.req.raw.url, {
body,
cache: c.req.raw.cache,
credentials: c.req.raw.credentials,
headers: c.req.raw.headers,
integrity: c.req.raw.integrity,
keepalive: c.req.raw.keepalive,
method: c.req.raw.method,
mode: c.req.raw.mode,
redirect: c.req.raw.redirect,
referrer: c.req.raw.referrer,
referrerPolicy: c.req.raw.referrerPolicy,
signal: c.req.raw.signal,
}),
ctxEnv.AUTH_URL
),
config
)
return new Response(res.body, res)
}
}