dartvex_auth_better 0.2.0 copy "dartvex_auth_better: ^0.2.0" to clipboard
dartvex_auth_better: ^0.2.0 copied to clipboard

Better Auth adapter for Dartvex. Self-hosted authentication for Convex with Better Auth.

Dartvex

dartvex_auth_better #

Better Auth adapter for dartvex — the pure Dart client for Convex. Self-hosted authentication powered by Better Auth.

This keeps Better Auth isolated from the core SDK packages:

Dartvex Flutter demo — real-time chats running on iOS and macOS

The Dartvex ecosystem #

Package Description
dartvex Core client — WebSocket sync, subscriptions, auth
dartvex_flutter Flutter widgets — Provider, Query, Mutation
dartvex_codegen CLI code generator — type-safe Dart bindings from schema
dartvex_local Offline support — SQLite cache, mutation queue
dartvex_auth_better Better Auth adapter

Source and full docs: github.com/AndreFrelicot/dartvex

Installation #

dependencies:
  dartvex: ^0.2.0
  dartvex_auth_better: ^0.2.0

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.

Flutter web CORS #

For Flutter web, Better Auth must expose the session-token header through CORS:

Access-Control-Expose-Headers: set-auth-token

Browsers do not expose Set-Cookie to Dart or JavaScript, so the cookie fallback is native-only. Web sign-in and sign-up need either the exposed set-auth-token header or a non-empty JSON token field in the Better Auth response body.

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 — seed the provider with the persisted token, then restore
final stored = await secureStorage.read(key: 'session_token');
final provider = ConvexBetterAuthProvider(
  client: authClient,
  initialSessionToken: stored,
);
final authedClient = convexClient.withAuth(provider);
if (stored != null) {
  final session = await authedClient.loginFromCache();
  // Session restored — session.token has a fresh Convex JWT, and the
  // Convex client is authenticated with automatic token refresh.
}

For one-off validation outside the provider flow, authClient.getSession(sessionToken: stored) also returns a fresh session (or null when the session has expired).

5. Sign out #

await authClient.signOut(sessionToken: session.sessionToken);
await secureStorage.delete(key: 'session_token');
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({name, email, password}) — create account, returns BetterAuthSession
  • signIn({email, password}) — authenticate, returns BetterAuthSession
  • forgotPassword({email, redirectTo?}) — send password reset email
  • resetPassword({token, newPassword}) — confirm password reset
  • sendMagicLink({email, callbackURL?}) — send passwordless sign-in link
  • verifyMagicLink({token}) — exchange magic link token for a session
  • signOut({sessionToken}) — end session
  • getSession({sessionToken}) — validate existing session and get fresh Convex JWT
  • close() — dispose HTTP client

ConvexBetterAuthProvider #

Implements AuthProvider<BetterAuthSession> from dartvex:

  • ConvexBetterAuthProvider({client, initialSessionToken?}) — pass a persisted session token to restore the session across app restarts
  • login() — sign in with stored email/password
  • loginFromCache() — restore session from the cached (or seeded) token
  • logout() — sign out and clear cache
  • signUp({name, email, password, onIdToken}) — create account and authenticate, reporting the Convex JWT through onIdToken

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.

1
likes
160
points
110
downloads

Documentation

API reference

Publisher

verified publisherandrefrelicot.dev

Weekly Downloads

Better Auth adapter for Dartvex. Self-hosted authentication for Convex with Better Auth.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#convex #authentication #better-auth #sync

License

MIT (license)

Dependencies

dartvex, http

More

Packages that depend on dartvex_auth_better