flutter_auth_screen 0.1.5 copy "flutter_auth_screen: ^0.1.5" to clipboard
flutter_auth_screen: ^0.1.5 copied to clipboard

Customizable PIN authentication plugin with biometric support, lockout protection, and pure UI components.

Flutter Auth Screen 🛡️ #

A modern, customizable, and production-ready Flutter plugin for PIN-based authentication with advanced security features.

pub package License: MIT

✨ Features #

  • 🎨 Fully Customizable UI - Complete control over colors, sizes, animations, and layout
  • 🔐 PIN Strength Validation - Prevent weak PINs (sequential, repeating, common patterns)
  • 👆 Biometric Authentication - Optional fingerprint/face ID support
  • 🔒 Lockout Protection - Automatic lockout after failed attempts
  • 🌙 Dark Theme Support - Built-in theme switching
  • Accessibility - Full VoiceOver and semantic label support
  • Haptic Feedback - Customizable vibration patterns
  • 🎭 Smooth Animations - Shake, scale, and fade effects
  • 📦 Zero Business Logic - Pure UI components, you control storage and validation
  • 🚀 Production Ready - Tested and optimized for real-world apps

📸 Screenshots #

Set PIN Verify PIN Error State
[Set PIN] [Verify PIN] [Error]

🚀 Getting Started #

Installation #

Add to your pubspec.yaml:

dependencies:
  flutter_auth_screen: ^0.1.3

Run:

flutter pub get

Basic Usage #

1. Set PIN Screen

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => SetPinScreen(
      onPinSet: (pin) async {
        // Save PIN to your preferred storage
        await YourStorageService.savePin(pin);
        return true; // Return true if successful
      },
      onCompleted: (success) {
        if (success) {
          Navigator.pop(context);
          // Show success message
        }
      },
    ),
  ),
);

2. Verify PIN Screen

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => VerifyPinScreen(
      onVerifyPin: (pin) async {
        // Verify PIN against stored value
        return await YourStorageService.verifyPin(pin);
      },
      onVerificationResult: (success, attemptsRemaining) {
        if (success) {
          Navigator.pop(context);
          // Grant access
        }
      },
    ),
  ),
);

🎨 Customization #

Theme Customization #

SetPinScreen(
  onPinSet: (pin) async => await savePin(pin),
  config: PinScreenConfig(
    // Colors
    primaryColor: Colors.purple,
    backgroundColor: Colors.white,
    dotFilledColor: Colors.purple,
    errorColor: Colors.red,
    
    // Sizes
    pinLength: 6,
    dotSize: 20.0,
    numberButtonSize: 80.0,
    
    // Dark Theme
    brightness: Brightness.dark,
    
    // Animations
    enableHaptic: true,
    showShakeAnimation: true,
    animationDuration: Duration(milliseconds: 300),
  ),
);

PIN Strength Validation #

SetPinScreen(
  onPinSet: (pin) async => await savePin(pin),
  config: PinScreenConfig(
    // Prevent weak PINs
    preventSequentialPins: true,      // Blocks: 1234, 4321
    preventRepeatingDigits: true,     // Blocks: 1111, 2222
    preventCommonPins: true,          // Blocks: 0000, 1212, etc.
    customBlockedPins: ['1234', '0000'], // Your custom blocked list
  ),
  validatePin: (pin) {
    // Optional: Add your own validation
    if (pin.contains('13')) {
      return 'PIN cannot contain 13';
    }
    return null;
  },
);

Biometric Authentication #

VerifyPinScreen(
  onVerifyPin: (pin) async => await verifyPin(pin),
  config: PinScreenConfig(
    showBiometric: true,
    biometricIcon: Icons.fingerprint,
    onBiometricAuth: () async {
      // Implement biometric authentication
      final authenticated = await LocalAuthentication().authenticate(
        localizedReason: 'Authenticate to access',
      );
      return authenticated;
    },
  ),
);

Forgot PIN Support #

VerifyPinScreen(
  onVerifyPin: (pin) async => await verifyPin(pin),
  config: PinScreenConfig(
    showForgotPin: true,
    forgotPinText: 'Forgot your PIN?',
    onForgotPin: () {
      // Navigate to password reset or recovery flow
      Navigator.push(context, MaterialPageRoute(
        builder: (context) => ForgotPinScreen(),
      ));
    },
  ),
);

Lockout Protection #

VerifyPinScreen(
  onVerifyPin: (pin) async => await verifyPin(pin),
  maxAttempts: 5,
  config: PinScreenConfig(
    lockoutDuration: Duration(minutes: 5),
  ),
  onVerificationResult: (success, attemptsRemaining) {
    if (!success && attemptsRemaining == 0) {
      // Handle lockout - save lockout time
      YourStorageService.setLockoutUntil(
        DateTime.now().add(Duration(minutes: 5)),
      );
    }
  },
);

