VooStackAuth Client

Version Flutter License

A comprehensive Flutter SDK for VooStackAuth - a centralized authentication platform. Supports email/password authentication, OAuth providers, automatic token refresh, and provider linking.

Features

  • Email/Password Authentication - Register and login with email and password
  • OAuth Providers - Login with Google, GitHub, Microsoft, Apple, Discord
  • Token Management - Automatic token storage and refresh
  • Provider Linking - Link/unlink multiple OAuth providers to a single account
  • Dio Interceptor - Automatic token refresh with request queuing
  • Type Safe - Fully typed with strong type constraints
  • Clean Architecture - Following best practices with VooCore integration

Installation

Add to your pubspec.yaml:

dependencies:
  voostackauth_client: ^0.1.0

Or for local development in the VooFlutter monorepo:

dependencies:
  voostackauth_client:
    path: packages/dev/voostackauth_client

Quick Start

1. Initialize the Service

import 'package:voostackauth_client/voostackauth_client.dart';

final authService = VooStackAuthService(
  config: VooStackAuthConfig(
    baseUrl: 'https://auth.voostack.com/api',
  ),
);

// Initialize (checks for stored tokens)
await authService.initialize();

2. Register a New User

try {
  final result = await authService.register(
    email: 'user@example.com',
    password: 'securePassword123',
    firstName: 'John',
    lastName: 'Doe',
  );

  print('Welcome, ${result.user.fullName}!');
} on VooStackAuthException catch (e) {
  print('Registration failed: ${e.message}');
}

3. Login with Email/Password

try {
  final result = await authService.loginWithEmail(
    email: 'user@example.com',
    password: 'securePassword123',
  );

  print('Logged in as ${result.user.email}');
} on VooStackAuthException catch (e) {
  if (e.code == 'invalid-credentials') {
    print('Invalid email or password');
  }
}

4. Login with OAuth Provider

// With access token from OAuth provider
final result = await authService.loginWithOAuthToken(
  provider: OAuthProvider.google,
  token: googleAccessToken,
);

// With authorization code
final result = await authService.loginWithOAuthCode(
  provider: OAuthProvider.github,
  code: authorizationCode,
  redirectUri: 'https://yourapp.com/callback',
);

5. Listen to Auth State Changes

authService.statusStream.listen((status) {
  switch (status) {
    case AuthStatus.authenticated:
      print('User is logged in');
      break;
    case AuthStatus.unauthenticated:
      print('User is logged out');
      break;
    case AuthStatus.authenticating:
      print('Login in progress...');
      break;
    case AuthStatus.refreshing:
      print('Refreshing token...');
      break;
    case AuthStatus.error:
      print('Authentication error');
      break;
  }
});

authService.userStream.listen((user) {
  if (user != null) {
    print('Current user: ${user.fullName}');
  }
});

OAuth Providers

Supported OAuth providers:

Provider Enum Value
Google OAuthProvider.google
GitHub OAuthProvider.github
Microsoft OAuthProvider.microsoft
Apple OAuthProvider.apple
Discord OAuthProvider.discord

Provider Linking

Link multiple OAuth providers to a single account:

// Get linked providers
final providers = await authService.getLinkedProviders();
for (final provider in providers) {
  print('${provider.providerType}: ${provider.email}');
}

// Link a new provider
final linked = await authService.linkProviderWithToken(
  provider: OAuthProvider.github,
  token: githubAccessToken,
);
print('Linked ${linked.providerType}');

// Unlink a provider
await authService.unlinkProvider(OAuthProvider.github);

Token Management

Custom Token Storage

Implement TokenStorage for persistent storage:

class SecureTokenStorage implements TokenStorage {
  final FlutterSecureStorage _storage = FlutterSecureStorage();

  @override
  Future<void> saveTokens(AuthTokens tokens) async {
    await _storage.write(key: 'auth_tokens', value: jsonEncode(tokens.toJson()));
  }

  @override
  Future<AuthTokens?> getTokens() async {
    final data = await _storage.read(key: 'auth_tokens');
    if (data == null) return null;
    return AuthTokens.fromJson(jsonDecode(data));
  }

