first steps for auth in staff app
This commit is contained in:
@@ -1,34 +1,113 @@
|
|||||||
import 'package:krow_data_connect/krow_data_connect.dart';
|
import 'dart:async';
|
||||||
import 'package:krow_domain/krow_domain.dart';
|
|
||||||
|
import 'package:firebase_auth/firebase_auth.dart' as firebase;
|
||||||
|
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
|
||||||
|
import 'package:krow_domain/krow_domain.dart' as domain;
|
||||||
import '../../domain/repositories/auth_repository_interface.dart';
|
import '../../domain/repositories/auth_repository_interface.dart';
|
||||||
|
|
||||||
/// Implementation of [AuthRepositoryInterface].
|
/// Implementation of [AuthRepositoryInterface].
|
||||||
class AuthRepositoryImpl implements AuthRepositoryInterface {
|
class AuthRepositoryImpl implements AuthRepositoryInterface {
|
||||||
final AuthRepositoryMock mock;
|
final firebase.FirebaseAuth _firebaseAuth;
|
||||||
|
final dc.ExampleConnector _dataConnect;
|
||||||
|
|
||||||
AuthRepositoryImpl({required this.mock});
|
AuthRepositoryImpl({
|
||||||
|
required firebase.FirebaseAuth firebaseAuth,
|
||||||
|
required dc.ExampleConnector dataConnect,
|
||||||
|
}) : _firebaseAuth = firebaseAuth,
|
||||||
|
_dataConnect = dataConnect;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<User?> get currentUser => mock.currentUser;
|
Stream<domain.User?> get currentUser => _firebaseAuth
|
||||||
|
.authStateChanges()
|
||||||
|
.map((firebaseUser) {
|
||||||
|
if (firebaseUser == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.User(
|
||||||
|
id: firebaseUser.uid,
|
||||||
|
email: firebaseUser.email ?? '',
|
||||||
|
phone: firebaseUser.phoneNumber,
|
||||||
|
role: 'staff',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
/// Signs in with a phone number and returns a verification ID.
|
/// Signs in with a phone number and returns a verification ID.
|
||||||
@override
|
@override
|
||||||
Future<String?> signInWithPhone({required String phoneNumber}) {
|
Future<String?> signInWithPhone({required String phoneNumber}) async {
|
||||||
return mock.signInWithPhone(phoneNumber);
|
final completer = Completer<String?>();
|
||||||
|
|
||||||
|
await _firebaseAuth.verifyPhoneNumber(
|
||||||
|
phoneNumber: phoneNumber,
|
||||||
|
verificationCompleted: (_) {},
|
||||||
|
verificationFailed: (e) {
|
||||||
|
if (!completer.isCompleted) {
|
||||||
|
completer.completeError(
|
||||||
|
Exception(e.message ?? 'Phone verification failed.'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
codeSent: (verificationId, _) {
|
||||||
|
if (!completer.isCompleted) {
|
||||||
|
completer.complete(verificationId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
codeAutoRetrievalTimeout: (verificationId) {
|
||||||
|
if (!completer.isCompleted) {
|
||||||
|
completer.complete(verificationId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signs out the current user.
|
/// Signs out the current user.
|
||||||
@override
|
@override
|
||||||
Future<void> signOut() {
|
Future<void> signOut() {
|
||||||
return mock.signOut();
|
return _firebaseAuth.signOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verifies an OTP code and returns the authenticated user.
|
/// Verifies an OTP code and returns the authenticated user.
|
||||||
@override
|
@override
|
||||||
Future<User?> verifyOtp({
|
Future<domain.User?> verifyOtp({
|
||||||
required String verificationId,
|
required String verificationId,
|
||||||
required String smsCode,
|
required String smsCode,
|
||||||
}) {
|
}) async {
|
||||||
return mock.verifyOtp(verificationId, smsCode);
|
final credential = firebase.PhoneAuthProvider.credential(
|
||||||
|
verificationId: verificationId,
|
||||||
|
smsCode: smsCode,
|
||||||
|
);
|
||||||
|
final userCredential = await _firebaseAuth.signInWithCredential(credential);
|
||||||
|
final firebaseUser = userCredential.user;
|
||||||
|
if (firebaseUser == null) {
|
||||||
|
throw Exception('Phone verification failed, no Firebase user received.');
|
||||||
|
}
|
||||||
|
|
||||||
|
final response = await _dataConnect.getUserById(
|
||||||
|
id: firebaseUser.uid,
|
||||||
|
).execute();
|
||||||
|
final user = response.data?.user;
|
||||||
|
if (user == null) {
|
||||||
|
await _firebaseAuth.signOut();
|
||||||
|
throw Exception('Authenticated user profile not found in database.');
|
||||||
|
}
|
||||||
|
if (user.userRole != 'STAFF') {
|
||||||
|
await _firebaseAuth.signOut();
|
||||||
|
throw Exception('User is not authorized for this app.');
|
||||||
|
}
|
||||||
|
|
||||||
|
final email = user.email ?? '';
|
||||||
|
if (email.isEmpty) {
|
||||||
|
await _firebaseAuth.signOut();
|
||||||
|
throw Exception('User email is missing in profile data.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.User(
|
||||||
|
id: user.id,
|
||||||
|
email: email,
|
||||||
|
phone: firebaseUser.phoneNumber,
|
||||||
|
role: user.role.stringValue,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ library staff_authentication;
|
|||||||
|
|
||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
import 'package:krow_data_connect/krow_data_connect.dart';
|
import 'package:krow_data_connect/krow_data_connect.dart';
|
||||||
|
import 'package:firebase_auth/firebase_auth.dart' as firebase;
|
||||||
import 'package:staff_authentication/src/data/repositories_impl/auth_repository_impl.dart';
|
import 'package:staff_authentication/src/data/repositories_impl/auth_repository_impl.dart';
|
||||||
import 'package:staff_authentication/src/domain/repositories/auth_repository_interface.dart';
|
import 'package:staff_authentication/src/domain/repositories/auth_repository_interface.dart';
|
||||||
import 'package:staff_authentication/src/domain/usecases/sign_in_with_phone_usecase.dart';
|
import 'package:staff_authentication/src/domain/usecases/sign_in_with_phone_usecase.dart';
|
||||||
@@ -28,7 +29,10 @@ class StaffAuthenticationModule extends Module {
|
|||||||
void binds(Injector i) {
|
void binds(Injector i) {
|
||||||
// Repositories
|
// Repositories
|
||||||
i.addLazySingleton<AuthRepositoryInterface>(
|
i.addLazySingleton<AuthRepositoryInterface>(
|
||||||
() => AuthRepositoryImpl(mock: i.get<AuthRepositoryMock>()),
|
() => AuthRepositoryImpl(
|
||||||
|
firebaseAuth: firebase.FirebaseAuth.instance,
|
||||||
|
dataConnect: ExampleConnector.instance,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// UseCases
|
// UseCases
|
||||||
|
|||||||
Reference in New Issue
Block a user