103 lines
3.7 KiB
Dart
103 lines
3.7 KiB
Dart
/// 인증 계약 — 제공자 인터페이스와 결과 타입.
|
|
///
|
|
/// 원칙: **"키 미투입"은 예외가 아니라 상태다.** 카카오·네이버는 발주사 사업자 정보로
|
|
/// 개발자 콘솔에 앱을 등록해야 키가 나오고(Q3), Google·Apple 은 Firebase 설정 파일이
|
|
/// 있어야 한다(S1·S2). 둘 다 "아직 준비가 안 됐다"이지 "지원하지 않는다"가 아니므로
|
|
/// 예외를 던지지 않고 [AuthNotConfigured] 로 돌려준다. 화면은 이걸 안내로 보여 준다.
|
|
library;
|
|
|
|
/// 소셜 제공자. **순서와 라벨은 시안 `시안/screens/S-A-LOGIN.html` 의 버튼 그대로다.**
|
|
/// 화면명세 `wireframe/planning/screen-spec/onboard/S-A-LOGIN.md` 도 4종으로 같다.
|
|
enum SocialProvider {
|
|
kakao('카카오로 시작하기'),
|
|
naver('네이버로 시작하기'),
|
|
apple('Apple로 시작하기'),
|
|
google('Google로 시작하기');
|
|
|
|
const SocialProvider(this.label);
|
|
|
|
/// 버튼 라벨. 임의로 바꾸지 마라 — 시안 대조 대상이다.
|
|
final String label;
|
|
}
|
|
|
|
// 이메일 가입에 대하여 — 기능 플래그를 두지 않았다.
|
|
//
|
|
// CD-18(가입 수단) 미확정(2주차_확인요청항목 Q2)이라 이메일 경로는 구현하지 않았다.
|
|
// 플래그 상수를 하나 선언해 두는 방법도 있었지만, 그 값을 읽는 분기가 없으면
|
|
// 「false 라서 닫혀 있다」는 착각만 만든다 — 누군가 true 로 바꿔도 아무 일이 일어나지 않는다.
|
|
// 지금 이메일을 닫고 있는 것은 플래그가 아니라 AuthRepository 의 제공자 목록에
|
|
// 이메일 구현체가 없다는 사실 하나다.
|
|
//
|
|
// Q2 가 「이메일 병행」으로 오면 할 일: [SocialAuthProvider] 를 구현한 이메일 제공자를 만들고
|
|
// AuthRepository._defaultProviders() 에 추가한다. 화면 수·약관 동선도 함께 바뀐다.
|
|
|
|
/// 로그인된 계정.
|
|
class AuthAccount {
|
|
const AuthAccount({
|
|
required this.uid,
|
|
required this.provider,
|
|
this.displayName,
|
|
this.email,
|
|
this.isMock = false,
|
|
});
|
|
|
|
final String uid;
|
|
final SocialProvider? provider;
|
|
final String? displayName;
|
|
final String? email;
|
|
|
|
/// Firebase 미설정 상태에서 만든 임시 세션인지. 실 세션과 절대 섞이면 안 된다.
|
|
final bool isMock;
|
|
}
|
|
|
|
/// 로그인 시도 결과.
|
|
sealed class AuthOutcome {
|
|
const AuthOutcome();
|
|
}
|
|
|
|
final class AuthSucceeded extends AuthOutcome {
|
|
const AuthSucceeded(this.account);
|
|
|
|
final AuthAccount account;
|
|
}
|
|
|
|
/// 사용자가 취소함. 에러로 취급하지 않는다.
|
|
final class AuthCancelled extends AuthOutcome {
|
|
const AuthCancelled();
|
|
}
|
|
|
|
/// 실패. [code] 는 `wireframe/planning/error-catalog.yaml` 의 ID 다(소셜 실패 = E-AUTH-03).
|
|
final class AuthFailed extends AuthOutcome {
|
|
const AuthFailed(this.code, this.message);
|
|
|
|
final String code;
|
|
final String message;
|
|
}
|
|
|
|
/// 아직 쓸 수 없음 — 키·설정 파일 미투입.
|
|
final class AuthNotConfigured extends AuthOutcome {
|
|
const AuthNotConfigured(this.provider, this.missing);
|
|
|
|
final SocialProvider provider;
|
|
|
|
/// 투입해야 하는 것들(파일명·키명). 화면과 README 에 그대로 노출한다.
|
|
final List<String> missing;
|
|
}
|
|
|
|
/// 소셜 로그인 제공자 인터페이스.
|
|
///
|
|
/// 이메일 가입이 확정되면(Q2) 같은 인터페이스로 구현체 하나가 더 붙는 자리다.
|
|
abstract interface class SocialAuthProvider {
|
|
SocialProvider get provider;
|
|
|
|
/// 실 연동 코드 경로를 가지고 있는지. 스텁이면 false.
|
|
bool get isLive;
|
|
|
|
/// 비어 있지 않으면 지금은 로그인할 수 없다. [signIn] 은 [AuthNotConfigured] 를 낸다.
|
|
List<String> get missingConfig;
|
|
|
|
Future<AuthOutcome> signIn();
|
|
|
|
Future<void> signOut();
|
|
}
|