Flutter · colveor

Authentication

Everything in package:colveor/auth.dart — from the signed-in user to complete sign-in and sign-up screens.

Auth state

authControllerProvider (kept alive) holds an AuthState:

NameDescription
statusAuthStatus: unauthenticated, authenticating, authenticated or error.
userThe signed-in User, or null.
isNewUserTrue right after sign-up.
errorThe last error message.
gettersisAuthenticated, isLoading, hasError.

The controller exposes:

NameDescription
applyTokens(tokens, {isNewUser})Store tokens from a successful login and mark the user authenticated.
logout()Calls the logout endpoint, then clears the session whether or not the call succeeds.
clearError()Reset an error state back to unauthenticated.
dioThe shared Dio client.

Session & storage

On start, if a refresh token and a user are stored, the state becomes authenticated straight away without a network call; the access token is fetched on the first protected request. AuthSession.instance offers hasStoredSession(), refresh(), restoreUser() and signOut() — useful on a splash screen:

Dart
final session = AuthSession.instance;
if (!await session.hasStoredSession()) return false;
return session.refresh();

AuthStorage persists the refresh token (vo_refresh_token) and the user (vo_user) with VoStorage. The access token is never persisted.

Sign-out clears all storage

Signing out calls VoStorage.deleteAll(), which also removes the DPoP key, notification flags, the saved theme and anything your app stored with VoStorage.

VoAuthScreen

VoAuthScreen runs a multi-step auth flow on top of the colveor_ui page flow. You supply the page widgets; it handles navigation, state and the API calls.

Dart
VoAuthScreen(
  initialPage: VoAuthPageKeys.phoneSignIn,
  pages: VoAuthPages.phone(
    phoneBuilder: (_) => const PhoneSignInPage(),
    verifyOtpBuilder: (_) => const VerifyOtpPage(),
    signUpBuilder: (_) => const PhoneSignUpPage(),
  ),
  onAuthSuccess: (user, isNewUser) => context.vo.pushReplace(AppPaths.home),
)
NameDescription
pagesVoAuthPages.phone(...) or VoAuthPages.emailAndPassword(signInBuilder, signUpBuilder, forgotPasswordBuilder, resetPasswordBuilder, verifyResetPasswordBuilder).
initialPageA VoAuthPageKeys value. Default signIn.
onAuthSuccessCalled with the user and isNewUser once authentication succeeds.

Flows

Phone / OTP

  1. phoneSignUp(phone:) sends an OTP and moves to the verify page.
  2. verifyOtp(otp:) verifies it. Existing accounts are signed in; new numbers move to the sign-up page.
  3. signUp(...) registers using the verified phone. resendOtp() is available throughout.

Email / password

  • signIn(email:, password:)
  • signUp(email:, password:, profile:) — registers and marks the user as new.
  • forgotPassword(email:) — requests a reset email.

Building pages

Inside a page, get the flow with VoAuthScope.of(context) (or mix VoAuthWidget into your widget and call auth(context)). It is a ChangeNotifier exposing isLoading, error, hasError, navigateTo, goBack and the flow actions. State is synced as soon as an action completes.

Dart
final auth = VoAuthScope.of(context);

ListenableBuilder(
  listenable: auth,
  builder: (context, _) => VoButton(
    label: 'Continue',
    isLoading: auth.isLoading,
    onPressed: () async {
      await auth.phoneSignUp(phone: _phoneController.text.trim());
      if (auth.hasError) showErrorToast(auth.error!);
    },
  ),
)

Route guards

Re-run redirects whenever auth changes with the colveor_ui routing config:

Dart
import 'package:colveor/auth.dart';
import 'package:colveor/config.dart';

VoRoutingConfig(
  initialLocation: '/',
  onInit: (ref, notifier) =>
      ref.listen(authControllerProvider, (_, _) => notifier.notify()),
  redirect: (ref, context, state) {
    final signedIn = ref.read(authControllerProvider).isAuthenticated;
    return signedIn ? null : '/auth';
  },
)

Context helpers

From package:colveor/extensions.dart:

NameDescription
context.currentUserThe signed-in User, or null.
context.logout()Sign out (fire-and-forget).
context.applyTokens(tokens)Apply tokens obtained elsewhere.

Current limits

Note

Password reset completion (resetPassword, verifyResetPassword), PIN, MFA and accepting invites are not implemented in the client yet. The reset actions return an error explaining this.