Add recovery_key_cubit.dart

pull/90/head
Inex Code 2022-05-24 19:09:47 +03:00
parent 804e2750da
commit a096e7e732
5 changed files with 142 additions and 16 deletions

View File

@ -628,7 +628,7 @@ class ServerApi extends ApiMap {
.replaceAll('"', '');
}
Future<ApiResponse<RecoveryTokenStatus>> getRecoveryTokenStatus() async {
Future<ApiResponse<RecoveryKeyStatus>> getRecoveryTokenStatus() async {
Response response;
var client = await getClient();
@ -639,7 +639,7 @@ class ServerApi extends ApiMap {
return ApiResponse(
errorMessage: e.message,
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
data: RecoveryTokenStatus(exists: false, valid: false));
data: RecoveryKeyStatus(exists: false, valid: false));
} finally {
close(client);
}
@ -654,17 +654,23 @@ class ServerApi extends ApiMap {
}
Future<ApiResponse<String>> generateRecoveryToken(
DateTime expiration, int uses) async {
DateTime? expiration,
int? uses,
) async {
Response response;
var client = await getClient();
var data = {};
if (expiration != null) {
data['expiration'] = expiration.toIso8601String();
}
if (uses != null) {
data['uses'] = uses;
}
try {
response = await client.post(
'/auth/recovery_token',
data: {
'expiration': expiration.toIso8601String(),
'uses': uses,
},
data: data,
);
} on DioError catch (e) {
print(e.message);

View File

@ -0,0 +1,72 @@
import 'package:selfprivacy/logic/api_maps/server.dart';
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
part 'recovery_key_state.dart';
class RecoveryKeyCubit
extends ServerInstallationDependendCubit<RecoveryKeyState> {
RecoveryKeyCubit(ServerInstallationCubit serverInstallationCubit)
: super(serverInstallationCubit, RecoveryKeyState.initial());
final api = ServerApi();
@override
void load() async {
if (serverInstallationCubit.state is ServerInstallationFinished) {
final status = await _getRecoveryKeyStatus();
if (status == null) {
emit(state.copyWith(loadingStatus: LoadingStatus.error));
} else {
emit(state.copyWith(status: status, loadingStatus: LoadingStatus.good));
}
} else {
emit(state.copyWith(loadingStatus: LoadingStatus.uninitialized));
}
}
Future<RecoveryKeyStatus?> _getRecoveryKeyStatus() async {
final ApiResponse<RecoveryKeyStatus> response =
await api.getRecoveryTokenStatus();
if (response.isSuccess) {
return response.data;
} else {
return null;
}
}
Future<void> refresh() async {
emit(state.copyWith(loadingStatus: LoadingStatus.refreshing));
final status = await _getRecoveryKeyStatus();
if (status == null) {
emit(state.copyWith(loadingStatus: LoadingStatus.error));
} else {
emit(state.copyWith(status: status, loadingStatus: LoadingStatus.good));
}
}
Future<String> generateRecoveryKey({
DateTime? expirationDate,
int? numberOfUses,
}) async {
final ApiResponse<String> response =
await api.generateRecoveryToken(expirationDate, numberOfUses);
if (response.isSuccess) {
refresh();
return response.data;
} else {
throw GenerationError(response.errorMessage ?? 'Unknown error');
}
}
@override
void clear() {
emit(state.copyWith(loadingStatus: LoadingStatus.uninitialized));
}
}
class GenerationError extends Error {
final String message;
GenerationError(this.message);
}

View File

@ -0,0 +1,37 @@
part of 'recovery_key_cubit.dart';
enum LoadingStatus {
uninitialized,
refreshing,
good,
error,
}
class RecoveryKeyState extends ServerInstallationDependendState {
const RecoveryKeyState(this._status, this.loadingStatus);
RecoveryKeyState.initial()
: this(RecoveryKeyStatus(exists: false, valid: false), LoadingStatus.refreshing);
final RecoveryKeyStatus _status;
final LoadingStatus loadingStatus;
bool get exists => _status.exists;
bool get isValid => _status.valid;
DateTime? get generatedAt => _status.date;
DateTime? get expiresAt => _status.date;
int? get usesLeft => _status.usesLeft;
@override
List<Object> get props => [_status, loadingStatus];
RecoveryKeyState copyWith({
RecoveryKeyStatus? status,
LoadingStatus? loadingStatus,
}) {
return RecoveryKeyState(
status ?? this._status,
loadingStatus ?? this.loadingStatus,
);
}
}

View File

@ -1,23 +1,34 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'recovery_token_status.g.dart';
@JsonSerializable()
class RecoveryTokenStatus {
RecoveryTokenStatus({
class RecoveryKeyStatus extends Equatable {
RecoveryKeyStatus({
required this.exists,
required this.valid,
this.date,
this.expiration,
this.uses_left,
this.usesLeft,
});
final bool exists;
final DateTime? date;
final DateTime? expiration;
final int? uses_left;
@JsonKey(name: 'uses_left')
final int? usesLeft;
final bool valid;
factory RecoveryTokenStatus.fromJson(Map<String, dynamic> json) =>
_$RecoveryTokenStatusFromJson(json);
factory RecoveryKeyStatus.fromJson(Map<String, dynamic> json) =>
_$RecoveryKeyStatusFromJson(json);
@override
List<Object?> get props => [
exists,
date,
expiration,
usesLeft,
valid,
];
}

View File

@ -6,8 +6,8 @@ part of 'recovery_token_status.dart';
// JsonSerializableGenerator
// **************************************************************************
RecoveryTokenStatus _$RecoveryTokenStatusFromJson(Map<String, dynamic> json) =>
RecoveryTokenStatus(
RecoveryKeyStatus _$RecoveryKeyStatusFromJson(Map<String, dynamic> json) =>
RecoveryKeyStatus(
exists: json['exists'] as bool,
valid: json['valid'] as bool,
date:
@ -15,5 +15,5 @@ RecoveryTokenStatus _$RecoveryTokenStatusFromJson(Map<String, dynamic> json) =>
expiration: json['expiration'] == null
? null
: DateTime.parse(json['expiration'] as String),
uses_left: json['uses_left'] as int?,
usesLeft: json['uses_left'] as int?,
);