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
parent
7a45d5749d
commit
7585969171
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@hono/auth-js': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(auth-js): use HonoRequest.blob() instead of HonoRequest.raw.body()
|
|
@ -2,6 +2,7 @@ import { skipCSRFCheck } from '@auth/core'
|
||||||
import type { Adapter } from '@auth/core/adapters'
|
import type { Adapter } from '@auth/core/adapters'
|
||||||
import Credentials from '@auth/core/providers/credentials'
|
import Credentials from '@auth/core/providers/credentials'
|
||||||
import { Hono } from 'hono'
|
import { Hono } from 'hono'
|
||||||
|
import { validator } from 'hono/validator'
|
||||||
import { describe, expect, it, vi } from 'vitest'
|
import { describe, expect, it, vi } from 'vitest'
|
||||||
import type { AuthConfig } from '.'
|
import type { AuthConfig } from '.'
|
||||||
import { authHandler, verifyAuth, initAuthConfig, reqWithEnvUrl } from '.'
|
import { authHandler, verifyAuth, initAuthConfig, reqWithEnvUrl } from '.'
|
||||||
|
@ -80,6 +81,128 @@ describe('reqWithEnvUrl()', async () => {
|
||||||
it('Should rewrite the base path', () => {
|
it('Should rewrite the base path', () => {
|
||||||
expect(newReq.url.toString()).toBe('https://auth-url-base/request-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', () => {
|
describe('Credentials Provider', () => {
|
||||||
|
|
|
@ -135,7 +135,27 @@ export function authHandler(): MiddlewareHandler {
|
||||||
throw new HTTPException(500, { message: 'Missing AUTH_SECRET' })
|
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)
|
return new Response(res.body, res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue