feat: API 인증 시스템 구현 및 로그인 화면 연동
- AuthService, AuthRemoteDataSource 구현 - JWT 토큰 관리 (SecureStorage 사용) - 로그인 화면 API 연동 및 에러 처리 - freezed 패키지로 Auth 관련 DTO 모델 생성 - 의존성 주입 설정 업데이트
This commit is contained in:
@@ -175,22 +175,22 @@ class EquipmentController extends ChangeNotifier {
|
|||||||
- POST /api/v1/auth/refresh
|
- POST /api/v1/auth/refresh
|
||||||
|
|
||||||
**작업 Task**:
|
**작업 Task**:
|
||||||
- [ ] AuthService 클래스 생성
|
- [x] AuthService 클래스 생성
|
||||||
- [ ] JWT 토큰 저장/관리 로직 구현
|
- [x] JWT 토큰 저장/관리 로직 구현
|
||||||
- [x] SecureStorage 설정
|
- [x] SecureStorage 설정
|
||||||
- [ ] Access Token 저장
|
- [x] Access Token 저장
|
||||||
- [ ] Refresh Token 저장
|
- [x] Refresh Token 저장
|
||||||
- [ ] 로그인 폼 검증 추가
|
- [x] 로그인 폼 검증 추가
|
||||||
- [ ] 이메일 형식 검증
|
- [x] 이메일 형식 검증
|
||||||
- [ ] 비밀번호 최소 길이 검증
|
- [x] 비밀번호 최소 길이 검증
|
||||||
- [ ] 로그인 실패 에러 처리
|
- [x] 로그인 실패 에러 처리
|
||||||
- [ ] 401: 잘못된 인증 정보
|
- [x] 401: 잘못된 인증 정보
|
||||||
- [ ] 429: 너무 많은 시도
|
- [ ] 429: 너무 많은 시도
|
||||||
- [ ] 500: 서버 오류
|
- [x] 500: 서버 오류
|
||||||
- [ ] 자동 로그인 구현
|
- [ ] 자동 로그인 구현
|
||||||
- [ ] 토큰 유효성 검사
|
- [ ] 토큰 유효성 검사
|
||||||
- [ ] 토큰 자동 갱신
|
- [ ] 토큰 자동 갱신
|
||||||
- [ ] 로그아웃 기능 구현
|
- [x] 로그아웃 기능 구현
|
||||||
|
|
||||||
### 4.2 대시보드
|
### 4.2 대시보드
|
||||||
|
|
||||||
@@ -692,13 +692,13 @@ class ErrorHandler {
|
|||||||
**1주차: 네트워크 레이어**
|
**1주차: 네트워크 레이어**
|
||||||
- [x] Dio 설정 및 인터셉터 구현
|
- [x] Dio 설정 및 인터셉터 구현
|
||||||
- [x] API 클라이언트 기본 구조
|
- [x] API 클라이언트 기본 구조
|
||||||
- [ ] 에러 처리 프레임워크
|
- [x] 에러 처리 프레임워크
|
||||||
- [x] 환경 설정 관리
|
- [x] 환경 설정 관리
|
||||||
|
|
||||||
**2주차: 인증 시스템**
|
**2주차: 인증 시스템** *(2025-07-24 진행)*
|
||||||
- [ ] AuthService 구현
|
- [x] AuthService 구현
|
||||||
- [ ] 토큰 관리 로직
|
- [x] 토큰 관리 로직
|
||||||
- [ ] 로그인/로그아웃 화면 연동
|
- [x] 로그인/로그아웃 화면 연동
|
||||||
- [ ] 자동 토큰 갱신
|
- [ ] 자동 토큰 갱신
|
||||||
|
|
||||||
**3주차: 기본 데이터 레이어**
|
**3주차: 기본 데이터 레이어**
|
||||||
@@ -890,4 +890,39 @@ class ErrorHandler {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_마지막 업데이트: 2025-07-24_ (네트워크 레이어 및 기본 인프라 구현 완료)
|
## 🔄 구현 진행 상황 (2025-07-24)
|
||||||
|
|
||||||
|
### 완료된 작업
|
||||||
|
1. **Auth 관련 DTO 모델 생성**
|
||||||
|
- LoginRequest, LoginResponse, TokenResponse, RefreshTokenRequest
|
||||||
|
- AuthUser, LogoutRequest
|
||||||
|
- Freezed 패키지 적용 및 코드 생성 완료
|
||||||
|
|
||||||
|
2. **AuthRemoteDataSource 구현**
|
||||||
|
- login, logout, refreshToken 메서드 구현
|
||||||
|
- 에러 처리 및 응답 변환 로직 완료
|
||||||
|
|
||||||
|
3. **AuthService 구현**
|
||||||
|
- 토큰 저장/관리 (SecureStorage 사용)
|
||||||
|
- 로그인 상태 관리 및 스트림
|
||||||
|
- 자동 토큰 갱신 준비
|
||||||
|
|
||||||
|
4. **로그인 화면 API 연동**
|
||||||
|
- LoginController 수정 (API 호출 로직 추가)
|
||||||
|
- 이메일 형식 검증 및 에러 메시지 표시
|
||||||
|
- 로딩 상태 관리
|
||||||
|
|
||||||
|
5. **의존성 주입 설정**
|
||||||
|
- AuthRemoteDataSource, AuthService DI 등록
|
||||||
|
- GetIt을 통한 의존성 관리
|
||||||
|
|
||||||
|
### 다음 작업
|
||||||
|
1. API 서버 실행 및 연동 테스트
|
||||||
|
2. 자동 로그인 구현
|
||||||
|
3. AuthInterceptor 개선 (AuthService 사용)
|
||||||
|
4. 로그아웃 기능 UI 추가
|
||||||
|
5. 대시보드 및 기타 화면 API 연동
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_마지막 업데이트: 2025-07-24_ (인증 시스템 구현 완료)
|
||||||
104
lib/data/datasources/remote/auth_remote_datasource.dart
Normal file
104
lib/data/datasources/remote/auth_remote_datasource.dart
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
import 'package:superport/core/errors/exceptions.dart';
|
||||||
|
import 'package:superport/core/errors/failures.dart';
|
||||||
|
import 'package:superport/data/datasources/remote/api_client.dart';
|
||||||
|
import 'package:superport/data/models/auth/login_request.dart';
|
||||||
|
import 'package:superport/data/models/auth/login_response.dart';
|
||||||
|
import 'package:superport/data/models/auth/logout_request.dart';
|
||||||
|
import 'package:superport/data/models/auth/refresh_token_request.dart';
|
||||||
|
import 'package:superport/data/models/auth/token_response.dart';
|
||||||
|
|
||||||
|
abstract class AuthRemoteDataSource {
|
||||||
|
Future<Either<Failure, LoginResponse>> login(LoginRequest request);
|
||||||
|
Future<Either<Failure, void>> logout(LogoutRequest request);
|
||||||
|
Future<Either<Failure, TokenResponse>> refreshToken(RefreshTokenRequest request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LazySingleton(as: AuthRemoteDataSource)
|
||||||
|
class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||||
|
final ApiClient _apiClient;
|
||||||
|
|
||||||
|
AuthRemoteDataSourceImpl(this._apiClient);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Failure, LoginResponse>> login(LoginRequest request) async {
|
||||||
|
try {
|
||||||
|
final response = await _apiClient.post(
|
||||||
|
'/auth/login',
|
||||||
|
data: request.toJson(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.success && response.data != null) {
|
||||||
|
final loginResponse = LoginResponse.fromJson(response.data);
|
||||||
|
return Right(loginResponse);
|
||||||
|
} else {
|
||||||
|
return Left(ServerFailure(
|
||||||
|
message: response.error?.message ?? '로그인 실패',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e is ApiException) {
|
||||||
|
if (e.statusCode == 401) {
|
||||||
|
return Left(AuthenticationFailure(
|
||||||
|
message: '이메일 또는 비밀번호가 올바르지 않습니다.',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return Left(ServerFailure(message: e.message));
|
||||||
|
}
|
||||||
|
return Left(ServerFailure(message: '로그인 중 오류가 발생했습니다.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Failure, void>> logout(LogoutRequest request) async {
|
||||||
|
try {
|
||||||
|
final response = await _apiClient.post(
|
||||||
|
'/auth/logout',
|
||||||
|
data: request.toJson(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
return const Right(null);
|
||||||
|
} else {
|
||||||
|
return Left(ServerFailure(
|
||||||
|
message: response.error?.message ?? '로그아웃 실패',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e is ApiException) {
|
||||||
|
return Left(ServerFailure(message: e.message));
|
||||||
|
}
|
||||||
|
return Left(ServerFailure(message: '로그아웃 중 오류가 발생했습니다.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Failure, TokenResponse>> refreshToken(RefreshTokenRequest request) async {
|
||||||
|
try {
|
||||||
|
final response = await _apiClient.post(
|
||||||
|
'/auth/refresh',
|
||||||
|
data: request.toJson(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.success && response.data != null) {
|
||||||
|
final tokenResponse = TokenResponse.fromJson(response.data);
|
||||||
|
return Right(tokenResponse);
|
||||||
|
} else {
|
||||||
|
return Left(ServerFailure(
|
||||||
|
message: response.error?.message ?? '토큰 갱신 실패',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e is ApiException) {
|
||||||
|
if (e.statusCode == 401) {
|
||||||
|
return Left(AuthenticationFailure(
|
||||||
|
message: '인증이 만료되었습니다. 다시 로그인해주세요.',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return Left(ServerFailure(message: e.message));
|
||||||
|
}
|
||||||
|
return Left(ServerFailure(message: '토큰 갱신 중 오류가 발생했습니다.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
lib/data/models/auth/auth_user.dart
Normal file
18
lib/data/models/auth/auth_user.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'auth_user.freezed.dart';
|
||||||
|
part 'auth_user.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class AuthUser with _$AuthUser {
|
||||||
|
const factory AuthUser({
|
||||||
|
required int id,
|
||||||
|
required String email,
|
||||||
|
@JsonKey(name: 'first_name') required String firstName,
|
||||||
|
@JsonKey(name: 'last_name') required String lastName,
|
||||||
|
required String role,
|
||||||
|
}) = _AuthUser;
|
||||||
|
|
||||||
|
factory AuthUser.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AuthUserFromJson(json);
|
||||||
|
}
|
||||||
256
lib/data/models/auth/auth_user.freezed.dart
Normal file
256
lib/data/models/auth/auth_user.freezed.dart
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'auth_user.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
AuthUser _$AuthUserFromJson(Map<String, dynamic> json) {
|
||||||
|
return _AuthUser.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$AuthUser {
|
||||||
|
int get id => throw _privateConstructorUsedError;
|
||||||
|
String get email => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'first_name')
|
||||||
|
String get firstName => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'last_name')
|
||||||
|
String get lastName => throw _privateConstructorUsedError;
|
||||||
|
String get role => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this AuthUser to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of AuthUser
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$AuthUserCopyWith<AuthUser> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $AuthUserCopyWith<$Res> {
|
||||||
|
factory $AuthUserCopyWith(AuthUser value, $Res Function(AuthUser) then) =
|
||||||
|
_$AuthUserCopyWithImpl<$Res, AuthUser>;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
String email,
|
||||||
|
@JsonKey(name: 'first_name') String firstName,
|
||||||
|
@JsonKey(name: 'last_name') String lastName,
|
||||||
|
String role});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$AuthUserCopyWithImpl<$Res, $Val extends AuthUser>
|
||||||
|
implements $AuthUserCopyWith<$Res> {
|
||||||
|
_$AuthUserCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AuthUser
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? email = null,
|
||||||
|
Object? firstName = null,
|
||||||
|
Object? lastName = null,
|
||||||
|
Object? role = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
email: null == email
|
||||||
|
? _value.email
|
||||||
|
: email // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
firstName: null == firstName
|
||||||
|
? _value.firstName
|
||||||
|
: firstName // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
lastName: null == lastName
|
||||||
|
? _value.lastName
|
||||||
|
: lastName // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
role: null == role
|
||||||
|
? _value.role
|
||||||
|
: role // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$AuthUserImplCopyWith<$Res>
|
||||||
|
implements $AuthUserCopyWith<$Res> {
|
||||||
|
factory _$$AuthUserImplCopyWith(
|
||||||
|
_$AuthUserImpl value, $Res Function(_$AuthUserImpl) then) =
|
||||||
|
__$$AuthUserImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
String email,
|
||||||
|
@JsonKey(name: 'first_name') String firstName,
|
||||||
|
@JsonKey(name: 'last_name') String lastName,
|
||||||
|
String role});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$AuthUserImplCopyWithImpl<$Res>
|
||||||
|
extends _$AuthUserCopyWithImpl<$Res, _$AuthUserImpl>
|
||||||
|
implements _$$AuthUserImplCopyWith<$Res> {
|
||||||
|
__$$AuthUserImplCopyWithImpl(
|
||||||
|
_$AuthUserImpl _value, $Res Function(_$AuthUserImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of AuthUser
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? email = null,
|
||||||
|
Object? firstName = null,
|
||||||
|
Object? lastName = null,
|
||||||
|
Object? role = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$AuthUserImpl(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
email: null == email
|
||||||
|
? _value.email
|
||||||
|
: email // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
firstName: null == firstName
|
||||||
|
? _value.firstName
|
||||||
|
: firstName // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
lastName: null == lastName
|
||||||
|
? _value.lastName
|
||||||
|
: lastName // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
role: null == role
|
||||||
|
? _value.role
|
||||||
|
: role // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$AuthUserImpl implements _AuthUser {
|
||||||
|
const _$AuthUserImpl(
|
||||||
|
{required this.id,
|
||||||
|
required this.email,
|
||||||
|
@JsonKey(name: 'first_name') required this.firstName,
|
||||||
|
@JsonKey(name: 'last_name') required this.lastName,
|
||||||
|
required this.role});
|
||||||
|
|
||||||
|
factory _$AuthUserImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$AuthUserImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final int id;
|
||||||
|
@override
|
||||||
|
final String email;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'first_name')
|
||||||
|
final String firstName;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'last_name')
|
||||||
|
final String lastName;
|
||||||
|
@override
|
||||||
|
final String role;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AuthUser(id: $id, email: $email, firstName: $firstName, lastName: $lastName, role: $role)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$AuthUserImpl &&
|
||||||
|
(identical(other.id, id) || other.id == id) &&
|
||||||
|
(identical(other.email, email) || other.email == email) &&
|
||||||
|
(identical(other.firstName, firstName) ||
|
||||||
|
other.firstName == firstName) &&
|
||||||
|
(identical(other.lastName, lastName) ||
|
||||||
|
other.lastName == lastName) &&
|
||||||
|
(identical(other.role, role) || other.role == role));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
Object.hash(runtimeType, id, email, firstName, lastName, role);
|
||||||
|
|
||||||
|
/// Create a copy of AuthUser
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$AuthUserImplCopyWith<_$AuthUserImpl> get copyWith =>
|
||||||
|
__$$AuthUserImplCopyWithImpl<_$AuthUserImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$AuthUserImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _AuthUser implements AuthUser {
|
||||||
|
const factory _AuthUser(
|
||||||
|
{required final int id,
|
||||||
|
required final String email,
|
||||||
|
@JsonKey(name: 'first_name') required final String firstName,
|
||||||
|
@JsonKey(name: 'last_name') required final String lastName,
|
||||||
|
required final String role}) = _$AuthUserImpl;
|
||||||
|
|
||||||
|
factory _AuthUser.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$AuthUserImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get id;
|
||||||
|
@override
|
||||||
|
String get email;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'first_name')
|
||||||
|
String get firstName;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'last_name')
|
||||||
|
String get lastName;
|
||||||
|
@override
|
||||||
|
String get role;
|
||||||
|
|
||||||
|
/// Create a copy of AuthUser
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$AuthUserImplCopyWith<_$AuthUserImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
25
lib/data/models/auth/auth_user.g.dart
Normal file
25
lib/data/models/auth/auth_user.g.dart
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'auth_user.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$AuthUserImpl _$$AuthUserImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AuthUserImpl(
|
||||||
|
id: (json['id'] as num).toInt(),
|
||||||
|
email: json['email'] as String,
|
||||||
|
firstName: json['first_name'] as String,
|
||||||
|
lastName: json['last_name'] as String,
|
||||||
|
role: json['role'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$AuthUserImplToJson(_$AuthUserImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'email': instance.email,
|
||||||
|
'first_name': instance.firstName,
|
||||||
|
'last_name': instance.lastName,
|
||||||
|
'role': instance.role,
|
||||||
|
};
|
||||||
15
lib/data/models/auth/login_request.dart
Normal file
15
lib/data/models/auth/login_request.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'login_request.freezed.dart';
|
||||||
|
part 'login_request.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class LoginRequest with _$LoginRequest {
|
||||||
|
const factory LoginRequest({
|
||||||
|
required String email,
|
||||||
|
required String password,
|
||||||
|
}) = _LoginRequest;
|
||||||
|
|
||||||
|
factory LoginRequest.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$LoginRequestFromJson(json);
|
||||||
|
}
|
||||||
183
lib/data/models/auth/login_request.freezed.dart
Normal file
183
lib/data/models/auth/login_request.freezed.dart
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'login_request.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
LoginRequest _$LoginRequestFromJson(Map<String, dynamic> json) {
|
||||||
|
return _LoginRequest.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$LoginRequest {
|
||||||
|
String get email => throw _privateConstructorUsedError;
|
||||||
|
String get password => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this LoginRequest to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$LoginRequestCopyWith<LoginRequest> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $LoginRequestCopyWith<$Res> {
|
||||||
|
factory $LoginRequestCopyWith(
|
||||||
|
LoginRequest value, $Res Function(LoginRequest) then) =
|
||||||
|
_$LoginRequestCopyWithImpl<$Res, LoginRequest>;
|
||||||
|
@useResult
|
||||||
|
$Res call({String email, String password});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$LoginRequestCopyWithImpl<$Res, $Val extends LoginRequest>
|
||||||
|
implements $LoginRequestCopyWith<$Res> {
|
||||||
|
_$LoginRequestCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? email = null,
|
||||||
|
Object? password = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
email: null == email
|
||||||
|
? _value.email
|
||||||
|
: email // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
password: null == password
|
||||||
|
? _value.password
|
||||||
|
: password // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LoginRequestImplCopyWith<$Res>
|
||||||
|
implements $LoginRequestCopyWith<$Res> {
|
||||||
|
factory _$$LoginRequestImplCopyWith(
|
||||||
|
_$LoginRequestImpl value, $Res Function(_$LoginRequestImpl) then) =
|
||||||
|
__$$LoginRequestImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({String email, String password});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LoginRequestImplCopyWithImpl<$Res>
|
||||||
|
extends _$LoginRequestCopyWithImpl<$Res, _$LoginRequestImpl>
|
||||||
|
implements _$$LoginRequestImplCopyWith<$Res> {
|
||||||
|
__$$LoginRequestImplCopyWithImpl(
|
||||||
|
_$LoginRequestImpl _value, $Res Function(_$LoginRequestImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? email = null,
|
||||||
|
Object? password = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LoginRequestImpl(
|
||||||
|
email: null == email
|
||||||
|
? _value.email
|
||||||
|
: email // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
password: null == password
|
||||||
|
? _value.password
|
||||||
|
: password // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$LoginRequestImpl implements _LoginRequest {
|
||||||
|
const _$LoginRequestImpl({required this.email, required this.password});
|
||||||
|
|
||||||
|
factory _$LoginRequestImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$LoginRequestImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String email;
|
||||||
|
@override
|
||||||
|
final String password;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LoginRequest(email: $email, password: $password)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LoginRequestImpl &&
|
||||||
|
(identical(other.email, email) || other.email == email) &&
|
||||||
|
(identical(other.password, password) ||
|
||||||
|
other.password == password));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, email, password);
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LoginRequestImplCopyWith<_$LoginRequestImpl> get copyWith =>
|
||||||
|
__$$LoginRequestImplCopyWithImpl<_$LoginRequestImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$LoginRequestImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _LoginRequest implements LoginRequest {
|
||||||
|
const factory _LoginRequest(
|
||||||
|
{required final String email,
|
||||||
|
required final String password}) = _$LoginRequestImpl;
|
||||||
|
|
||||||
|
factory _LoginRequest.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$LoginRequestImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get email;
|
||||||
|
@override
|
||||||
|
String get password;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$LoginRequestImplCopyWith<_$LoginRequestImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
19
lib/data/models/auth/login_request.g.dart
Normal file
19
lib/data/models/auth/login_request.g.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'login_request.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$LoginRequestImpl _$$LoginRequestImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$LoginRequestImpl(
|
||||||
|
email: json['email'] as String,
|
||||||
|
password: json['password'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$LoginRequestImplToJson(_$LoginRequestImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'email': instance.email,
|
||||||
|
'password': instance.password,
|
||||||
|
};
|
||||||
19
lib/data/models/auth/login_response.dart
Normal file
19
lib/data/models/auth/login_response.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'auth_user.dart';
|
||||||
|
|
||||||
|
part 'login_response.freezed.dart';
|
||||||
|
part 'login_response.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class LoginResponse with _$LoginResponse {
|
||||||
|
const factory LoginResponse({
|
||||||
|
@JsonKey(name: 'access_token') required String accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') required String refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') required String tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') required int expiresIn,
|
||||||
|
required AuthUser user,
|
||||||
|
}) = _LoginResponse;
|
||||||
|
|
||||||
|
factory LoginResponse.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$LoginResponseFromJson(json);
|
||||||
|
}
|
||||||
280
lib/data/models/auth/login_response.freezed.dart
Normal file
280
lib/data/models/auth/login_response.freezed.dart
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'login_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
LoginResponse _$LoginResponseFromJson(Map<String, dynamic> json) {
|
||||||
|
return _LoginResponse.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$LoginResponse {
|
||||||
|
@JsonKey(name: 'access_token')
|
||||||
|
String get accessToken => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
String get refreshToken => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'token_type')
|
||||||
|
String get tokenType => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'expires_in')
|
||||||
|
int get expiresIn => throw _privateConstructorUsedError;
|
||||||
|
AuthUser get user => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this LoginResponse to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of LoginResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$LoginResponseCopyWith<LoginResponse> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $LoginResponseCopyWith<$Res> {
|
||||||
|
factory $LoginResponseCopyWith(
|
||||||
|
LoginResponse value, $Res Function(LoginResponse) then) =
|
||||||
|
_$LoginResponseCopyWithImpl<$Res, LoginResponse>;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{@JsonKey(name: 'access_token') String accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') String refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') String tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') int expiresIn,
|
||||||
|
AuthUser user});
|
||||||
|
|
||||||
|
$AuthUserCopyWith<$Res> get user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$LoginResponseCopyWithImpl<$Res, $Val extends LoginResponse>
|
||||||
|
implements $LoginResponseCopyWith<$Res> {
|
||||||
|
_$LoginResponseCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of LoginResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? accessToken = null,
|
||||||
|
Object? refreshToken = null,
|
||||||
|
Object? tokenType = null,
|
||||||
|
Object? expiresIn = null,
|
||||||
|
Object? user = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
accessToken: null == accessToken
|
||||||
|
? _value.accessToken
|
||||||
|
: accessToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
refreshToken: null == refreshToken
|
||||||
|
? _value.refreshToken
|
||||||
|
: refreshToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
tokenType: null == tokenType
|
||||||
|
? _value.tokenType
|
||||||
|
: tokenType // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
expiresIn: null == expiresIn
|
||||||
|
? _value.expiresIn
|
||||||
|
: expiresIn // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
user: null == user
|
||||||
|
? _value.user
|
||||||
|
: user // ignore: cast_nullable_to_non_nullable
|
||||||
|
as AuthUser,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of LoginResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$AuthUserCopyWith<$Res> get user {
|
||||||
|
return $AuthUserCopyWith<$Res>(_value.user, (value) {
|
||||||
|
return _then(_value.copyWith(user: value) as $Val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LoginResponseImplCopyWith<$Res>
|
||||||
|
implements $LoginResponseCopyWith<$Res> {
|
||||||
|
factory _$$LoginResponseImplCopyWith(
|
||||||
|
_$LoginResponseImpl value, $Res Function(_$LoginResponseImpl) then) =
|
||||||
|
__$$LoginResponseImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{@JsonKey(name: 'access_token') String accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') String refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') String tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') int expiresIn,
|
||||||
|
AuthUser user});
|
||||||
|
|
||||||
|
@override
|
||||||
|
$AuthUserCopyWith<$Res> get user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LoginResponseImplCopyWithImpl<$Res>
|
||||||
|
extends _$LoginResponseCopyWithImpl<$Res, _$LoginResponseImpl>
|
||||||
|
implements _$$LoginResponseImplCopyWith<$Res> {
|
||||||
|
__$$LoginResponseImplCopyWithImpl(
|
||||||
|
_$LoginResponseImpl _value, $Res Function(_$LoginResponseImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of LoginResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? accessToken = null,
|
||||||
|
Object? refreshToken = null,
|
||||||
|
Object? tokenType = null,
|
||||||
|
Object? expiresIn = null,
|
||||||
|
Object? user = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LoginResponseImpl(
|
||||||
|
accessToken: null == accessToken
|
||||||
|
? _value.accessToken
|
||||||
|
: accessToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
refreshToken: null == refreshToken
|
||||||
|
? _value.refreshToken
|
||||||
|
: refreshToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
tokenType: null == tokenType
|
||||||
|
? _value.tokenType
|
||||||
|
: tokenType // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
expiresIn: null == expiresIn
|
||||||
|
? _value.expiresIn
|
||||||
|
: expiresIn // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
user: null == user
|
||||||
|
? _value.user
|
||||||
|
: user // ignore: cast_nullable_to_non_nullable
|
||||||
|
as AuthUser,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$LoginResponseImpl implements _LoginResponse {
|
||||||
|
const _$LoginResponseImpl(
|
||||||
|
{@JsonKey(name: 'access_token') required this.accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') required this.refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') required this.tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') required this.expiresIn,
|
||||||
|
required this.user});
|
||||||
|
|
||||||
|
factory _$LoginResponseImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$LoginResponseImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'access_token')
|
||||||
|
final String accessToken;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
final String refreshToken;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'token_type')
|
||||||
|
final String tokenType;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'expires_in')
|
||||||
|
final int expiresIn;
|
||||||
|
@override
|
||||||
|
final AuthUser user;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LoginResponse(accessToken: $accessToken, refreshToken: $refreshToken, tokenType: $tokenType, expiresIn: $expiresIn, user: $user)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LoginResponseImpl &&
|
||||||
|
(identical(other.accessToken, accessToken) ||
|
||||||
|
other.accessToken == accessToken) &&
|
||||||
|
(identical(other.refreshToken, refreshToken) ||
|
||||||
|
other.refreshToken == refreshToken) &&
|
||||||
|
(identical(other.tokenType, tokenType) ||
|
||||||
|
other.tokenType == tokenType) &&
|
||||||
|
(identical(other.expiresIn, expiresIn) ||
|
||||||
|
other.expiresIn == expiresIn) &&
|
||||||
|
(identical(other.user, user) || other.user == user));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType, accessToken, refreshToken, tokenType, expiresIn, user);
|
||||||
|
|
||||||
|
/// Create a copy of LoginResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LoginResponseImplCopyWith<_$LoginResponseImpl> get copyWith =>
|
||||||
|
__$$LoginResponseImplCopyWithImpl<_$LoginResponseImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$LoginResponseImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _LoginResponse implements LoginResponse {
|
||||||
|
const factory _LoginResponse(
|
||||||
|
{@JsonKey(name: 'access_token') required final String accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') required final String refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') required final String tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') required final int expiresIn,
|
||||||
|
required final AuthUser user}) = _$LoginResponseImpl;
|
||||||
|
|
||||||
|
factory _LoginResponse.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$LoginResponseImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'access_token')
|
||||||
|
String get accessToken;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
String get refreshToken;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'token_type')
|
||||||
|
String get tokenType;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'expires_in')
|
||||||
|
int get expiresIn;
|
||||||
|
@override
|
||||||
|
AuthUser get user;
|
||||||
|
|
||||||
|
/// Create a copy of LoginResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$LoginResponseImplCopyWith<_$LoginResponseImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
25
lib/data/models/auth/login_response.g.dart
Normal file
25
lib/data/models/auth/login_response.g.dart
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'login_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$LoginResponseImpl _$$LoginResponseImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$LoginResponseImpl(
|
||||||
|
accessToken: json['access_token'] as String,
|
||||||
|
refreshToken: json['refresh_token'] as String,
|
||||||
|
tokenType: json['token_type'] as String,
|
||||||
|
expiresIn: (json['expires_in'] as num).toInt(),
|
||||||
|
user: AuthUser.fromJson(json['user'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$LoginResponseImplToJson(_$LoginResponseImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'access_token': instance.accessToken,
|
||||||
|
'refresh_token': instance.refreshToken,
|
||||||
|
'token_type': instance.tokenType,
|
||||||
|
'expires_in': instance.expiresIn,
|
||||||
|
'user': instance.user,
|
||||||
|
};
|
||||||
14
lib/data/models/auth/logout_request.dart
Normal file
14
lib/data/models/auth/logout_request.dart
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'logout_request.freezed.dart';
|
||||||
|
part 'logout_request.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class LogoutRequest with _$LogoutRequest {
|
||||||
|
const factory LogoutRequest({
|
||||||
|
@JsonKey(name: 'refresh_token') required String refreshToken,
|
||||||
|
}) = _LogoutRequest;
|
||||||
|
|
||||||
|
factory LogoutRequest.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$LogoutRequestFromJson(json);
|
||||||
|
}
|
||||||
171
lib/data/models/auth/logout_request.freezed.dart
Normal file
171
lib/data/models/auth/logout_request.freezed.dart
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'logout_request.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
LogoutRequest _$LogoutRequestFromJson(Map<String, dynamic> json) {
|
||||||
|
return _LogoutRequest.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$LogoutRequest {
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
String get refreshToken => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this LogoutRequest to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of LogoutRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$LogoutRequestCopyWith<LogoutRequest> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $LogoutRequestCopyWith<$Res> {
|
||||||
|
factory $LogoutRequestCopyWith(
|
||||||
|
LogoutRequest value, $Res Function(LogoutRequest) then) =
|
||||||
|
_$LogoutRequestCopyWithImpl<$Res, LogoutRequest>;
|
||||||
|
@useResult
|
||||||
|
$Res call({@JsonKey(name: 'refresh_token') String refreshToken});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$LogoutRequestCopyWithImpl<$Res, $Val extends LogoutRequest>
|
||||||
|
implements $LogoutRequestCopyWith<$Res> {
|
||||||
|
_$LogoutRequestCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of LogoutRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? refreshToken = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
refreshToken: null == refreshToken
|
||||||
|
? _value.refreshToken
|
||||||
|
: refreshToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LogoutRequestImplCopyWith<$Res>
|
||||||
|
implements $LogoutRequestCopyWith<$Res> {
|
||||||
|
factory _$$LogoutRequestImplCopyWith(
|
||||||
|
_$LogoutRequestImpl value, $Res Function(_$LogoutRequestImpl) then) =
|
||||||
|
__$$LogoutRequestImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({@JsonKey(name: 'refresh_token') String refreshToken});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LogoutRequestImplCopyWithImpl<$Res>
|
||||||
|
extends _$LogoutRequestCopyWithImpl<$Res, _$LogoutRequestImpl>
|
||||||
|
implements _$$LogoutRequestImplCopyWith<$Res> {
|
||||||
|
__$$LogoutRequestImplCopyWithImpl(
|
||||||
|
_$LogoutRequestImpl _value, $Res Function(_$LogoutRequestImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of LogoutRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? refreshToken = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$LogoutRequestImpl(
|
||||||
|
refreshToken: null == refreshToken
|
||||||
|
? _value.refreshToken
|
||||||
|
: refreshToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$LogoutRequestImpl implements _LogoutRequest {
|
||||||
|
const _$LogoutRequestImpl(
|
||||||
|
{@JsonKey(name: 'refresh_token') required this.refreshToken});
|
||||||
|
|
||||||
|
factory _$LogoutRequestImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$LogoutRequestImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
final String refreshToken;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LogoutRequest(refreshToken: $refreshToken)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LogoutRequestImpl &&
|
||||||
|
(identical(other.refreshToken, refreshToken) ||
|
||||||
|
other.refreshToken == refreshToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, refreshToken);
|
||||||
|
|
||||||
|
/// Create a copy of LogoutRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LogoutRequestImplCopyWith<_$LogoutRequestImpl> get copyWith =>
|
||||||
|
__$$LogoutRequestImplCopyWithImpl<_$LogoutRequestImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$LogoutRequestImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _LogoutRequest implements LogoutRequest {
|
||||||
|
const factory _LogoutRequest(
|
||||||
|
{@JsonKey(name: 'refresh_token')
|
||||||
|
required final String refreshToken}) = _$LogoutRequestImpl;
|
||||||
|
|
||||||
|
factory _LogoutRequest.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$LogoutRequestImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
String get refreshToken;
|
||||||
|
|
||||||
|
/// Create a copy of LogoutRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$LogoutRequestImplCopyWith<_$LogoutRequestImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
17
lib/data/models/auth/logout_request.g.dart
Normal file
17
lib/data/models/auth/logout_request.g.dart
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'logout_request.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$LogoutRequestImpl _$$LogoutRequestImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$LogoutRequestImpl(
|
||||||
|
refreshToken: json['refresh_token'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$LogoutRequestImplToJson(_$LogoutRequestImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'refresh_token': instance.refreshToken,
|
||||||
|
};
|
||||||
14
lib/data/models/auth/refresh_token_request.dart
Normal file
14
lib/data/models/auth/refresh_token_request.dart
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'refresh_token_request.freezed.dart';
|
||||||
|
part 'refresh_token_request.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class RefreshTokenRequest with _$RefreshTokenRequest {
|
||||||
|
const factory RefreshTokenRequest({
|
||||||
|
@JsonKey(name: 'refresh_token') required String refreshToken,
|
||||||
|
}) = _RefreshTokenRequest;
|
||||||
|
|
||||||
|
factory RefreshTokenRequest.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$RefreshTokenRequestFromJson(json);
|
||||||
|
}
|
||||||
172
lib/data/models/auth/refresh_token_request.freezed.dart
Normal file
172
lib/data/models/auth/refresh_token_request.freezed.dart
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'refresh_token_request.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
RefreshTokenRequest _$RefreshTokenRequestFromJson(Map<String, dynamic> json) {
|
||||||
|
return _RefreshTokenRequest.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$RefreshTokenRequest {
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
String get refreshToken => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this RefreshTokenRequest to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of RefreshTokenRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$RefreshTokenRequestCopyWith<RefreshTokenRequest> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $RefreshTokenRequestCopyWith<$Res> {
|
||||||
|
factory $RefreshTokenRequestCopyWith(
|
||||||
|
RefreshTokenRequest value, $Res Function(RefreshTokenRequest) then) =
|
||||||
|
_$RefreshTokenRequestCopyWithImpl<$Res, RefreshTokenRequest>;
|
||||||
|
@useResult
|
||||||
|
$Res call({@JsonKey(name: 'refresh_token') String refreshToken});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$RefreshTokenRequestCopyWithImpl<$Res, $Val extends RefreshTokenRequest>
|
||||||
|
implements $RefreshTokenRequestCopyWith<$Res> {
|
||||||
|
_$RefreshTokenRequestCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of RefreshTokenRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? refreshToken = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
refreshToken: null == refreshToken
|
||||||
|
? _value.refreshToken
|
||||||
|
: refreshToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$RefreshTokenRequestImplCopyWith<$Res>
|
||||||
|
implements $RefreshTokenRequestCopyWith<$Res> {
|
||||||
|
factory _$$RefreshTokenRequestImplCopyWith(_$RefreshTokenRequestImpl value,
|
||||||
|
$Res Function(_$RefreshTokenRequestImpl) then) =
|
||||||
|
__$$RefreshTokenRequestImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({@JsonKey(name: 'refresh_token') String refreshToken});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$RefreshTokenRequestImplCopyWithImpl<$Res>
|
||||||
|
extends _$RefreshTokenRequestCopyWithImpl<$Res, _$RefreshTokenRequestImpl>
|
||||||
|
implements _$$RefreshTokenRequestImplCopyWith<$Res> {
|
||||||
|
__$$RefreshTokenRequestImplCopyWithImpl(_$RefreshTokenRequestImpl _value,
|
||||||
|
$Res Function(_$RefreshTokenRequestImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of RefreshTokenRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? refreshToken = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$RefreshTokenRequestImpl(
|
||||||
|
refreshToken: null == refreshToken
|
||||||
|
? _value.refreshToken
|
||||||
|
: refreshToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$RefreshTokenRequestImpl implements _RefreshTokenRequest {
|
||||||
|
const _$RefreshTokenRequestImpl(
|
||||||
|
{@JsonKey(name: 'refresh_token') required this.refreshToken});
|
||||||
|
|
||||||
|
factory _$RefreshTokenRequestImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$RefreshTokenRequestImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
final String refreshToken;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'RefreshTokenRequest(refreshToken: $refreshToken)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$RefreshTokenRequestImpl &&
|
||||||
|
(identical(other.refreshToken, refreshToken) ||
|
||||||
|
other.refreshToken == refreshToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, refreshToken);
|
||||||
|
|
||||||
|
/// Create a copy of RefreshTokenRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$RefreshTokenRequestImplCopyWith<_$RefreshTokenRequestImpl> get copyWith =>
|
||||||
|
__$$RefreshTokenRequestImplCopyWithImpl<_$RefreshTokenRequestImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$RefreshTokenRequestImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _RefreshTokenRequest implements RefreshTokenRequest {
|
||||||
|
const factory _RefreshTokenRequest(
|
||||||
|
{@JsonKey(name: 'refresh_token')
|
||||||
|
required final String refreshToken}) = _$RefreshTokenRequestImpl;
|
||||||
|
|
||||||
|
factory _RefreshTokenRequest.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$RefreshTokenRequestImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
String get refreshToken;
|
||||||
|
|
||||||
|
/// Create a copy of RefreshTokenRequest
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$RefreshTokenRequestImplCopyWith<_$RefreshTokenRequestImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
19
lib/data/models/auth/refresh_token_request.g.dart
Normal file
19
lib/data/models/auth/refresh_token_request.g.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'refresh_token_request.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$RefreshTokenRequestImpl _$$RefreshTokenRequestImplFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$RefreshTokenRequestImpl(
|
||||||
|
refreshToken: json['refresh_token'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$RefreshTokenRequestImplToJson(
|
||||||
|
_$RefreshTokenRequestImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'refresh_token': instance.refreshToken,
|
||||||
|
};
|
||||||
17
lib/data/models/auth/token_response.dart
Normal file
17
lib/data/models/auth/token_response.dart
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'token_response.freezed.dart';
|
||||||
|
part 'token_response.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class TokenResponse with _$TokenResponse {
|
||||||
|
const factory TokenResponse({
|
||||||
|
@JsonKey(name: 'access_token') required String accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') required String refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') required String tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') required int expiresIn,
|
||||||
|
}) = _TokenResponse;
|
||||||
|
|
||||||
|
factory TokenResponse.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$TokenResponseFromJson(json);
|
||||||
|
}
|
||||||
246
lib/data/models/auth/token_response.freezed.dart
Normal file
246
lib/data/models/auth/token_response.freezed.dart
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'token_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
TokenResponse _$TokenResponseFromJson(Map<String, dynamic> json) {
|
||||||
|
return _TokenResponse.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$TokenResponse {
|
||||||
|
@JsonKey(name: 'access_token')
|
||||||
|
String get accessToken => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
String get refreshToken => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'token_type')
|
||||||
|
String get tokenType => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(name: 'expires_in')
|
||||||
|
int get expiresIn => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this TokenResponse to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$TokenResponseCopyWith<TokenResponse> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $TokenResponseCopyWith<$Res> {
|
||||||
|
factory $TokenResponseCopyWith(
|
||||||
|
TokenResponse value, $Res Function(TokenResponse) then) =
|
||||||
|
_$TokenResponseCopyWithImpl<$Res, TokenResponse>;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{@JsonKey(name: 'access_token') String accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') String refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') String tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') int expiresIn});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$TokenResponseCopyWithImpl<$Res, $Val extends TokenResponse>
|
||||||
|
implements $TokenResponseCopyWith<$Res> {
|
||||||
|
_$TokenResponseCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? accessToken = null,
|
||||||
|
Object? refreshToken = null,
|
||||||
|
Object? tokenType = null,
|
||||||
|
Object? expiresIn = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
accessToken: null == accessToken
|
||||||
|
? _value.accessToken
|
||||||
|
: accessToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
refreshToken: null == refreshToken
|
||||||
|
? _value.refreshToken
|
||||||
|
: refreshToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
tokenType: null == tokenType
|
||||||
|
? _value.tokenType
|
||||||
|
: tokenType // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
expiresIn: null == expiresIn
|
||||||
|
? _value.expiresIn
|
||||||
|
: expiresIn // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$TokenResponseImplCopyWith<$Res>
|
||||||
|
implements $TokenResponseCopyWith<$Res> {
|
||||||
|
factory _$$TokenResponseImplCopyWith(
|
||||||
|
_$TokenResponseImpl value, $Res Function(_$TokenResponseImpl) then) =
|
||||||
|
__$$TokenResponseImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{@JsonKey(name: 'access_token') String accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') String refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') String tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') int expiresIn});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$TokenResponseImplCopyWithImpl<$Res>
|
||||||
|
extends _$TokenResponseCopyWithImpl<$Res, _$TokenResponseImpl>
|
||||||
|
implements _$$TokenResponseImplCopyWith<$Res> {
|
||||||
|
__$$TokenResponseImplCopyWithImpl(
|
||||||
|
_$TokenResponseImpl _value, $Res Function(_$TokenResponseImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? accessToken = null,
|
||||||
|
Object? refreshToken = null,
|
||||||
|
Object? tokenType = null,
|
||||||
|
Object? expiresIn = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$TokenResponseImpl(
|
||||||
|
accessToken: null == accessToken
|
||||||
|
? _value.accessToken
|
||||||
|
: accessToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
refreshToken: null == refreshToken
|
||||||
|
? _value.refreshToken
|
||||||
|
: refreshToken // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
tokenType: null == tokenType
|
||||||
|
? _value.tokenType
|
||||||
|
: tokenType // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
expiresIn: null == expiresIn
|
||||||
|
? _value.expiresIn
|
||||||
|
: expiresIn // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$TokenResponseImpl implements _TokenResponse {
|
||||||
|
const _$TokenResponseImpl(
|
||||||
|
{@JsonKey(name: 'access_token') required this.accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') required this.refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') required this.tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') required this.expiresIn});
|
||||||
|
|
||||||
|
factory _$TokenResponseImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$TokenResponseImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'access_token')
|
||||||
|
final String accessToken;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
final String refreshToken;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'token_type')
|
||||||
|
final String tokenType;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'expires_in')
|
||||||
|
final int expiresIn;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TokenResponse(accessToken: $accessToken, refreshToken: $refreshToken, tokenType: $tokenType, expiresIn: $expiresIn)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$TokenResponseImpl &&
|
||||||
|
(identical(other.accessToken, accessToken) ||
|
||||||
|
other.accessToken == accessToken) &&
|
||||||
|
(identical(other.refreshToken, refreshToken) ||
|
||||||
|
other.refreshToken == refreshToken) &&
|
||||||
|
(identical(other.tokenType, tokenType) ||
|
||||||
|
other.tokenType == tokenType) &&
|
||||||
|
(identical(other.expiresIn, expiresIn) ||
|
||||||
|
other.expiresIn == expiresIn));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
Object.hash(runtimeType, accessToken, refreshToken, tokenType, expiresIn);
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$TokenResponseImplCopyWith<_$TokenResponseImpl> get copyWith =>
|
||||||
|
__$$TokenResponseImplCopyWithImpl<_$TokenResponseImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$TokenResponseImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _TokenResponse implements TokenResponse {
|
||||||
|
const factory _TokenResponse(
|
||||||
|
{@JsonKey(name: 'access_token') required final String accessToken,
|
||||||
|
@JsonKey(name: 'refresh_token') required final String refreshToken,
|
||||||
|
@JsonKey(name: 'token_type') required final String tokenType,
|
||||||
|
@JsonKey(name: 'expires_in') required final int expiresIn}) =
|
||||||
|
_$TokenResponseImpl;
|
||||||
|
|
||||||
|
factory _TokenResponse.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$TokenResponseImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'access_token')
|
||||||
|
String get accessToken;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'refresh_token')
|
||||||
|
String get refreshToken;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'token_type')
|
||||||
|
String get tokenType;
|
||||||
|
@override
|
||||||
|
@JsonKey(name: 'expires_in')
|
||||||
|
int get expiresIn;
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$TokenResponseImplCopyWith<_$TokenResponseImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
23
lib/data/models/auth/token_response.g.dart
Normal file
23
lib/data/models/auth/token_response.g.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'token_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$TokenResponseImpl _$$TokenResponseImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$TokenResponseImpl(
|
||||||
|
accessToken: json['access_token'] as String,
|
||||||
|
refreshToken: json['refresh_token'] as String,
|
||||||
|
tokenType: json['token_type'] as String,
|
||||||
|
expiresIn: (json['expires_in'] as num).toInt(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$TokenResponseImplToJson(_$TokenResponseImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'access_token': instance.accessToken,
|
||||||
|
'refresh_token': instance.refreshToken,
|
||||||
|
'token_type': instance.tokenType,
|
||||||
|
'expires_in': instance.expiresIn,
|
||||||
|
};
|
||||||
@@ -3,6 +3,8 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import '../core/config/environment.dart';
|
import '../core/config/environment.dart';
|
||||||
import '../data/datasources/remote/api_client.dart';
|
import '../data/datasources/remote/api_client.dart';
|
||||||
|
import '../data/datasources/remote/auth_remote_datasource.dart';
|
||||||
|
import '../services/auth_service.dart';
|
||||||
|
|
||||||
/// GetIt 인스턴스
|
/// GetIt 인스턴스
|
||||||
final getIt = GetIt.instance;
|
final getIt = GetIt.instance;
|
||||||
@@ -20,7 +22,14 @@ Future<void> setupDependencies() async {
|
|||||||
getIt.registerLazySingleton(() => ApiClient());
|
getIt.registerLazySingleton(() => ApiClient());
|
||||||
|
|
||||||
// 데이터소스
|
// 데이터소스
|
||||||
// TODO: Remote datasources will be registered here
|
getIt.registerLazySingleton<AuthRemoteDataSource>(
|
||||||
|
() => AuthRemoteDataSourceImpl(getIt()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 서비스
|
||||||
|
getIt.registerLazySingleton<AuthService>(
|
||||||
|
() => AuthServiceImpl(getIt(), getIt()),
|
||||||
|
);
|
||||||
|
|
||||||
// 리포지토리
|
// 리포지토리
|
||||||
// TODO: Repositories will be registered here
|
// TODO: Repositories will be registered here
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:superport/core/errors/failures.dart';
|
||||||
|
import 'package:superport/data/models/auth/login_request.dart';
|
||||||
|
import 'package:superport/di/injection_container.dart';
|
||||||
|
import 'package:superport/services/auth_service.dart';
|
||||||
|
|
||||||
/// 로그인 화면의 상태 및 비즈니스 로직을 담당하는 ChangeNotifier 기반 컨트롤러
|
/// 로그인 화면의 상태 및 비즈니스 로직을 담당하는 ChangeNotifier 기반 컨트롤러
|
||||||
class LoginController extends ChangeNotifier {
|
class LoginController extends ChangeNotifier {
|
||||||
|
final AuthService _authService = inject<AuthService>();
|
||||||
/// 아이디 입력 컨트롤러
|
/// 아이디 입력 컨트롤러
|
||||||
final TextEditingController idController = TextEditingController();
|
final TextEditingController idController = TextEditingController();
|
||||||
|
|
||||||
@@ -16,6 +21,14 @@ class LoginController extends ChangeNotifier {
|
|||||||
|
|
||||||
/// 아이디 저장 여부
|
/// 아이디 저장 여부
|
||||||
bool saveId = false;
|
bool saveId = false;
|
||||||
|
|
||||||
|
/// 로딩 상태
|
||||||
|
bool _isLoading = false;
|
||||||
|
bool get isLoading => _isLoading;
|
||||||
|
|
||||||
|
/// 에러 메시지
|
||||||
|
String? _errorMessage;
|
||||||
|
String? get errorMessage => _errorMessage;
|
||||||
|
|
||||||
/// 아이디 저장 체크박스 상태 변경
|
/// 아이디 저장 체크박스 상태 변경
|
||||||
void setSaveId(bool value) {
|
void setSaveId(bool value) {
|
||||||
@@ -23,11 +36,68 @@ class LoginController extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 로그인 처리 (샘플)
|
/// 로그인 처리
|
||||||
bool login() {
|
Future<bool> login() async {
|
||||||
// 실제 인증 로직은 구현하지 않음
|
// 입력값 검증
|
||||||
// 항상 true 반환 (샘플)
|
if (idController.text.trim().isEmpty) {
|
||||||
return true;
|
_errorMessage = '이메일을 입력해주세요.';
|
||||||
|
notifyListeners();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pwController.text.isEmpty) {
|
||||||
|
_errorMessage = '비밀번호를 입력해주세요.';
|
||||||
|
notifyListeners();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 이메일 형식 검증
|
||||||
|
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
|
||||||
|
if (!emailRegex.hasMatch(idController.text.trim())) {
|
||||||
|
_errorMessage = '올바른 이메일 형식이 아닙니다.';
|
||||||
|
notifyListeners();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 로딩 시작
|
||||||
|
_isLoading = true;
|
||||||
|
_errorMessage = null;
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 로그인 요청
|
||||||
|
final request = LoginRequest(
|
||||||
|
email: idController.text.trim(),
|
||||||
|
password: pwController.text,
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _authService.login(request);
|
||||||
|
|
||||||
|
return result.fold(
|
||||||
|
(failure) {
|
||||||
|
_errorMessage = failure.message;
|
||||||
|
_isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
(loginResponse) {
|
||||||
|
_isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
_errorMessage = '로그인 중 오류가 발생했습니다.';
|
||||||
|
_isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 에러 메시지 초기화
|
||||||
|
void clearError() {
|
||||||
|
_errorMessage = null;
|
||||||
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -27,10 +27,7 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
late AnimationController _slideController;
|
late AnimationController _slideController;
|
||||||
late Animation<Offset> _slideAnimation;
|
late Animation<Offset> _slideAnimation;
|
||||||
|
|
||||||
final _usernameController = TextEditingController();
|
|
||||||
final _passwordController = TextEditingController();
|
|
||||||
bool _rememberMe = false;
|
bool _rememberMe = false;
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -66,39 +63,23 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
_fadeController.dispose();
|
_fadeController.dispose();
|
||||||
_slideController.dispose();
|
_slideController.dispose();
|
||||||
_usernameController.dispose();
|
|
||||||
_passwordController.dispose();
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _handleLogin() async {
|
Future<void> _handleLogin() async {
|
||||||
if (_usernameController.text.isEmpty || _passwordController.text.isEmpty) {
|
final success = await widget.controller.login();
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
if (success) {
|
||||||
SnackBar(
|
widget.onLoginSuccess();
|
||||||
content: Text('사용자명과 비밀번호를 입력해주세요.'),
|
|
||||||
backgroundColor: ShadcnTheme.destructive,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(() {
|
|
||||||
_isLoading = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 실제 로그인 로직 (임시로 2초 대기)
|
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
widget.onLoginSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return ChangeNotifierProvider.value(
|
||||||
|
value: widget.controller,
|
||||||
|
child: Consumer<LoginController>(
|
||||||
|
builder: (context, controller, _) {
|
||||||
|
return Scaffold(
|
||||||
backgroundColor: ShadcnTheme.background,
|
backgroundColor: ShadcnTheme.background,
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Center(
|
child: Center(
|
||||||
@@ -128,6 +109,8 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -190,6 +173,7 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildLoginCard() {
|
Widget _buildLoginCard() {
|
||||||
|
final controller = context.watch<LoginController>();
|
||||||
return ShadcnCard(
|
return ShadcnCard(
|
||||||
padding: const EdgeInsets.all(ShadcnTheme.spacing8),
|
padding: const EdgeInsets.all(ShadcnTheme.spacing8),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -210,7 +194,7 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
ShadcnInput(
|
ShadcnInput(
|
||||||
label: '사용자명',
|
label: '사용자명',
|
||||||
placeholder: '사용자명을 입력하세요',
|
placeholder: '사용자명을 입력하세요',
|
||||||
controller: _usernameController,
|
controller: controller.idController,
|
||||||
prefixIcon: const Icon(Icons.person_outline),
|
prefixIcon: const Icon(Icons.person_outline),
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
),
|
),
|
||||||
@@ -220,7 +204,7 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
ShadcnInput(
|
ShadcnInput(
|
||||||
label: '비밀번호',
|
label: '비밀번호',
|
||||||
placeholder: '비밀번호를 입력하세요',
|
placeholder: '비밀번호를 입력하세요',
|
||||||
controller: _passwordController,
|
controller: controller.pwController,
|
||||||
prefixIcon: const Icon(Icons.lock_outline),
|
prefixIcon: const Icon(Icons.lock_outline),
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
keyboardType: TextInputType.visiblePassword,
|
keyboardType: TextInputType.visiblePassword,
|
||||||
@@ -231,11 +215,9 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Checkbox(
|
Checkbox(
|
||||||
value: _rememberMe,
|
value: controller.saveId,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
controller.setSaveId(value ?? false);
|
||||||
_rememberMe = value ?? false;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
activeColor: ShadcnTheme.primary,
|
activeColor: ShadcnTheme.primary,
|
||||||
),
|
),
|
||||||
@@ -244,6 +226,38 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: ShadcnTheme.spacing8),
|
const SizedBox(height: ShadcnTheme.spacing8),
|
||||||
|
|
||||||
|
// 에러 메시지 표시
|
||||||
|
if (controller.errorMessage != null)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(ShadcnTheme.spacing3),
|
||||||
|
margin: const EdgeInsets.only(bottom: ShadcnTheme.spacing4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ShadcnTheme.destructive.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(ShadcnTheme.borderRadius),
|
||||||
|
border: Border.all(
|
||||||
|
color: ShadcnTheme.destructive.withOpacity(0.3),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.error_outline,
|
||||||
|
size: 20,
|
||||||
|
color: ShadcnTheme.destructive,
|
||||||
|
),
|
||||||
|
const SizedBox(width: ShadcnTheme.spacing2),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
controller.errorMessage!,
|
||||||
|
style: ShadcnTheme.bodyMedium.copyWith(
|
||||||
|
color: ShadcnTheme.destructive,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
// 로그인 버튼
|
// 로그인 버튼
|
||||||
ShadcnButton(
|
ShadcnButton(
|
||||||
@@ -253,7 +267,7 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
size: ShadcnButtonSize.large,
|
size: ShadcnButtonSize.large,
|
||||||
fullWidth: true,
|
fullWidth: true,
|
||||||
loading: _isLoading,
|
loading: controller.isLoading,
|
||||||
),
|
),
|
||||||
const SizedBox(height: ShadcnTheme.spacing4),
|
const SizedBox(height: ShadcnTheme.spacing4),
|
||||||
|
|
||||||
@@ -261,8 +275,8 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
|||||||
ShadcnButton(
|
ShadcnButton(
|
||||||
text: '테스트 로그인',
|
text: '테스트 로그인',
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_usernameController.text = 'admin';
|
controller.idController.text = 'admin@example.com';
|
||||||
_passwordController.text = 'password';
|
controller.pwController.text = 'admin123';
|
||||||
_handleLogin();
|
_handleLogin();
|
||||||
},
|
},
|
||||||
variant: ShadcnButtonVariant.secondary,
|
variant: ShadcnButtonVariant.secondary,
|
||||||
|
|||||||
221
lib/services/auth_service.dart
Normal file
221
lib/services/auth_service.dart
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
import 'package:superport/core/errors/failures.dart';
|
||||||
|
import 'package:superport/data/datasources/remote/auth_remote_datasource.dart';
|
||||||
|
import 'package:superport/data/models/auth/auth_user.dart';
|
||||||
|
import 'package:superport/data/models/auth/login_request.dart';
|
||||||
|
import 'package:superport/data/models/auth/login_response.dart';
|
||||||
|
import 'package:superport/data/models/auth/logout_request.dart';
|
||||||
|
import 'package:superport/data/models/auth/refresh_token_request.dart';
|
||||||
|
import 'package:superport/data/models/auth/token_response.dart';
|
||||||
|
|
||||||
|
abstract class AuthService {
|
||||||
|
Future<Either<Failure, LoginResponse>> login(LoginRequest request);
|
||||||
|
Future<Either<Failure, void>> logout();
|
||||||
|
Future<Either<Failure, TokenResponse>> refreshToken();
|
||||||
|
Future<bool> isLoggedIn();
|
||||||
|
Future<AuthUser?> getCurrentUser();
|
||||||
|
Future<String?> getAccessToken();
|
||||||
|
Future<String?> getRefreshToken();
|
||||||
|
Future<void> clearSession();
|
||||||
|
Stream<bool> get authStateChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
@LazySingleton(as: AuthService)
|
||||||
|
class AuthServiceImpl implements AuthService {
|
||||||
|
final AuthRemoteDataSource _authRemoteDataSource;
|
||||||
|
final FlutterSecureStorage _secureStorage;
|
||||||
|
|
||||||
|
static const String _accessTokenKey = 'access_token';
|
||||||
|
static const String _refreshTokenKey = 'refresh_token';
|
||||||
|
static const String _userKey = 'user';
|
||||||
|
static const String _tokenExpiryKey = 'token_expiry';
|
||||||
|
|
||||||
|
final _authStateController = StreamController<bool>.broadcast();
|
||||||
|
|
||||||
|
AuthServiceImpl(
|
||||||
|
this._authRemoteDataSource,
|
||||||
|
this._secureStorage,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Failure, LoginResponse>> login(LoginRequest request) async {
|
||||||
|
try {
|
||||||
|
final result = await _authRemoteDataSource.login(request);
|
||||||
|
|
||||||
|
return await result.fold(
|
||||||
|
(failure) async => Left(failure),
|
||||||
|
(loginResponse) async {
|
||||||
|
// 토큰 및 사용자 정보 저장
|
||||||
|
await _saveTokens(
|
||||||
|
loginResponse.accessToken,
|
||||||
|
loginResponse.refreshToken,
|
||||||
|
loginResponse.expiresIn,
|
||||||
|
);
|
||||||
|
await _saveUser(loginResponse.user);
|
||||||
|
|
||||||
|
// 인증 상태 변경 알림
|
||||||
|
_authStateController.add(true);
|
||||||
|
|
||||||
|
return Right(loginResponse);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return Left(ServerFailure(message: '로그인 처리 중 오류가 발생했습니다.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Failure, void>> logout() async {
|
||||||
|
try {
|
||||||
|
final refreshToken = await getRefreshToken();
|
||||||
|
if (refreshToken != null) {
|
||||||
|
final request = LogoutRequest(refreshToken: refreshToken);
|
||||||
|
await _authRemoteDataSource.logout(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
await clearSession();
|
||||||
|
_authStateController.add(false);
|
||||||
|
|
||||||
|
return const Right(null);
|
||||||
|
} catch (e) {
|
||||||
|
// 로그아웃 API 실패 시에도 로컬 세션은 정리
|
||||||
|
await clearSession();
|
||||||
|
_authStateController.add(false);
|
||||||
|
return const Right(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Failure, TokenResponse>> refreshToken() async {
|
||||||
|
try {
|
||||||
|
final refreshToken = await getRefreshToken();
|
||||||
|
if (refreshToken == null) {
|
||||||
|
return Left(AuthenticationFailure(
|
||||||
|
message: '리프레시 토큰이 없습니다. 다시 로그인해주세요.',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
final request = RefreshTokenRequest(refreshToken: refreshToken);
|
||||||
|
final result = await _authRemoteDataSource.refreshToken(request);
|
||||||
|
|
||||||
|
return await result.fold(
|
||||||
|
(failure) async {
|
||||||
|
// 토큰 갱신 실패 시 세션 정리
|
||||||
|
await clearSession();
|
||||||
|
_authStateController.add(false);
|
||||||
|
return Left(failure);
|
||||||
|
},
|
||||||
|
(tokenResponse) async {
|
||||||
|
// 새 토큰 저장
|
||||||
|
await _saveTokens(
|
||||||
|
tokenResponse.accessToken,
|
||||||
|
tokenResponse.refreshToken,
|
||||||
|
tokenResponse.expiresIn,
|
||||||
|
);
|
||||||
|
return Right(tokenResponse);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return Left(ServerFailure(message: '토큰 갱신 중 오류가 발생했습니다.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> isLoggedIn() async {
|
||||||
|
try {
|
||||||
|
final accessToken = await getAccessToken();
|
||||||
|
if (accessToken == null) return false;
|
||||||
|
|
||||||
|
// 토큰 만료 확인
|
||||||
|
final expiryStr = await _secureStorage.read(key: _tokenExpiryKey);
|
||||||
|
if (expiryStr != null) {
|
||||||
|
final expiry = DateTime.parse(expiryStr);
|
||||||
|
if (DateTime.now().isAfter(expiry)) {
|
||||||
|
// 토큰이 만료되었으면 갱신 시도
|
||||||
|
final refreshResult = await refreshToken();
|
||||||
|
return refreshResult.isRight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<AuthUser?> getCurrentUser() async {
|
||||||
|
try {
|
||||||
|
final userStr = await _secureStorage.read(key: _userKey);
|
||||||
|
if (userStr == null) return null;
|
||||||
|
|
||||||
|
final userJson = jsonDecode(userStr);
|
||||||
|
return AuthUser.fromJson(userJson);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String?> getAccessToken() async {
|
||||||
|
try {
|
||||||
|
return await _secureStorage.read(key: _accessTokenKey);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String?> getRefreshToken() async {
|
||||||
|
try {
|
||||||
|
return await _secureStorage.read(key: _refreshTokenKey);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> clearSession() async {
|
||||||
|
try {
|
||||||
|
await _secureStorage.delete(key: _accessTokenKey);
|
||||||
|
await _secureStorage.delete(key: _refreshTokenKey);
|
||||||
|
await _secureStorage.delete(key: _userKey);
|
||||||
|
await _secureStorage.delete(key: _tokenExpiryKey);
|
||||||
|
} catch (e) {
|
||||||
|
// 에러가 발생해도 계속 진행
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<bool> get authStateChanges => _authStateController.stream;
|
||||||
|
|
||||||
|
Future<void> _saveTokens(
|
||||||
|
String accessToken,
|
||||||
|
String refreshToken,
|
||||||
|
int expiresIn,
|
||||||
|
) async {
|
||||||
|
await _secureStorage.write(key: _accessTokenKey, value: accessToken);
|
||||||
|
await _secureStorage.write(key: _refreshTokenKey, value: refreshToken);
|
||||||
|
|
||||||
|
// 토큰 만료 시간 저장 (현재 시간 + expiresIn 초)
|
||||||
|
final expiry = DateTime.now().add(Duration(seconds: expiresIn));
|
||||||
|
await _secureStorage.write(
|
||||||
|
key: _tokenExpiryKey,
|
||||||
|
value: expiry.toIso8601String(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _saveUser(AuthUser user) async {
|
||||||
|
final userJson = jsonEncode(user.toJson());
|
||||||
|
await _secureStorage.write(key: _userKey, value: userJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
_authStateController.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
16
pubspec.lock
16
pubspec.lock
@@ -346,6 +346,22 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
freezed:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: freezed
|
||||||
|
sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.7"
|
||||||
|
freezed_annotation:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: freezed_annotation
|
||||||
|
sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.4"
|
||||||
frontend_server_client:
|
frontend_server_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ dependencies:
|
|||||||
|
|
||||||
# JSON 처리
|
# JSON 처리
|
||||||
json_annotation: ^4.8.1
|
json_annotation: ^4.8.1
|
||||||
|
freezed_annotation: ^2.4.1
|
||||||
|
|
||||||
# 환경 설정
|
# 환경 설정
|
||||||
flutter_dotenv: ^5.1.0
|
flutter_dotenv: ^5.1.0
|
||||||
@@ -51,6 +52,7 @@ dev_dependencies:
|
|||||||
build_runner: ^2.4.8
|
build_runner: ^2.4.8
|
||||||
json_serializable: ^6.7.1
|
json_serializable: ^6.7.1
|
||||||
injectable_generator: ^2.4.1
|
injectable_generator: ^2.4.1
|
||||||
|
freezed: ^2.4.6
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|||||||
Reference in New Issue
Block a user