inventory / sebn_inventory_app / lib / domain / auth / entities.dart
entities.dart
Raw
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,
      );
}