Fix fingerprint: adaptive auth screen (login/register by state), auto-prompt biometric on open, optimistic switch, real error messages
This commit is contained in:
@@ -4,7 +4,7 @@ import 'package:login_vault_app/auth_service.dart';
|
||||
import 'package:login_vault_app/dashboard_screen.dart';
|
||||
import 'package:login_vault_app/theme_provider.dart';
|
||||
|
||||
/// First screen: register, or (if registered) re-authenticate.
|
||||
/// First screen: register (if not yet), or re-authenticate (if registered).
|
||||
/// If a valid session exists, skip straight to the Dashboard.
|
||||
class AuthScreen extends StatefulWidget {
|
||||
final AuthService auth;
|
||||
@@ -24,9 +24,39 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initMode();
|
||||
}
|
||||
|
||||
/// Decide login vs register based on whether an account exists.
|
||||
Future<void> _initMode() async {
|
||||
final registered = await widget.auth.isRegistered();
|
||||
if (!mounted) return;
|
||||
setState(() => _isLogin = registered);
|
||||
// If already registered and biometric is enabled, prompt fingerprint
|
||||
// automatically (unless a valid session already skips to dashboard).
|
||||
if (registered && await widget.auth.isBiometricEnabled()) {
|
||||
final timeout = await widget.auth.getTimeoutMinutes();
|
||||
final valid = await widget.auth.hasValidSession(timeout);
|
||||
if (!valid) {
|
||||
_promptBiometricOnOpen();
|
||||
return; // skip silent-auth path; biometric handles entry
|
||||
}
|
||||
}
|
||||
_trySilentAuth();
|
||||
}
|
||||
|
||||
/// Auto-prompt fingerprint on open when enabled; on success go to dashboard
|
||||
/// (email may be empty for google-less accounts, fallback to stored email).
|
||||
Future<void> _promptBiometricOnOpen() async {
|
||||
final (ok, err) = await widget.auth.authenticateWithBiometrics();
|
||||
if (!mounted) return;
|
||||
if (ok) {
|
||||
final email = await widget.auth.getEmail() ?? '';
|
||||
_goToDashboard(email);
|
||||
}
|
||||
// on failure, the auth screen stays; user can tap Masuk manually
|
||||
}
|
||||
|
||||
/// On open: if a valid session is present, go straight to Dashboard.
|
||||
Future<void> _trySilentAuth() async {
|
||||
final timeout = await widget.auth.getTimeoutMinutes();
|
||||
@@ -51,7 +81,7 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _submitEmail() async {
|
||||
Future<void> _submit() async {
|
||||
setState(() => _busy = true);
|
||||
final email = _emailCtrl.text.trim();
|
||||
final pass = _passCtrl.text;
|
||||
@@ -113,20 +143,9 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
const SizedBox(height: 12),
|
||||
_busy
|
||||
? const CircularProgressIndicator()
|
||||
: Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: _submitEmail,
|
||||
child: Text(_isLogin ? 'Masuk' : 'Daftar'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () =>
|
||||
setState(() => _isLogin = !_isLogin),
|
||||
child: Text(_isLogin
|
||||
? 'Belum punya akun? Daftar'
|
||||
: 'Sudah punya akun? Masuk'),
|
||||
),
|
||||
],
|
||||
: ElevatedButton(
|
||||
onPressed: _submit,
|
||||
child: Text(_isLogin ? 'Masuk' : 'Daftar'),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user