Implement server endpoints for tokens

get /auth/recovery_token
post /auth/recovery_token
post /auth/recovery_token/use
post /auth/new_device/authorize
post /auth/new_device
delete /auth/new_device
get /auth/tokens
post /auth/tokens
delete /auth/tokens
pull/90/head
NaiJi ✨ 2022-05-10 02:16:36 +03:00
parent 8d6cbfdfc9
commit 31be961dd0
7 changed files with 345 additions and 0 deletions

View File

@ -5,9 +5,12 @@ import 'dart:io';
import 'package:dio/dio.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
import 'package:selfprivacy/logic/models/api_token.dart';
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
import 'package:selfprivacy/logic/models/backblaze_bucket.dart';
import 'package:selfprivacy/logic/models/backup.dart';
import 'package:selfprivacy/logic/models/recovery_token_status.dart';
import 'package:selfprivacy/logic/models/device_token.dart';
import 'package:selfprivacy/logic/models/timezone_settings.dart';
import 'package:selfprivacy/logic/models/user.dart';
@ -431,6 +434,244 @@ class ServerApi extends ApiMap {
.split(')')[0]
.replaceAll('"', '');
}
Future<ApiResponse<RecoveryTokenStatus>> getRecoveryTokenStatus() async {
var client = await getClient();
Response response = await client.get(
'/auth/recovery_token',
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(
statusCode: response.statusCode!,
data: response.data != null
? response.data.fromJson(response.data)
: null);
}
return ApiResponse(
statusCode: HttpStatus.internalServerError,
data: RecoveryTokenStatus(exists: false, valid: false));
}
Future<ApiResponse<String>> generateRecoveryToken(
DateTime expiration, int uses) async {
var client = await getClient();
Response response = await client.post(
'/auth/recovery_token',
data: {
'expiration': expiration.toIso8601String(),
'uses': uses,
},
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(
statusCode: response.statusCode!,
data: response.data != null ? response.data["token"] : '');
}
return ApiResponse(statusCode: HttpStatus.internalServerError, data: '');
}
Future<ApiResponse<String>> useRecoveryToken(DeviceToken token) async {
var client = await getClient();
Response response = await client.post(
'/auth/recovery_token/use',
data: {
'token': token.token,
'device': token.device,
},
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(
statusCode: response.statusCode!,
data: response.data != null ? response.data["token"] : '');
}
return ApiResponse(statusCode: HttpStatus.internalServerError, data: '');
}
Future<ApiResponse<String>> authorizeDevice(DeviceToken token) async {
var client = await getClient();
Response response = await client.post(
'/auth/new_device/authorize',
data: {
'token': token.token,
'device': token.device,
},
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(
statusCode: response.statusCode!,
data: response.data != null ? response.data : '');
}
return ApiResponse(statusCode: HttpStatus.internalServerError, data: '');
}
Future<ApiResponse<String>> createDeviceToken() async {
var client = await getClient();
Response response = await client.post(
'/auth/new_device',
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(
statusCode: response.statusCode!,
data: response.data != null ? response.data["token"] : '');
}
return ApiResponse(statusCode: HttpStatus.internalServerError, data: '');
}
Future<ApiResponse<String>> deleteDeviceToken() async {
var client = await getClient();
Response response = await client.delete(
'/auth/new_device',
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(
statusCode: response.statusCode!,
data: response.data != null ? response.data : '');
}
return ApiResponse(statusCode: HttpStatus.internalServerError, data: '');
}
Future<ApiResponse<List<ApiToken>>> getApiTokens() async {
var client = await getClient();
Response response = await client.get(
'/auth/tokens',
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(
statusCode: response.statusCode!,
data: (response.data != null)
? response.data
.map<ApiToken>((e) => ApiToken.fromJson(e))
.toList()
: []);
}
return ApiResponse(statusCode: HttpStatus.internalServerError, data: []);
}
Future<ApiResponse<String>> refreshCurrentApiToken() async {
var client = await getClient();
Response response = await client.post(
'/auth/tokens',
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(
statusCode: response.statusCode!,
data: (response.data != null) ? response.data["token"] : '');
}
return ApiResponse(statusCode: HttpStatus.internalServerError, data: '');
}
Future<ApiResponse<void>> deleteApiToken(String device) async {
var client = await getClient();
Response response = await client.delete(
'/auth/tokens',
data: {
'device': device,
},
options: Options(
contentType: 'application/json',
receiveDataWhenStatusError: true,
followRedirects: false,
validateStatus: (status) {
return (status != null) &&
(status < HttpStatus.internalServerError);
}),
);
client.close();
if (response.statusCode != null) {
return ApiResponse(statusCode: response.statusCode!, data: null);
}
return ApiResponse(statusCode: HttpStatus.internalServerError, data: null);
}
}
extension UrlServerExt on ServiceTypes {

View File

@ -0,0 +1,20 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:json_annotation/json_annotation.dart';
part 'api_token.g.dart';
@JsonSerializable()
class ApiToken {
ApiToken({
required this.name,
required this.date,
required this.is_caller,
});
final String name;
final DateTime date;
final bool is_caller;
factory ApiToken.fromJson(Map<String, dynamic> json) =>
_$ApiTokenFromJson(json);
}

View File

@ -0,0 +1,13 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'api_token.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ApiToken _$ApiTokenFromJson(Map<String, dynamic> json) => ApiToken(
name: json['name'] as String,
date: DateTime.parse(json['date'] as String),
is_caller: json['is_caller'] as bool,
);

View File

@ -0,0 +1,17 @@
import 'package:json_annotation/json_annotation.dart';
part 'device_token.g.dart';
@JsonSerializable()
class DeviceToken {
DeviceToken({
required this.device,
required this.token,
});
final String device;
final String token;
factory DeviceToken.fromJson(Map<String, dynamic> json) =>
_$DeviceTokenFromJson(json);
}

View File

@ -0,0 +1,12 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'device_token.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DeviceToken _$DeviceTokenFromJson(Map<String, dynamic> json) => DeviceToken(
device: json['device'] as String,
token: json['token'] as String,
);

View File

@ -0,0 +1,23 @@
import 'package:json_annotation/json_annotation.dart';
part 'recovery_token_status.g.dart';
@JsonSerializable()
class RecoveryTokenStatus {
RecoveryTokenStatus({
required this.exists,
required this.valid,
this.date,
this.expiration,
this.uses_left,
});
final bool exists;
final DateTime? date;
final DateTime? expiration;
final int? uses_left;
final bool valid;
factory RecoveryTokenStatus.fromJson(Map<String, dynamic> json) =>
_$RecoveryTokenStatusFromJson(json);
}

View File

@ -0,0 +1,19 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'recovery_token_status.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
RecoveryTokenStatus _$RecoveryTokenStatusFromJson(Map<String, dynamic> json) =>
RecoveryTokenStatus(
exists: json['exists'] as bool,
valid: json['valid'] as bool,
date:
json['date'] == null ? null : DateTime.parse(json['date'] as String),
expiration: json['expiration'] == null
? null
: DateTime.parse(json['expiration'] as String),
uses_left: json['uses_left'] as int?,
);