  @override
  Future<void> deleteTokens() async {
    await _storage.delete(key: 'auth_tokens');
  }

  @override
  Future<bool> hasTokens() async {
    return await _storage.containsKey(key: 'auth_tokens');
  }
}

// Use custom storage
final authService = VooStackAuthService(
  config: VooStackAuthConfig(baseUrl: 'https://auth.voostack.com/api'),
  tokenStorage: SecureTokenStorage(),
);

Auto-Refresh Interceptor

Add the interceptor to your Dio instance for automatic token refresh:

final dio = Dio();
dio.interceptors.add(AuthInterceptor(
  authService: authService,
  refreshBuffer: Duration(minutes: 5), // Refresh 5 min before expiry
));

// All requests will now automatically include auth headers
// and refresh tokens when needed
final response = await dio.get('/api/protected-resource');

Configuration

VooStackAuthConfig(
  // Required
  baseUrl: 'https://auth.voostack.com/api',

  // Optional
  connectTimeout: Duration(seconds: 30),
  receiveTimeout: Duration(seconds: 30),
  autoRefreshBuffer: Duration(minutes: 5),
)

Error Handling

All auth errors throw VooStackAuthException:

try {
  await authService.loginWithEmail(email: email, password: password);
} on VooStackAuthException catch (e) {
  switch (e.code) {
    case 'invalid-credentials':
      // Wrong email or password
      break;
    case 'unauthenticated':
      // User not logged in
      break;
    case 'token-expired':
      // Token has expired
      break;
    case 'refresh-failed':
      // Failed to refresh token
      break;
    case 'network-error':
      // Network connectivity issue
      break;
    case 'email-in-use':
      // Email already registered
      break;
    case 'provider-already-linked':
      // OAuth provider already linked
      break;
    case 'provider-not-linked':
      // OAuth provider not linked
      break;
    default:
      print('Error: ${e.message}');
  }
}

API Reference

VooStackAuthService

Method Description
initialize() Check for stored tokens and restore session
register() Register new user with email/password
loginWithEmail() Login with email and password
loginWithOAuthToken() Login with OAuth provider token
loginWithOAuthCode() Login with OAuth authorization code
refreshToken() Manually refresh the access token
logout() Logout and clear tokens
getCurrentUser() Fetch current user info
getLinkedProviders() Get all linked OAuth providers
linkProviderWithToken() Link OAuth provider with token
linkProviderWithCode() Link OAuth provider with code
unlinkProvider() Unlink an OAuth provider
dispose() Clean up resources

Properties

Property Type Description
status AuthStatus Current auth status
currentUser UserInfo? Current user info
currentTokens AuthTokens? Current tokens
isAuthenticated bool Whether user is authenticated
statusStream Stream<AuthStatus> Auth status changes
userStream Stream<UserInfo?> User changes
authenticatedDio Dio Dio instance with auth headers

Example

See the example folder for a complete sample application demonstrating:

  • Email/password registration and login
  • OAuth provider authentication
  • Auth state management
  • Provider linking/unlinking
  • Token refresh

Run the example:

cd example
flutter run -d chrome

Architecture

lib/
├── voostackauth_client.dart    # Main export
└── src/
    ├── enums/
    │   ├── auth_status.dart    # Authentication states
    │   └── oauth_provider.dart # OAuth provider enum
    ├── exceptions/
    │   └── voostackauth_exception.dart
    ├── interceptors/
    │   └── auth_interceptor.dart  # Auto-refresh interceptor
    ├── models/
    │   ├── auth_result.dart    # Login/register result
    │   ├── auth_tokens.dart    # JWT tokens
    │   ├── linked_provider.dart # Linked OAuth provider
    │   └── user_info.dart      # User information
    └── services/
        ├── auth_service.dart   # Main auth service
        └── token_storage.dart  # Token storage interface

Learn More

License

MIT License - see LICENSE for details.


Built by VooStack

Need help with Flutter development or authentication solutions?

Contact Us

VooStack builds enterprise Flutter applications and developer tools. We're here to help with your next project.

Libraries

voostackauth_client
Flutter SDK for VooStackAuth - a centralized authentication platform.