implemented auth repository and service in dart (JWT)
This commit is contained in:
parent
6cf055db22
commit
05fdefc3e2
@ -0,0 +1,81 @@
|
|||||||
|
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||||
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
|
import 'package:backend_dart/domain/repository/auth_repository.dart';
|
||||||
|
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
|
||||||
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
|
class InMemoryAuthRepositoryImpl implements AuthRepository {
|
||||||
|
final String secretKey;
|
||||||
|
final Map<String, String> sessionCache = {};
|
||||||
|
final Duration tokenExpiry;
|
||||||
|
|
||||||
|
InMemoryAuthRepositoryImpl({
|
||||||
|
required this.secretKey,
|
||||||
|
this.tokenExpiry = const Duration(hours: 24),
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
TaskEither<IError, String> generateToken(String userId) {
|
||||||
|
return TaskEither.tryCatch(
|
||||||
|
() async {
|
||||||
|
final jwt = JWT({
|
||||||
|
'userId': userId,
|
||||||
|
'exp': DateTime.now().add(tokenExpiry).millisecondsSinceEpoch,
|
||||||
|
});
|
||||||
|
final token = jwt.sign(SecretKey(secretKey));
|
||||||
|
|
||||||
|
// Add to cache
|
||||||
|
sessionCache[token] = userId;
|
||||||
|
|
||||||
|
return token;
|
||||||
|
},
|
||||||
|
(error, _) =>
|
||||||
|
AppError.authenticationError(message: 'Failed to generate token'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
TaskEither<IError, String> validateToken(String token) {
|
||||||
|
return TaskEither.tryCatch(
|
||||||
|
() async {
|
||||||
|
final jwt = JWT.verify(token, SecretKey(secretKey));
|
||||||
|
|
||||||
|
// Extract userId
|
||||||
|
final userId = jwt.payload['userId'] as String?;
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
throw AppError.authenticationError(
|
||||||
|
message: 'Invalid token payload: userId not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the token exists in the cache
|
||||||
|
if (!sessionCache.containsKey(token)) {
|
||||||
|
throw AppError.authenticationError(
|
||||||
|
message: 'Token not found in cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
return userId;
|
||||||
|
},
|
||||||
|
(error, _) => error is AppError
|
||||||
|
? error
|
||||||
|
: AppError.authenticationError(message: 'Failed to validate token'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
TaskEither<IError, void> revokeToken(String token) {
|
||||||
|
return TaskEither.tryCatch(
|
||||||
|
() async {
|
||||||
|
if (sessionCache.containsKey(token)) {
|
||||||
|
sessionCache.remove(token);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
throw AppError.authenticationError(message: 'Token not found');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error, _) => error is AppError
|
||||||
|
? error
|
||||||
|
: AppError.authenticationError(message: 'Failed to revoke token'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/domain/data/database.dart';
|
import 'package:backend_dart/domain/data/database.dart';
|
||||||
import 'package:backend_dart/domain/entities/project.dart';
|
import 'package:backend_dart/domain/entities/project.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/domain/repository/project_repository.dart';
|
import 'package:backend_dart/domain/repository/project_repository.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/domain/data/database.dart';
|
import 'package:backend_dart/domain/data/database.dart';
|
||||||
import 'package:backend_dart/domain/entities/project_task.dart';
|
import 'package:backend_dart/domain/entities/project_task.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/domain/repository/project_task_repository.dart';
|
import 'package:backend_dart/domain/repository/project_task_repository.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import 'package:backend_dart/application/repository/in_memory_auth_repository_impl.dart';
|
||||||
import 'package:backend_dart/application/repository/project_repository_impl.dart';
|
import 'package:backend_dart/application/repository/project_repository_impl.dart';
|
||||||
import 'package:backend_dart/application/repository/project_task_repository_impl.dart';
|
import 'package:backend_dart/application/repository/project_task_repository_impl.dart';
|
||||||
import 'package:backend_dart/application/repository/time_entry_repository_impl.dart';
|
import 'package:backend_dart/application/repository/time_entry_repository_impl.dart';
|
||||||
import 'package:backend_dart/application/repository/user_repository_impl.dart';
|
import 'package:backend_dart/application/repository/user_repository_impl.dart';
|
||||||
|
import 'package:backend_dart/domain/repository/auth_repository.dart';
|
||||||
import 'package:backend_dart/domain/repository/project_repository.dart';
|
import 'package:backend_dart/domain/repository/project_repository.dart';
|
||||||
import 'package:backend_dart/domain/repository/project_task_repository.dart';
|
import 'package:backend_dart/domain/repository/project_task_repository.dart';
|
||||||
import 'package:backend_dart/domain/repository/time_entry_repository.dart';
|
import 'package:backend_dart/domain/repository/time_entry_repository.dart';
|
||||||
@ -28,3 +30,7 @@ final timeEntryProvider = Provider<TimeEntryRepository>((ref) {
|
|||||||
final database = ref.read(databaseProvider);
|
final database = ref.read(databaseProvider);
|
||||||
return TimeEntryRepositoryImpl(database);
|
return TimeEntryRepositoryImpl(database);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final authProvider = Provider<AuthRepository>((ref) {
|
||||||
|
return InMemoryAuthRepositoryImpl(secretKey: "Secret");
|
||||||
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/domain/data/database.dart';
|
import 'package:backend_dart/domain/data/database.dart';
|
||||||
import 'package:backend_dart/domain/entities/time_entry.dart';
|
import 'package:backend_dart/domain/entities/time_entry.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/domain/repository/time_entry_repository.dart';
|
import 'package:backend_dart/domain/repository/time_entry_repository.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/domain/entities/user.dart';
|
import 'package:backend_dart/domain/entities/user.dart';
|
||||||
import 'package:backend_dart/domain/data/database.dart';
|
import 'package:backend_dart/domain/data/database.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/domain/repository/user_repository.dart';
|
import 'package:backend_dart/domain/repository/user_repository.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
|
77
backend-dart/lib/application/service/auth_service.dart
Normal file
77
backend-dart/lib/application/service/auth_service.dart
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'package:backend_dart/application/service/dto/auth_dto.dart';
|
||||||
|
import 'package:backend_dart/common/request_helper.dart';
|
||||||
|
import 'package:backend_dart/common/response_helpers.dart';
|
||||||
|
import 'package:backend_dart/common/secure_hash.dart';
|
||||||
|
import 'package:backend_dart/common/validation.dart';
|
||||||
|
import 'package:backend_dart/domain/entities/user.dart';
|
||||||
|
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||||
|
import 'package:backend_dart/domain/repository/auth_repository.dart';
|
||||||
|
import 'package:backend_dart/domain/repository/user_repository.dart';
|
||||||
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
import 'package:shelf/shelf.dart';
|
||||||
|
import 'package:shelf_router/shelf_router.dart';
|
||||||
|
|
||||||
|
part 'auth_service.g.dart';
|
||||||
|
|
||||||
|
class AuthService {
|
||||||
|
final AuthRepository authRepository;
|
||||||
|
final UserRepository users;
|
||||||
|
|
||||||
|
AuthService(this.authRepository, this.users);
|
||||||
|
|
||||||
|
/// Route to generate a token
|
||||||
|
@Route.post('/login')
|
||||||
|
Future<Response> generateToken(Request request) async {
|
||||||
|
return requestToJson(request)
|
||||||
|
.flatMap(validateJsonKeys(['email', 'password']))
|
||||||
|
.flatMap((json) => decodeJson(json, LoginRequestDTO.fromJson))
|
||||||
|
.flatMap<User>(
|
||||||
|
(loginRequest) => users.findByEmail(loginRequest.email).flatMap(
|
||||||
|
(user) => user.passwordHash ==
|
||||||
|
generateSecureHash(loginRequest.password)
|
||||||
|
? TaskEither.right(user)
|
||||||
|
: TaskEither.left(
|
||||||
|
AppError.authenticationError(
|
||||||
|
message: 'Invalid email or password'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.flatMap((user) => authRepository.generateToken(user.id).map((token) =>
|
||||||
|
TokenResponseDTO(token: token, userId: user.id).toJson()))
|
||||||
|
.map(jsonEncode)
|
||||||
|
.toResponse()
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Route to validate a token
|
||||||
|
@Route.post('/validate')
|
||||||
|
Future<Response> validateToken(Request request) async {
|
||||||
|
return requestToJson(request)
|
||||||
|
.flatMap(validateJsonKeys(['token']))
|
||||||
|
.flatMap((json) => decodeJson(json, TokenRequestDTO.fromJson))
|
||||||
|
.map((tokenRequest) => tokenRequest.token)
|
||||||
|
.flatMap((token) => authRepository.validateToken(token).map((userId) =>
|
||||||
|
TokenResponseDTO(token: token, userId: userId).toJson()))
|
||||||
|
.map(jsonEncode)
|
||||||
|
.toResponse()
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Route to revoke a token
|
||||||
|
@Route.post('/revoke')
|
||||||
|
Future<Response> revokeToken(Request request) async {
|
||||||
|
return requestToJson(request)
|
||||||
|
.flatMap(validateJsonKeys(['token']))
|
||||||
|
.flatMap((json) => decodeJson(json, TokenRequestDTO.fromJson))
|
||||||
|
.map((tokenRequest) => tokenRequest.token)
|
||||||
|
.flatMap(authRepository.revokeToken)
|
||||||
|
.map((_) => {'message': 'Token revoked successfully'})
|
||||||
|
.map(jsonEncode)
|
||||||
|
.toResponse()
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Router for the AuthService
|
||||||
|
Router get router => _$AuthServiceRouter(this);
|
||||||
|
}
|
27
backend-dart/lib/application/service/auth_service.g.dart
Normal file
27
backend-dart/lib/application/service/auth_service.g.dart
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'auth_service.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// ShelfRouterGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Router _$AuthServiceRouter(AuthService service) {
|
||||||
|
final router = Router();
|
||||||
|
router.add(
|
||||||
|
'POST',
|
||||||
|
r'/login',
|
||||||
|
service.generateToken,
|
||||||
|
);
|
||||||
|
router.add(
|
||||||
|
'POST',
|
||||||
|
r'/validate',
|
||||||
|
service.validateToken,
|
||||||
|
);
|
||||||
|
router.add(
|
||||||
|
'POST',
|
||||||
|
r'/revoke',
|
||||||
|
service.revokeToken,
|
||||||
|
);
|
||||||
|
return router;
|
||||||
|
}
|
42
backend-dart/lib/application/service/dto/auth_dto.dart
Normal file
42
backend-dart/lib/application/service/dto/auth_dto.dart
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'auth_dto.freezed.dart';
|
||||||
|
part 'auth_dto.g.dart';
|
||||||
|
|
||||||
|
/// TokenResponseDTO represents the response for a token generation or validation.
|
||||||
|
@freezed
|
||||||
|
class TokenResponseDTO with _$TokenResponseDTO {
|
||||||
|
const factory TokenResponseDTO({
|
||||||
|
required String token,
|
||||||
|
required String userId,
|
||||||
|
}) = _TokenResponseDTO;
|
||||||
|
|
||||||
|
/// JSON serialization
|
||||||
|
factory TokenResponseDTO.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$TokenResponseDTOFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TokenRequestDTO represents a request for operations involving tokens.
|
||||||
|
@freezed
|
||||||
|
class TokenRequestDTO with _$TokenRequestDTO {
|
||||||
|
const factory TokenRequestDTO({
|
||||||
|
required String token,
|
||||||
|
}) = _TokenRequestDTO;
|
||||||
|
|
||||||
|
/// JSON serialization
|
||||||
|
factory TokenRequestDTO.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$TokenRequestDTOFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// LoginRequestDTO represents the login request.
|
||||||
|
@freezed
|
||||||
|
class LoginRequestDTO with _$LoginRequestDTO {
|
||||||
|
const factory LoginRequestDTO({
|
||||||
|
required String email,
|
||||||
|
required String password,
|
||||||
|
}) = _LoginRequestDTO;
|
||||||
|
|
||||||
|
/// JSON serialization
|
||||||
|
factory LoginRequestDTO.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$LoginRequestDTOFromJson(json);
|
||||||
|
}
|
503
backend-dart/lib/application/service/dto/auth_dto.freezed.dart
Normal file
503
backend-dart/lib/application/service/dto/auth_dto.freezed.dart
Normal file
@ -0,0 +1,503 @@
|
|||||||
|
// 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_dto.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');
|
||||||
|
|
||||||
|
TokenResponseDTO _$TokenResponseDTOFromJson(Map<String, dynamic> json) {
|
||||||
|
return _TokenResponseDTO.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$TokenResponseDTO {
|
||||||
|
String get token => throw _privateConstructorUsedError;
|
||||||
|
String get userId => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this TokenResponseDTO to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponseDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$TokenResponseDTOCopyWith<TokenResponseDTO> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $TokenResponseDTOCopyWith<$Res> {
|
||||||
|
factory $TokenResponseDTOCopyWith(
|
||||||
|
TokenResponseDTO value, $Res Function(TokenResponseDTO) then) =
|
||||||
|
_$TokenResponseDTOCopyWithImpl<$Res, TokenResponseDTO>;
|
||||||
|
@useResult
|
||||||
|
$Res call({String token, String userId});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$TokenResponseDTOCopyWithImpl<$Res, $Val extends TokenResponseDTO>
|
||||||
|
implements $TokenResponseDTOCopyWith<$Res> {
|
||||||
|
_$TokenResponseDTOCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponseDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? token = null,
|
||||||
|
Object? userId = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
token: null == token
|
||||||
|
? _value.token
|
||||||
|
: token // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
userId: null == userId
|
||||||
|
? _value.userId
|
||||||
|
: userId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$TokenResponseDTOImplCopyWith<$Res>
|
||||||
|
implements $TokenResponseDTOCopyWith<$Res> {
|
||||||
|
factory _$$TokenResponseDTOImplCopyWith(_$TokenResponseDTOImpl value,
|
||||||
|
$Res Function(_$TokenResponseDTOImpl) then) =
|
||||||
|
__$$TokenResponseDTOImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({String token, String userId});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$TokenResponseDTOImplCopyWithImpl<$Res>
|
||||||
|
extends _$TokenResponseDTOCopyWithImpl<$Res, _$TokenResponseDTOImpl>
|
||||||
|
implements _$$TokenResponseDTOImplCopyWith<$Res> {
|
||||||
|
__$$TokenResponseDTOImplCopyWithImpl(_$TokenResponseDTOImpl _value,
|
||||||
|
$Res Function(_$TokenResponseDTOImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponseDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? token = null,
|
||||||
|
Object? userId = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$TokenResponseDTOImpl(
|
||||||
|
token: null == token
|
||||||
|
? _value.token
|
||||||
|
: token // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
userId: null == userId
|
||||||
|
? _value.userId
|
||||||
|
: userId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$TokenResponseDTOImpl implements _TokenResponseDTO {
|
||||||
|
const _$TokenResponseDTOImpl({required this.token, required this.userId});
|
||||||
|
|
||||||
|
factory _$TokenResponseDTOImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$TokenResponseDTOImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String token;
|
||||||
|
@override
|
||||||
|
final String userId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TokenResponseDTO(token: $token, userId: $userId)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$TokenResponseDTOImpl &&
|
||||||
|
(identical(other.token, token) || other.token == token) &&
|
||||||
|
(identical(other.userId, userId) || other.userId == userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, token, userId);
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponseDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$TokenResponseDTOImplCopyWith<_$TokenResponseDTOImpl> get copyWith =>
|
||||||
|
__$$TokenResponseDTOImplCopyWithImpl<_$TokenResponseDTOImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$TokenResponseDTOImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _TokenResponseDTO implements TokenResponseDTO {
|
||||||
|
const factory _TokenResponseDTO(
|
||||||
|
{required final String token,
|
||||||
|
required final String userId}) = _$TokenResponseDTOImpl;
|
||||||
|
|
||||||
|
factory _TokenResponseDTO.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$TokenResponseDTOImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get token;
|
||||||
|
@override
|
||||||
|
String get userId;
|
||||||
|
|
||||||
|
/// Create a copy of TokenResponseDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$TokenResponseDTOImplCopyWith<_$TokenResponseDTOImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenRequestDTO _$TokenRequestDTOFromJson(Map<String, dynamic> json) {
|
||||||
|
return _TokenRequestDTO.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$TokenRequestDTO {
|
||||||
|
String get token => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this TokenRequestDTO to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of TokenRequestDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$TokenRequestDTOCopyWith<TokenRequestDTO> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $TokenRequestDTOCopyWith<$Res> {
|
||||||
|
factory $TokenRequestDTOCopyWith(
|
||||||
|
TokenRequestDTO value, $Res Function(TokenRequestDTO) then) =
|
||||||
|
_$TokenRequestDTOCopyWithImpl<$Res, TokenRequestDTO>;
|
||||||
|
@useResult
|
||||||
|
$Res call({String token});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$TokenRequestDTOCopyWithImpl<$Res, $Val extends TokenRequestDTO>
|
||||||
|
implements $TokenRequestDTOCopyWith<$Res> {
|
||||||
|
_$TokenRequestDTOCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TokenRequestDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? token = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
token: null == token
|
||||||
|
? _value.token
|
||||||
|
: token // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$TokenRequestDTOImplCopyWith<$Res>
|
||||||
|
implements $TokenRequestDTOCopyWith<$Res> {
|
||||||
|
factory _$$TokenRequestDTOImplCopyWith(_$TokenRequestDTOImpl value,
|
||||||
|
$Res Function(_$TokenRequestDTOImpl) then) =
|
||||||
|
__$$TokenRequestDTOImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({String token});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$TokenRequestDTOImplCopyWithImpl<$Res>
|
||||||
|
extends _$TokenRequestDTOCopyWithImpl<$Res, _$TokenRequestDTOImpl>
|
||||||
|
implements _$$TokenRequestDTOImplCopyWith<$Res> {
|
||||||
|
__$$TokenRequestDTOImplCopyWithImpl(
|
||||||
|
_$TokenRequestDTOImpl _value, $Res Function(_$TokenRequestDTOImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of TokenRequestDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? token = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$TokenRequestDTOImpl(
|
||||||
|
token: null == token
|
||||||
|
? _value.token
|
||||||
|
: token // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$TokenRequestDTOImpl implements _TokenRequestDTO {
|
||||||
|
const _$TokenRequestDTOImpl({required this.token});
|
||||||
|
|
||||||
|
factory _$TokenRequestDTOImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$TokenRequestDTOImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String token;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TokenRequestDTO(token: $token)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$TokenRequestDTOImpl &&
|
||||||
|
(identical(other.token, token) || other.token == token));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, token);
|
||||||
|
|
||||||
|
/// Create a copy of TokenRequestDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$TokenRequestDTOImplCopyWith<_$TokenRequestDTOImpl> get copyWith =>
|
||||||
|
__$$TokenRequestDTOImplCopyWithImpl<_$TokenRequestDTOImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$TokenRequestDTOImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _TokenRequestDTO implements TokenRequestDTO {
|
||||||
|
const factory _TokenRequestDTO({required final String token}) =
|
||||||
|
_$TokenRequestDTOImpl;
|
||||||
|
|
||||||
|
factory _TokenRequestDTO.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$TokenRequestDTOImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get token;
|
||||||
|
|
||||||
|
/// Create a copy of TokenRequestDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$TokenRequestDTOImplCopyWith<_$TokenRequestDTOImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginRequestDTO _$LoginRequestDTOFromJson(Map<String, dynamic> json) {
|
||||||
|
return _LoginRequestDTO.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$LoginRequestDTO {
|
||||||
|
String get email => throw _privateConstructorUsedError;
|
||||||
|
String get password => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this LoginRequestDTO to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequestDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$LoginRequestDTOCopyWith<LoginRequestDTO> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $LoginRequestDTOCopyWith<$Res> {
|
||||||
|
factory $LoginRequestDTOCopyWith(
|
||||||
|
LoginRequestDTO value, $Res Function(LoginRequestDTO) then) =
|
||||||
|
_$LoginRequestDTOCopyWithImpl<$Res, LoginRequestDTO>;
|
||||||
|
@useResult
|
||||||
|
$Res call({String email, String password});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$LoginRequestDTOCopyWithImpl<$Res, $Val extends LoginRequestDTO>
|
||||||
|
implements $LoginRequestDTOCopyWith<$Res> {
|
||||||
|
_$LoginRequestDTOCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequestDTO
|
||||||
|
/// 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 _$$LoginRequestDTOImplCopyWith<$Res>
|
||||||
|
implements $LoginRequestDTOCopyWith<$Res> {
|
||||||
|
factory _$$LoginRequestDTOImplCopyWith(_$LoginRequestDTOImpl value,
|
||||||
|
$Res Function(_$LoginRequestDTOImpl) then) =
|
||||||
|
__$$LoginRequestDTOImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({String email, String password});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LoginRequestDTOImplCopyWithImpl<$Res>
|
||||||
|
extends _$LoginRequestDTOCopyWithImpl<$Res, _$LoginRequestDTOImpl>
|
||||||
|
implements _$$LoginRequestDTOImplCopyWith<$Res> {
|
||||||
|
__$$LoginRequestDTOImplCopyWithImpl(
|
||||||
|
_$LoginRequestDTOImpl _value, $Res Function(_$LoginRequestDTOImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequestDTO
|
||||||
|
/// 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(_$LoginRequestDTOImpl(
|
||||||
|
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 _$LoginRequestDTOImpl implements _LoginRequestDTO {
|
||||||
|
const _$LoginRequestDTOImpl({required this.email, required this.password});
|
||||||
|
|
||||||
|
factory _$LoginRequestDTOImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$LoginRequestDTOImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String email;
|
||||||
|
@override
|
||||||
|
final String password;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LoginRequestDTO(email: $email, password: $password)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$LoginRequestDTOImpl &&
|
||||||
|
(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 LoginRequestDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$LoginRequestDTOImplCopyWith<_$LoginRequestDTOImpl> get copyWith =>
|
||||||
|
__$$LoginRequestDTOImplCopyWithImpl<_$LoginRequestDTOImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$LoginRequestDTOImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _LoginRequestDTO implements LoginRequestDTO {
|
||||||
|
const factory _LoginRequestDTO(
|
||||||
|
{required final String email,
|
||||||
|
required final String password}) = _$LoginRequestDTOImpl;
|
||||||
|
|
||||||
|
factory _LoginRequestDTO.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$LoginRequestDTOImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get email;
|
||||||
|
@override
|
||||||
|
String get password;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequestDTO
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$LoginRequestDTOImplCopyWith<_$LoginRequestDTOImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
47
backend-dart/lib/application/service/dto/auth_dto.g.dart
Normal file
47
backend-dart/lib/application/service/dto/auth_dto.g.dart
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'auth_dto.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$TokenResponseDTOImpl _$$TokenResponseDTOImplFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$TokenResponseDTOImpl(
|
||||||
|
token: json['token'] as String,
|
||||||
|
userId: json['userId'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$TokenResponseDTOImplToJson(
|
||||||
|
_$TokenResponseDTOImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'token': instance.token,
|
||||||
|
'userId': instance.userId,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$TokenRequestDTOImpl _$$TokenRequestDTOImplFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$TokenRequestDTOImpl(
|
||||||
|
token: json['token'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$TokenRequestDTOImplToJson(
|
||||||
|
_$TokenRequestDTOImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'token': instance.token,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$LoginRequestDTOImpl _$$LoginRequestDTOImplFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$LoginRequestDTOImpl(
|
||||||
|
email: json['email'] as String,
|
||||||
|
password: json['password'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$LoginRequestDTOImplToJson(
|
||||||
|
_$LoginRequestDTOImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'email': instance.email,
|
||||||
|
'password': instance.password,
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/application/service/dto/project_dto.dart';
|
import 'package:backend_dart/application/service/dto/project_dto.dart';
|
||||||
import 'package:backend_dart/domain/entities/project.dart';
|
import 'package:backend_dart/domain/entities/project.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
class ProjectDtoMapper {
|
class ProjectDtoMapper {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/application/service/dto/project_task_dto.dart';
|
import 'package:backend_dart/application/service/dto/project_task_dto.dart';
|
||||||
import 'package:backend_dart/domain/entities/project_task.dart';
|
import 'package:backend_dart/domain/entities/project_task.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
class ProjectTaskDtoMapper {
|
class ProjectTaskDtoMapper {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/application/service/dto/time_entry_dto.dart';
|
import 'package:backend_dart/application/service/dto/time_entry_dto.dart';
|
||||||
import 'package:backend_dart/domain/entities/time_entry.dart';
|
import 'package:backend_dart/domain/entities/time_entry.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
class TimeEntryDtoMapper {
|
class TimeEntryDtoMapper {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/application/service/dto/user_dto.dart';
|
import 'package:backend_dart/application/service/dto/user_dto.dart';
|
||||||
import 'package:backend_dart/domain/entities/user.dart';
|
import 'package:backend_dart/domain/entities/user.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
class UserDtoMapper {
|
class UserDtoMapper {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:backend_dart/application/repository/provider.dart';
|
import 'package:backend_dart/application/repository/provider.dart';
|
||||||
|
import 'package:backend_dart/application/service/auth_service.dart';
|
||||||
import 'package:backend_dart/application/service/project_service.dart';
|
import 'package:backend_dart/application/service/project_service.dart';
|
||||||
import 'package:backend_dart/application/service/project_task_service.dart';
|
import 'package:backend_dart/application/service/project_task_service.dart';
|
||||||
import 'package:backend_dart/application/service/time_entry_service.dart';
|
import 'package:backend_dart/application/service/time_entry_service.dart';
|
||||||
@ -24,3 +25,9 @@ final timeEntryServiceProvider = Provider<TimeEntryService>((ref) {
|
|||||||
final database = ref.read(timeEntryProvider);
|
final database = ref.read(timeEntryProvider);
|
||||||
return TimeEntryService(database);
|
return TimeEntryService(database);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final authServiceProvider = Provider<AuthService>((ref) {
|
||||||
|
final authRepository = ref.read(authProvider);
|
||||||
|
final users = ref.read(userRepoProvider);
|
||||||
|
return AuthService(authRepository, users);
|
||||||
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
TaskEither<IError, T> Function(T?) errorOnNull<T>(IError error) {
|
TaskEither<IError, T> Function(T?) errorOnNull<T>(IError error) {
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
|||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
|
|
||||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
import 'package:shelf/shelf.dart';
|
import 'package:shelf/shelf.dart';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:backend_dart/domain/errors/error_code.dart';
|
import 'package:backend_dart/domain/errors/error_code.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
import 'package:shelf/shelf.dart';
|
import 'package:shelf/shelf.dart';
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:backend_dart/domain/entities/project.dart';
|
import 'package:backend_dart/domain/entities/project.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
/// Interface for managing project data interactions.
|
/// Interface for managing project data interactions.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:backend_dart/domain/entities/project_task.dart';
|
import 'package:backend_dart/domain/entities/project_task.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
/// Interface for managing task data interactions.
|
/// Interface for managing task data interactions.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:backend_dart/domain/entities/time_entry.dart';
|
import 'package:backend_dart/domain/entities/time_entry.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
/// Interface for managing time entry data interactions.
|
/// Interface for managing time entry data interactions.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:backend_dart/domain/entities/user.dart';
|
import 'package:backend_dart/domain/entities/user.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
abstract class UserDataSource {
|
abstract class UserDataSource {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'error_code.dart';
|
import 'error_code.dart';
|
||||||
|
|
||||||
@ -48,4 +48,8 @@ class AppError with _$AppError implements IError {
|
|||||||
factory AppError.inputError({String? message}) {
|
factory AppError.inputError({String? message}) {
|
||||||
return AppError.fromErrorCode(ErrorCode.inputError, message: message);
|
return AppError.fromErrorCode(ErrorCode.inputError, message: message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
factory AppError.authenticationError({String? message}) {
|
||||||
|
return AppError.fromErrorCode(ErrorCode.authenticationError, message: message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ enum ErrorCode {
|
|||||||
validationError, // Eingabevalidierungsfehler
|
validationError, // Eingabevalidierungsfehler
|
||||||
unexpectedError, // Unerwarteter Fehler
|
unexpectedError, // Unerwarteter Fehler
|
||||||
authenticationError, // Authentifizierungsfehler
|
authenticationError, // Authentifizierungsfehler
|
||||||
|
authorizationError, // Autorisierungsfehler
|
||||||
permissionDenied, // Berechtigungsfehler
|
permissionDenied, // Berechtigungsfehler
|
||||||
notFound, // Ressource nicht gefunden
|
notFound, // Ressource nicht gefunden
|
||||||
exception, // Ausnahme
|
exception, // Ausnahme
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import 'package:backend_dart/domain/interface/error.dart';
|
|
||||||
import 'package:fpdart/fpdart.dart';
|
|
||||||
|
|
||||||
abstract class IMapper<U, V> {
|
|
||||||
/// Konvertiert von Typ U (Origin) zu Typ V (Target)
|
|
||||||
TaskEither<IError, V> to(U origin);
|
|
||||||
|
|
||||||
/// Konvertiert von Typ V (Target) zu Typ U (Origin)
|
|
||||||
TaskEither<IError, U> from(V target);
|
|
||||||
|
|
||||||
/// Konvertiert eine Liste von Typ U (Origin) zu einer Liste von Typ V (Target)
|
|
||||||
TaskEither<IError, List<V>> listTo(Iterable<U> origins);
|
|
||||||
|
|
||||||
/// Konvertiert eine Liste von Typ V (Target) zu einer Liste von Typ U (Origin)
|
|
||||||
TaskEither<IError, List<U>> listFrom(Iterable<V> targets);
|
|
||||||
}
|
|
8
backend-dart/lib/domain/repository/auth_repository.dart
Normal file
8
backend-dart/lib/domain/repository/auth_repository.dart
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
|
abstract class AuthRepository {
|
||||||
|
TaskEither<IError, String> generateToken(String userId);
|
||||||
|
TaskEither<IError, String> validateToken(String token);
|
||||||
|
TaskEither<IError, void> revokeToken(String token);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
import 'package:backend_dart/domain/entities/project.dart';
|
import 'package:backend_dart/domain/entities/project.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
|
|
||||||
abstract class ProjectRepository {
|
abstract class ProjectRepository {
|
||||||
/// Creates a new project.
|
/// Creates a new project.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
import 'package:backend_dart/domain/entities/project_task.dart';
|
import 'package:backend_dart/domain/entities/project_task.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
|
|
||||||
abstract class ProjectTaskRepository {
|
abstract class ProjectTaskRepository {
|
||||||
/// Creates a new project task.
|
/// Creates a new project task.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
import 'package:backend_dart/domain/entities/time_entry.dart';
|
import 'package:backend_dart/domain/entities/time_entry.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
|
|
||||||
abstract class TimeEntryRepository {
|
abstract class TimeEntryRepository {
|
||||||
/// Creates a new time entry.
|
/// Creates a new time entry.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:backend_dart/domain/entities/user.dart';
|
import 'package:backend_dart/domain/entities/user.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
|
||||||
abstract class UserRepository {
|
abstract class UserRepository {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/common/extensions.dart';
|
import 'package:backend_dart/common/extensions.dart';
|
||||||
import 'package:backend_dart/domain/entities/project.dart';
|
import 'package:backend_dart/domain/entities/project.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/common/extensions.dart';
|
import 'package:backend_dart/common/extensions.dart';
|
||||||
import 'package:backend_dart/domain/entities/project_task.dart';
|
import 'package:backend_dart/domain/entities/project_task.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:backend_dart/common/extensions.dart';
|
import 'package:backend_dart/common/extensions.dart';
|
||||||
import 'package:backend_dart/domain/entities/time_entry.dart';
|
import 'package:backend_dart/domain/entities/time_entry.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:backend_dart/common/extensions.dart';
|
import 'package:backend_dart/common/extensions.dart';
|
||||||
import 'package:backend_dart/common/secure_hash.dart';
|
import 'package:backend_dart/common/secure_hash.dart';
|
||||||
import 'package:backend_dart/domain/entities/user.dart';
|
import 'package:backend_dart/domain/entities/user.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
@ -2,7 +2,7 @@ import 'package:backend_dart/common/error_on_null.dart';
|
|||||||
import 'package:backend_dart/domain/data/project_data_source.dart';
|
import 'package:backend_dart/domain/data/project_data_source.dart';
|
||||||
import 'package:backend_dart/domain/entities/project.dart';
|
import 'package:backend_dart/domain/entities/project.dart';
|
||||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/client.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/client.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
||||||
|
@ -2,7 +2,7 @@ import 'package:backend_dart/common/error_on_null.dart';
|
|||||||
import 'package:backend_dart/domain/data/project_task_data_source.dart';
|
import 'package:backend_dart/domain/data/project_task_data_source.dart';
|
||||||
import 'package:backend_dart/domain/entities/project_task.dart';
|
import 'package:backend_dart/domain/entities/project_task.dart';
|
||||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/client.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/client.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
||||||
|
@ -2,7 +2,7 @@ import 'package:backend_dart/common/error_on_null.dart';
|
|||||||
import 'package:backend_dart/domain/data/time_entry_data_source.dart';
|
import 'package:backend_dart/domain/data/time_entry_data_source.dart';
|
||||||
import 'package:backend_dart/domain/entities/time_entry.dart';
|
import 'package:backend_dart/domain/entities/time_entry.dart';
|
||||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/client.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/client.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
||||||
|
@ -2,7 +2,7 @@ import 'package:backend_dart/common/error_on_null.dart';
|
|||||||
import 'package:backend_dart/domain/data/user_data_source.dart';
|
import 'package:backend_dart/domain/data/user_data_source.dart';
|
||||||
import 'package:backend_dart/domain/entities/user.dart';
|
import 'package:backend_dart/domain/entities/user.dart';
|
||||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||||
import 'package:backend_dart/domain/interface/error.dart';
|
import 'package:backend_dart/domain/errors/error.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/model.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
import 'package:backend_dart/infrastructure/persistence/db/prisma.dart';
|
||||||
import 'package:backend_dart/infrastructure/persistence/mapper/user_dbo_mapper.dart';
|
import 'package:backend_dart/infrastructure/persistence/mapper/user_dbo_mapper.dart';
|
||||||
|
@ -20,12 +20,14 @@ Router getRouter(ProviderContainer container) {
|
|||||||
final projectService = container.read(projectServiceProvider);
|
final projectService = container.read(projectServiceProvider);
|
||||||
final projectTaskService = container.read(projectTaskServiceProvider);
|
final projectTaskService = container.read(projectTaskServiceProvider);
|
||||||
final timeEntryService = container.read(timeEntryServiceProvider);
|
final timeEntryService = container.read(timeEntryServiceProvider);
|
||||||
|
final authService = container.read(authServiceProvider);
|
||||||
|
|
||||||
// UserService-Router
|
// UserService-Router
|
||||||
router.mount('/api/users/', userService.router.call);
|
router.mount('/api/users/', userService.router.call);
|
||||||
router.mount('/api/projects/', projectService.router.call);
|
router.mount('/api/projects/', projectService.router.call);
|
||||||
router.mount('/api/project-tasks/', projectTaskService.router.call);
|
router.mount('/api/project-tasks/', projectTaskService.router.call);
|
||||||
router.mount('/api/time-entries/', timeEntryService.router.call);
|
router.mount('/api/time-entries/', timeEntryService.router.call);
|
||||||
|
router.mount('/api/auth/', authService.router.call);
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,14 @@ packages:
|
|||||||
description: dart
|
description: dart
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.3.3"
|
version: "0.3.3"
|
||||||
|
adaptive_number:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: adaptive_number
|
||||||
|
sha256: "3a567544e9b5c9c803006f51140ad544aedc79604fd4f3f2c1380003f97c1d77"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -238,6 +246,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0+6.11.0"
|
version: "1.0.0+6.11.0"
|
||||||
|
dart_jsonwebtoken:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dart_jsonwebtoken
|
||||||
|
sha256: "866787dc17afaef46a9ea7dd33eefe60c6d82084b4a36d70e8e788d091cd04ef"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.14.2"
|
||||||
dart_style:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -254,6 +270,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.2"
|
||||||
|
ed25519_edwards:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: ed25519_edwards
|
||||||
|
sha256: "6ce0112d131327ec6d42beede1e5dfd526069b18ad45dcf654f15074ad9276cd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.1"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -478,6 +502,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
|
pointycastle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointycastle
|
||||||
|
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.9.1"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -22,6 +22,7 @@ dependencies:
|
|||||||
freezed_annotation: ^2.4.4
|
freezed_annotation: ^2.4.4
|
||||||
uuid: ^4.5.1
|
uuid: ^4.5.1
|
||||||
crypto: ^3.0.6
|
crypto: ^3.0.6
|
||||||
|
dart_jsonwebtoken: ^2.14.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^3.0.0
|
lints: ^3.0.0
|
||||||
|
@ -28,7 +28,7 @@ func main() {
|
|||||||
projectRepo := repository.NewProjectRepository(database.Projects())
|
projectRepo := repository.NewProjectRepository(database.Projects())
|
||||||
projectTaskRepo := repository.NewProjectTaskRepository(database.ProjectTasks())
|
projectTaskRepo := repository.NewProjectTaskRepository(database.ProjectTasks())
|
||||||
timeEntryRepo := repository.NewTimeEntryRepository(database.TimeEntries())
|
timeEntryRepo := repository.NewTimeEntryRepository(database.TimeEntries())
|
||||||
authRepo := repository.NewInMemoryAuthRepository("secret")
|
authRepo := repository.NewInMemoryAuthRepositoryImpl("secret")
|
||||||
|
|
||||||
// Initialize services
|
// Initialize services
|
||||||
userService := services.NewUserService(userRepo)
|
userService := services.NewUserService(userRepo)
|
||||||
|
@ -19,7 +19,7 @@ type InMemoryAuthRepository struct {
|
|||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInMemoryAuthRepository(secretKey string) repository.AuthRepository {
|
func NewInMemoryAuthRepositoryImpl(secretKey string) repository.AuthRepository {
|
||||||
return &InMemoryAuthRepository{
|
return &InMemoryAuthRepository{
|
||||||
secretKey: secretKey,
|
secretKey: secretKey,
|
||||||
sessionCache: make(map[string]string),
|
sessionCache: make(map[string]string),
|
Loading…
x
Reference in New Issue
Block a user