34 lines
1.5 KiB
TypeScript
34 lines
1.5 KiB
TypeScript
import { createAuthClient } from 'better-auth/client'
|
|
import { magicLinkClient } from 'better-auth/client/plugins'
|
|
import { apiUrl } from './env'
|
|
|
|
// Better Auth mounts at /api/auth (default basePath); the client appends the
|
|
// endpoint verbatim to baseURL, so the base must include /auth — otherwise it
|
|
// emits /api/sign-in/email and 404s on both sandbox and deploy. The base MUST be
|
|
// absolute (apiUrl() never returns a bare relative path) or the client throws
|
|
// "Invalid base URL". The backend wires the magicLink plugin, so the client does
|
|
// too — candidates sign in by magic link, staff (company/backoffice) by password.
|
|
export const authClient = createAuthClient({
|
|
baseURL: `${apiUrl()}/auth`,
|
|
plugins: [magicLinkClient()],
|
|
})
|
|
|
|
export async function signInWithPassword(email: string, password: string): Promise<void> {
|
|
const { error } = await authClient.signIn.email({ email, password })
|
|
if (error) throw new Error(error.message || 'Invalid credentials')
|
|
}
|
|
|
|
export async function requestMagicLink(email: string): Promise<void> {
|
|
const { error } = await authClient.signIn.magicLink({ email })
|
|
if (error) throw new Error(error.message || 'Unable to send magic link')
|
|
}
|
|
|
|
export async function verifyMagicLink(token: string): Promise<void> {
|
|
const { error } = await authClient.magicLink.verify({ query: { token } })
|
|
if (error) throw new Error(error.message || 'Verification failed')
|
|
}
|
|
|
|
export async function signOut(): Promise<void> {
|
|
await authClient.signOut()
|
|
}
|