forked from baron/baron-sso
논리 검사 계속. 스케폴딩 일부 진행
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:descope/descope.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class LoginScreen extends ConsumerStatefulWidget {
|
||||
const LoginScreen({super.key});
|
||||
@@ -31,14 +33,133 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _handleEmailLogin() {
|
||||
// TODO: Implement Descope Email/Password Flow
|
||||
debugPrint("Email Login: ${_emailController.text}");
|
||||
Future<void> _handleEmailLogin() async {
|
||||
final email = _emailController.text.trim();
|
||||
if (email.isEmpty) return;
|
||||
|
||||
// Determine if it's Password or Enchanted Link flow
|
||||
// For this PoC, we'll try Enchanted Link as primary for 'Email' tab per requirements,
|
||||
// but the UI has a password field. Let's support both based on input.
|
||||
// However, PRD says Primary is Email/Password.
|
||||
|
||||
final password = _passwordController.text;
|
||||
if (password.isNotEmpty) {
|
||||
// Email + Password Flow
|
||||
try {
|
||||
final authResponse = await Descope.auth.password.signIn(
|
||||
loginId: email,
|
||||
password: password,
|
||||
);
|
||||
final session = DescopeSession.fromAuthenticationResponse(authResponse);
|
||||
Descope.sessionManager.manageSession(session);
|
||||
if (mounted) context.go('/dashboard');
|
||||
} catch (e) {
|
||||
_showError("Email/Password Login Failed: $e");
|
||||
}
|
||||
} else {
|
||||
// Enchanted Link Flow (Passwordless)
|
||||
try {
|
||||
// Start Enchanted Link
|
||||
final response = await Descope.auth.enchantedLink.signUpOrIn(
|
||||
loginId: email,
|
||||
uri: "baronsso://auth", // Deep link for the 'Clicked' device
|
||||
);
|
||||
|
||||
// Show Polling Dialog
|
||||
if (mounted) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text("Check your Email"),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text("We sent an email to $email"),
|
||||
const SizedBox(height: 16),
|
||||
const LinearProgressIndicator(),
|
||||
const SizedBox(height: 16),
|
||||
Text("Link: ${response.linkId}"), // Display for debug/PoC
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Poll for completion
|
||||
final authResponse = await Descope.auth.enchantedLink.poll(
|
||||
response.pendingRef,
|
||||
);
|
||||
final session = DescopeSession.fromAuthenticationResponse(
|
||||
authResponse,
|
||||
);
|
||||
Descope.sessionManager.manageSession(session);
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop(); // Close Dialog
|
||||
context.go('/dashboard');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) Navigator.of(context).pop(); // Close dialog if open
|
||||
_showError("Enchanted Link Failed: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _handleSmsLogin() {
|
||||
// TODO: Implement Descope SMS Enchanted Link Flow
|
||||
debugPrint("SMS Login: ${_phoneController.text}");
|
||||
Future<void> _handleSmsLogin() async {
|
||||
final phone = _phoneController.text.trim();
|
||||
if (phone.isEmpty) return;
|
||||
|
||||
try {
|
||||
// Enchanted Link via SMS (Polling)
|
||||
// Note: This assumes Descope project is configured to send SMS for this loginId
|
||||
final response = await Descope.auth.enchantedLink.signUpOrIn(
|
||||
loginId: phone,
|
||||
uri: "baronsso://auth", // Link for the device that receives SMS
|
||||
);
|
||||
|
||||
if (mounted) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text("Check your Messages"),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text("We sent a message to $phone"),
|
||||
const SizedBox(height: 16),
|
||||
const LinearProgressIndicator(),
|
||||
const SizedBox(height: 16),
|
||||
// Text("Link: ${response.linkId}"), // Debug
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Poll for completion
|
||||
final authResponse = await Descope.auth.enchantedLink.poll(
|
||||
response.pendingRef,
|
||||
);
|
||||
final session = DescopeSession.fromAuthenticationResponse(authResponse);
|
||||
Descope.sessionManager.manageSession(session);
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop(); // Close Dialog
|
||||
context.go('/dashboard');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted && Navigator.canPop(context)) Navigator.of(context).pop();
|
||||
_showError("SMS Enchanted Link Failed: $e");
|
||||
}
|
||||
}
|
||||
|
||||
void _showError(String message) {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(message), backgroundColor: Colors.red),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user