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/tokenspull/90/head
parent
8d6cbfdfc9
commit
31be961dd0
|
@ -5,9 +5,12 @@ import 'dart:io';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.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/auto_upgrade_settings.dart';
|
||||||
import 'package:selfprivacy/logic/models/backblaze_bucket.dart';
|
import 'package:selfprivacy/logic/models/backblaze_bucket.dart';
|
||||||
import 'package:selfprivacy/logic/models/backup.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/timezone_settings.dart';
|
||||||
import 'package:selfprivacy/logic/models/user.dart';
|
import 'package:selfprivacy/logic/models/user.dart';
|
||||||
|
|
||||||
|
@ -431,6 +434,244 @@ class ServerApi extends ApiMap {
|
||||||
.split(')')[0]
|
.split(')')[0]
|
||||||
.replaceAll('"', '');
|
.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 {
|
extension UrlServerExt on ServiceTypes {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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,
|
||||||
|
);
|
|
@ -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);
|
||||||
|
}
|
|
@ -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,
|
||||||
|
);
|
|
@ -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);
|
||||||
|
}
|
|
@ -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?,
|
||||||
|
);
|
Loading…
Reference in New Issue