dartvex_auth_better
Better Auth adapter for dartvex. Self-hosted authentication for Convex with Better Auth.
This keeps Better Auth isolated from the core SDK packages:
dartvexstays provider-agnosticdartvex_flutterstays provider-agnostic- Better Auth logic lives here
Installation
dependencies:
dartvex: ^0.1.1
dartvex_auth_better: ^0.1.1
Server-Side Setup
Your Convex Better Auth configuration must include the bearer() plugin for mobile/desktop session persistence:
// convex/authSetup.ts
import { bearer } from "better-auth/plugins";
export const createAuth = (ctx) => {
return betterAuth({
// ...
plugins: [
bearer(), // Required for mobile/API clients
convex({ authConfig }),
// ...
],
});
};
Without bearer(), session tokens cannot be restored across app restarts.
Usage
1. Create the auth client
import 'package:dartvex_auth_better/dartvex_auth_better.dart';
final authClient = BetterAuthClient(
baseUrl: 'https://your-deployment.convex.cloud',
);
2. Sign up / sign in
final session = await authClient.signIn(
email: 'user@example.com',
password: 'securePassword',
);
// session.token — Convex JWT (for WebSocket auth)
// session.sessionToken — Better Auth token (for session persistence)
3. Connect to Convex
import 'package:dartvex/dartvex.dart';
final convexClient = ConvexClient('https://your-deployment.convex.cloud');
final provider = ConvexBetterAuthProvider(client: authClient);
provider.email = 'user@example.com';
provider.password = 'securePassword';
final authedClient = convexClient.withAuth(provider);
await authedClient.login();
4. Persist sessions (mobile/desktop)
Store session.sessionToken in secure storage after login. On app restart, use it to restore the session:
// After login — save the session token
final session = await authedClient.login();
await secureStorage.write(key: 'session_token', value: session.sessionToken);
// On app restart — restore from cache
final stored = await secureStorage.read(key: 'session_token');
if (stored != null) {
final session = await authClient.getSession(sessionToken: stored);
if (session != null) {
// Session restored — session.token has a fresh Convex JWT
}
}
5. Sign out
await authClient.signOut(sessionToken: session.sessionToken);
await secureStorage.delete(key: 'session_token');
6. Password recovery and magic links
await authClient.forgotPassword(
email: 'user@example.com',
redirectTo: 'myapp://reset-password',
);
await authClient.resetPassword(
token: resetToken,
newPassword: 'newSecurePassword',
);
await authClient.sendMagicLink(
email: 'user@example.com',
callbackURL: 'myapp://auth-callback',
);
final session = await authClient.verifyMagicLink(token: magicLinkToken);
API Overview
BetterAuthClient
signUp({email, password, name?})— create account, returnsBetterAuthSessionsignIn({email, password})— authenticate, returnsBetterAuthSessionforgotPassword({email, redirectTo?})— send password reset emailresetPassword({token, newPassword})— confirm password resetsendMagicLink({email, callbackURL?})— send passwordless sign-in linkverifyMagicLink({token})— exchange magic link token for a sessionsignOut({sessionToken})— end sessiongetSession({sessionToken})— validate existing session and get fresh Convex JWTclose()— dispose HTTP client
ConvexBetterAuthProvider
Implements AuthProvider<BetterAuthSession> from dartvex:
login()— sign in with stored email/passwordloginFromCache()— restore session from cached tokenlogout()— sign out and clear cachesignUp({email, password, name?})— create account and authenticate
BetterAuthSession
class BetterAuthSession {
final String token; // JWT for Convex WebSocket auth
final String sessionToken; // Better Auth token (for persistence & sign-out)
final String userId; // Better Auth user ID
final String email; // User email
final String? name; // Optional display name
}
Full Documentation
See the Dartvex monorepo for full documentation and examples.