diff --git a/packages/auth-js/src/index.ts b/packages/auth-js/src/index.ts index 16d2efdc4..0a60ce11b 100644 --- a/packages/auth-js/src/index.ts +++ b/packages/auth-js/src/index.ts @@ -1,12 +1,12 @@ import type { AuthConfig as AuthConfigCore } from '@auth/core' -import { Auth } from '@auth/core' +import { Auth, createActionURL } from '@auth/core' import type { AdapterUser } from '@auth/core/adapters' import type { JWT } from '@auth/core/jwt' import type { Session } from '@auth/core/types' import type { Context, MiddlewareHandler } from 'hono' import { env } from 'hono/adapter' import { HTTPException } from 'hono/http-exception' -import { setEnvDefaults as coreSetEnvDefaults } from '@auth/core' +import { setEnvDefaults } from '@auth/core' declare module 'hono' { interface ContextVariableMap { @@ -32,54 +32,46 @@ export interface AuthConfig extends Omit {} export type ConfigHandler = (c: Context) => AuthConfig -export function setEnvDefaults(env: AuthEnv, config: AuthConfig) { - config.secret ??= env.AUTH_SECRET - coreSetEnvDefaults(env, config) -} - - -export async function getAuthUser(c: Context): Promise { +export async function getAuthUser(c: Context) { + const ctxEnv = env(c) const config = c.get('authConfig') - const ctxEnv = env(c) as AuthEnv - setEnvDefaults(ctxEnv, config) - const authReq = c.req.raw - const origin = new URL(authReq.url).origin - const request = new Request(`${origin}${config.basePath}/session`, { - headers: { cookie: c.req.header('cookie') ?? '' }, - }) + const req = c.req.raw + + const url = createActionURL('session', new URL(req.url).protocol, req.headers, ctxEnv, config) let authUser: AuthUser = {} as AuthUser - const response = (await Auth(request, { - ...config, - callbacks: { - ...config.callbacks, - async session(...args) { - authUser = args[0] - const session = (await config.callbacks?.session?.(...args)) ?? args[0].session - const user = args[0].user ?? args[0].token - return { user, ...session } satisfies Session + const response = await Auth( + new Request(url, { headers: { cookie: req.headers.get('cookie') ?? '' } }), + { + ...config, + callbacks: { + ...config.callbacks, + async session(...args) { + authUser = args[0] + const session = (await config.callbacks?.session?.(...args)) ?? args[0].session + const user = args[0].user ?? args[0].token + return { user, ...session } satisfies Session + }, }, - }, - })) as Response + } + ) const session = (await response.json()) as Session | null return session?.user ? authUser : null } +/** + * A utility middleware to verify the session of the incoming request by getAuthUser under the hood. + * If unauthorized, it will throw a 401 Unauthorized error. + */ export function verifyAuth(): MiddlewareHandler { return async (c, next) => { - const authUser = await getAuthUser(c) + const authUser = c.get('authUser') ?? (await getAuthUser(c)) const isAuth = !!authUser?.token || !!authUser?.user - if (!isAuth) { - const res = new Response('Unauthorized', { - status: 401, - }) - throw new HTTPException(401, { res }) - } + if (!isAuth) throw new HTTPException(401, { message: 'Unauthorized' }) c.set('authUser', authUser) - await next() } } @@ -87,6 +79,8 @@ export function verifyAuth(): MiddlewareHandler { export function initAuthConfig(cb: ConfigHandler): MiddlewareHandler { return async (c, next) => { const config = cb(c) + const ctxEnv = env(c) as AuthEnv + setEnvDefaults(ctxEnv, config) c.set('authConfig', config) await next() } @@ -95,14 +89,6 @@ export function initAuthConfig(cb: ConfigHandler): MiddlewareHandler { export function authHandler(): MiddlewareHandler { return async (c) => { const config = c.get('authConfig') - const ctxEnv = env(c) as AuthEnv - - setEnvDefaults(ctxEnv, config) - - if (!config.secret || config.secret.length === 0) { - throw new HTTPException(500, { message: 'Missing AUTH_SECRET' }) - } - const res = await Auth(c.req.raw, config) return new Response(res.body, res) } diff --git a/packages/auth-js/test/index.test.ts b/packages/auth-js/test/index.test.ts index 2c0ed82cb..befbbeae7 100644 --- a/packages/auth-js/test/index.test.ts +++ b/packages/auth-js/test/index.test.ts @@ -12,7 +12,7 @@ import { authHandler, verifyAuth, initAuthConfig } from '../src' global.crypto = webcrypto describe('Config', () => { - it('Should return 500 if AUTH_SECRET is missing', async () => { + test('Should return 500 if AUTH_SECRET is missing', async () => { globalThis.process.env = { AUTH_SECRET: '' } const app = new Hono() @@ -20,6 +20,7 @@ describe('Config', () => { '/*', initAuthConfig(() => { return { + basePath: "/api/auth", providers: [], } }) @@ -28,7 +29,7 @@ describe('Config', () => { const req = new Request('http://localhost/api/auth/signin') const res = await app.request(req) expect(res.status).toBe(500) - expect(await res.text()).toBe('Missing AUTH_SECRET') + expect(await res.text()).include("There is a problem with the server configuration.") }) it('Should return 200 auth initial config is correct', async () => {