import 'dart:convert'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:sebn_inventory_app/infrastructure/repository/datasources/local_datasource.dart'; import 'value_objects.dart'; part 'entities.freezed.dart'; @freezed class LoggedUser with _$LoggedUser { const factory LoggedUser({ required JWT jwt, required Username name, required Password password, required int branchId, required int areaId, required String language, required int inventoryId, }) = _LoggedUser; const LoggedUser._(); factory LoggedUser.empty() => LoggedUser( name: Username('unknown.user'), password: Password(''), jwt: JWT.empty(), branchId: -1, areaId: -1, inventoryId: -1, language: 'uk_UA', ); factory LoggedUser.fromUser(User user) => LoggedUser( jwt: JWT.empty(), name: Username(user.name), password: Password(''), branchId: user.branchId, areaId: user.areaId, inventoryId: user.inventoryId, language: user.language, ); bool get isValid => name != Username('unknown.user'); } class JWT { final Token refresh; final Token access; const JWT({ required this.refresh, required this.access, }); factory JWT.fromString(String value) { final array = value.split(','); try { final refresh = Token(array[0]); final access = Token(array[1]); return JWT(refresh: refresh, access: access); } catch (e) { return JWT.empty(); } } factory JWT.empty() { return JWT(refresh: Token(''), access: Token('')); } bool isAccessExpired() { return _getExpiredDateFrom(access).isBefore(DateTime.now()); } Duration accessExpiration() { final diff = DateTime.now().difference(_getExpiredDateFrom(access)); return diff.isNegative ? diff : Duration.zero; } Duration refreshExpiration() { final diff = DateTime.now().difference(_getExpiredDateFrom(refresh)); return diff.isNegative ? diff : Duration.zero; } bool isRefreshExpired() { return _getExpiredDateFrom(refresh).isBefore(DateTime.now()); } DateTime _getExpiredDateFrom(Token token) { final j = json.decode(ascii.decode(base64.decode(base64.normalize(token.toString().split(".")[1])))); final exp = int.tryParse(j["exp"].toString()) ?? 0; return DateTime.fromMillisecondsSinceEpoch(exp * 1000); } @override String toString() { return '${refresh.value.getOrElse(() => '')},${access.value.getOrElse(() => '')}'; } } @freezed class Branch with _$Branch { const factory Branch({ required int id, required String name, required String description, }) = _Branch; factory Branch.empty() => const Branch( id: -1, name: '', description: '', ); } @freezed class Area with _$Area { const factory Area({ required int id, required String name, required String description, required int floor, required int branchId, }) = _Area; factory Area.empty() => const Area( id: -1, name: '', description: '', floor: -1, branchId: -1, ); }