TausiDocs

Flutter

One package for Android, iOS, web, macOS, Windows and Linux. Sessions are kept in secure storage (Keychain / Keystore) and survive restarts; the app still opens signed in when offline.

Install

tausi_flutter on pub.devRequires Flutter 3.19+, Dart 3.3+
Not published yet
tausi_flutter isn't on pub.dev yet, so this command won't work until the first release. Everything below describes the package as it will ship.
Shell
flutter pub add tausi_flutter
Only the publishable key goes in the app
Anything shipped in an app can be extracted. Use pk_… here; keep sk_… on your server.

Set up

lib/tausi.dartDart
import 'package:tausi_flutter/tausi_flutter.dart';

final tausi = TausiClient(
  baseUrl: const String.fromEnvironment('TAUSI_URL', defaultValue: 'https://tausi-auth.onrender.com'),
  publishableKey: const String.fromEnvironment('TAUSI_KEY'),
);
terminalShell
flutter run --dart-define=TAUSI_URL=https://tausi-auth.onrender.com --dart-define=TAUSI_KEY=pk_…
OptionDefaultWhat it does
tokenStoreSecureTokenStoreWhere the session token is kept. Implement TokenStore to use your own.
sendDeviceIdtrueSends a random per-install ID so projects can limit accounts per device. Not a fingerprint.
timeout15 sPer-request timeout.
oauthLauncherflutter_web_auth_2How the social sign-in browser is opened.

Running on an Android emulator against a local Tausi? localhost there is the emulator itself; use http://10.0.2.2:3000.

Switch screens

lib/main.dartDart
void main() => runApp(MaterialApp(
      home: TausiAuthGate(
        client: tausi,
        loading: (_) => const SplashScreen(),
        signedIn: (_, user) => HomePage(user: user),
        signedOut: (_) => const SignInPage(),
      ),
    ));

TausiAuthGate restores the saved session, checks it with Tausi, and rebuilds whenever the user signs in or out (including when Tausi revokes the session or bans the user).

Email and password

sign_in_page.dartDart
// Sign up (optional attributes are saved with the account)
final verificationRequired = await tausi.signUp(
  email: email,
  password: password,
  name: name,
  username: username,              // optional
  phoneNumber: '+255712345678',    // optional
);

// Sign in
await tausi.signIn(email: email, password: password);

await tausi.sendVerificationEmail(email);
await tausi.forgotPassword(email);
await tausi.changePassword(currentPassword: current, newPassword: next); // signs out other devices
await tausi.signOut();

Errors

errorsDart
try {
  await tausi.signIn(email: email, password: password);
} on TausiException catch (e) {
  final message = switch (e.code) {
    'INVALID_CREDENTIALS' => 'Wrong email or password.',
    'EMAIL_NOT_VERIFIED' => 'Check your inbox to verify your email.',
    'ACCOUNT_BANNED' || 'ACCOUNT_SUSPENDED' => e.message,
    'RATE_LIMITED' => 'Too many attempts. Try again in ${e.retryAfter?.inSeconds ?? 60}s.',
    'NETWORK_ERROR' || 'TIMEOUT' => 'You seem to be offline.',
    _ => e.message,
  };
  ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message)));
}

TausiException has status, code, message, details and retryAfter. Sign-up adds EMAIL_ALREADY_REGISTERED and USERNAME_TAKEN.

Call your backend

api.dartDart
final token = await tausi.getToken();
final res = await http.get(
  Uri.parse('https://api.example.com/orders'),
  headers: {'authorization': 'Bearer $token'},
);

Verify it on the server with the Node, PHP or Python SDK. Renewed tokens are stored automatically.

Profile and devices

profileDart
final user = tausi.currentUser;                 // cached, available offline
final fresh = await tausi.getUser();
await tausi.updateUser(firstName: 'Asha', timezone: 'Africa/Dar_es_Salaam');
await tausi.updateUser(clear: {'phoneNumber'}); // remove an attribute

final sessions = await tausi.listSessions();    // OwnSession.current marks this device
await tausi.revokeSession(sessions.first.id);
await tausi.revokeOtherSessions();
await tausi.deleteAccount(password);

Social sign-in

socialDart
final methods = await tausi.getProviders();     // what the project enabled
await tausi.signInWithOAuth(
  OAuthProvider.google,                          // or 'github', 'apple', ...
  redirectTo: Uri.parse('https://app.example.com/auth/callback'),
);

The provider opens in a secure browser session and the one-time code is exchanged with PKCE. redirectTo must be an https URL on an allowed origin that opens your app:

  • Android: an App Link for that host, plus the CallbackActivity intent filter from flutter_web_auth_2.
  • iOS: a Universal Link (https callbacks need iOS 17.4 or later).
  • Web: a callback page on your origin.

Cancelling throws TausiException with code access_denied; a banned user gets account_banned. For other setups, call oauthUrl() and handleOAuthRedirect() yourself.

State management

The client is a ChangeNotifier, so it plugs into anything:

stateDart
// Plain Flutter
ListenableBuilder(listenable: tausi, builder: (_, __) => tausi.isSignedIn ? const Home() : const SignIn());

// Provider
ChangeNotifierProvider.value(value: tausi, child: const App());

// Riverpod
final tausiProvider = ChangeNotifierProvider((_) => tausi);