Custom Widgets #

PinScreenConfig(
  // Custom header
  headerWidget: Column(
    children: [
      Image.asset('assets/logo.png', height: 80),
      SizedBox(height: 16),
      Text('Secure Access', style: TextStyle(fontSize: 24)),
    ],
  ),
  
  // Custom footer
  footerWidget: Text(
    'Your data is encrypted and secure',
    style: TextStyle(fontSize: 12, color: Colors.grey),
  ),
  
  // Custom number pad
  customNumberPad: (context, onPressed, onDelete) {
    return YourCustomNumberPad(
      onPressed: onPressed,
      onDelete: onDelete,
    );
  },
);

Accessibility #

PinScreenConfig(
  enableVoiceOver: true,
  pinDotSemanticLabel: 'PIN digit',
  deleteButtonSemanticLabel: 'Delete last digit',
  biometricButtonSemanticLabel: 'Use fingerprint authentication',
  forgotPinSemanticLabel: 'Reset PIN',
);

🎯 Advanced Features #

For convenience, use built-in navigation helpers:

// Show Set PIN
final result = await FlutterAuthScreen.showSetPinDialog(
  context: context,
  onPinSet: (pin) async => await savePin(pin),
);

// Show Verify PIN
final verified = await FlutterAuthScreen.showVerifyPinDialog(
  context: context,
  onVerifyPin: (pin) async => await verifyPin(pin),
);

Complete Storage Example #

class PinService {
  final _storage = SharedPreferences.getInstance();
  
  Future<bool> savePin(String pin) async {
    final prefs = await _storage;
    final hashedPin = _hashPin(pin);
    return await prefs.setString('user_pin', hashedPin);
  }
  
  Future<bool> verifyPin(String pin) async {
    final prefs = await _storage;
    final storedPin = prefs.getString('user_pin');
    final hashedPin = _hashPin(pin);
    return storedPin == hashedPin;
  }
  
  Future<bool> isPinSet() async {
    final prefs = await _storage;
    return prefs.containsKey('user_pin');
  }
  
  String _hashPin(String pin) {
    // Use proper hashing in production (crypto package)
    return pin; // Simplified for example
  }
}

📚 Complete API Reference #

SetPinScreen #

Parameter Type Description
onPinSet Future<bool> Function(String) Called when PIN is set, return true if saved successfully
onCompleted Function(bool)? Called after operation completes
validatePin String? Function(String)? Custom validation, return error message or null
onCancel VoidCallback? Called when user cancels
primaryColor Color? Primary color override
backgroundColor Color? Background color override
config PinScreenConfig? Advanced configuration
createTitle String Title for create step
createSubtitle String Subtitle for create step
confirmTitle String Title for confirm step
confirmSubtitle String Subtitle for confirm step
mismatchMessage String Message when PINs don't match

VerifyPinScreen #

Parameter Type Description
onVerifyPin Future<bool> Function(String) Called to verify PIN, return true if correct
onVerificationResult Function(bool, int)? Called after each attempt (success, remaining)
onCancel VoidCallback? Called when user cancels
canCancel bool Whether cancel button is shown
maxAttempts int Maximum attempts before lockout (0 = unlimited)
primaryColor Color? Primary color override
backgroundColor Color? Background color override
config PinScreenConfig? Advanced configuration
title String Screen title
subtitle String Screen subtitle
incorrectPinMessage String Function(int)? Custom error message with remaining attempts
maxAttemptsMessage String Message shown when max attempts reached

PinScreenConfig #

See full configuration options in IMPLEMENTATION_GUIDE.md

🔐 Security Best Practices #

  1. Always hash PINs - Never store plain text PINs
  2. Use secure storage - Consider flutter_secure_storage for sensitive data
  3. Implement lockout - Prevent brute force attacks with lockout periods
  4. Validate PIN strength - Use built-in validation to prevent weak PINs
  5. Add biometric option - Provide convenience without sacrificing security
  6. Encrypt stored data - Combine PIN with encryption for sensitive app data

🤝 Contributing #

Contributions are welcome! Please read CONTRIBUTING.md for details.

📄 License #

This project is licensed under the MIT License - see the LICENSE file for details.

💖 Support #

If you find this plugin helpful, please:

  • ⭐ Star the repo
  • 🐛 Report issues
  • 📝 Suggest features
  • 🔀 Submit PRs

📮 Contact #

🙏 Acknowledgments #

Built with ❤️ for the Flutter community.


Made with Flutter 💙

2
likes
150
points
165
downloads

Publisher

unverified uploader

Weekly Downloads

Customizable PIN authentication plugin with biometric support, lockout protection, and pure UI components.

Repository (GitHub)
View/report issues

Topics

#security #authentication #pin #biometric #lock-screen

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface, shared_preferences

More

Packages that depend on flutter_auth_screen

Packages that implement flutter_auth_screen