@tillstack/auth-react
v0.3.0
Published
React SDK for TillAuth — drop-in auth provider + hooks
Readme
@tillstack/auth-react
Drop-in React SDK for TillAuth — an auth provider, hooks for sign-in / sign-up / sessions, and passkey (WebAuthn) support.
Install
npm install @tillstack/auth-react
# or: pnpm add @tillstack/auth-reactreact (>=18) is a peer dependency.
Usage
Wrap your app in TillAuthProvider:
import { TillAuthProvider } from '@tillstack/auth-react'
export function App() {
return (
<TillAuthProvider appId="tau_your_app_id">
<YourApp />
</TillAuthProvider>
)
}Read the current user and sign in:
import { useUser, useSignIn, useSignOut } from '@tillstack/auth-react'
function Login() {
const { signIn, pending, error } = useSignIn()
const user = useUser()
const signOut = useSignOut()
if (user) return <button onClick={signOut}>Sign out {user.email}</button>
return (
<button
disabled={pending}
onClick={() => signIn('[email protected]', 'password')}
>
Sign in {error && `— ${error}`}
</button>
)
}Hooks
useTillAuth()— the full auth context (client + state).useUser()/useSession()/useAuthStatus()— current identity + status.useSignIn()—{ signIn, sendMagic, signInWithProvider, pending, error }.useSignUp(),useSignOut(),useMfa().usePasskeys(),useRegisterPasskey(),useSignInWithPasskey(),passkeysSupported()— WebAuthn passkeys.
When a refresh ends the session, state.reason says why. reauth_required
means the app's session-risk policy wants a fresh sign-in; risk_revoked
means it ended every session of the user:
const { state } = useTillAuth()
if (state.status === 'unauthenticated' && state.reason === 'reauth_required') {
// show "For your security, please sign in again"
}A sign-in that looks unusual can owe one more step. signIn then returns
mfa_required: true; with no method it wants an authenticator code
(useMfa().verify), and with method: 'email' it wants the 6-digit code
emailed to email_hint (useMfa().verifyEmailCode). Past the app's block
threshold the result carries code: 'signin_blocked' and the user is emailed:
const { signIn } = useSignIn()
const { verifyEmailCode } = useMfa()
const r = await signIn(email, password)
if (r.ok === false && r.mfa_required === true && r.method === 'email') {
const code = await askUser(`Enter the code we sent to ${r.email_hint}`)
await verifyEmailCode({ challenge_token: r.challenge_token, code })
}Session tokens live in localStorage by default; pass sessionMode="cookie"
to TillAuthProvider to keep them in HttpOnly cookies via a same-site proxy.
Docs
Full documentation: https://tilldev.dev/docs
License
Apache-2.0
