chore: Merge master into digital-ocean

routes-refactor
NaiJi ✨ 2022-11-02 18:45:36 +04:00
commit 8c053f50b0
30 changed files with 638 additions and 784 deletions

View File

@ -422,7 +422,8 @@
"create_ssh_key": "Create SSH key for {}", "create_ssh_key": "Create SSH key for {}",
"delete_ssh_key": "Delete SSH key for {}", "delete_ssh_key": "Delete SSH key for {}",
"server_jobs": "Jobs on the server", "server_jobs": "Jobs on the server",
"reset_user_password": "Reset password of user" "reset_user_password": "Reset password of user",
"generic_error": "Couldn't connect to the server!"
}, },
"validations": { "validations": {
"required": "Required", "required": "Required",

View File

@ -422,7 +422,8 @@
"create_ssh_key": "Создать SSH ключ для {}", "create_ssh_key": "Создать SSH ключ для {}",
"delete_ssh_key": "Удалить SSH ключ для {}", "delete_ssh_key": "Удалить SSH ключ для {}",
"server_jobs": "Задачи на сервере", "server_jobs": "Задачи на сервере",
"reset_user_password": "Сбросить пароль пользователя" "reset_user_password": "Сбросить пароль пользователя",
"generic_error": "Не удалось подключиться к серверу!"
}, },
"validations": { "validations": {
"required": "Обязательное поле", "required": "Обязательное поле",

View File

@ -348,4 +348,12 @@ enum UserType {
type Users { type Users {
allUsers: [User!]! allUsers: [User!]!
getUser(username: String!): User getUser(username: String!): User
}
fragment dnsRecordFields on DnsRecord {
content
name
priority
recordType
ttl
} }

View File

@ -1,3 +1,5 @@
import 'package:gql/ast.dart';
import 'package:graphql/client.dart' as graphql;
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:selfprivacy/utils/scalars.dart'; import 'package:selfprivacy/utils/scalars.dart';
part 'schema.graphql.g.dart'; part 'schema.graphql.g.dart';
@ -736,6 +738,220 @@ enum Enum$UserType {
$unknown $unknown
} }
@JsonSerializable(explicitToJson: true)
class Fragment$dnsRecordFields {
Fragment$dnsRecordFields(
{required this.content,
required this.name,
this.priority,
required this.recordType,
required this.ttl,
required this.$__typename});
@override
factory Fragment$dnsRecordFields.fromJson(Map<String, dynamic> json) =>
_$Fragment$dnsRecordFieldsFromJson(json);
final String content;
final String name;
final int? priority;
final String recordType;
final int ttl;
@JsonKey(name: '__typename')
final String $__typename;
Map<String, dynamic> toJson() => _$Fragment$dnsRecordFieldsToJson(this);
int get hashCode {
final l$content = content;
final l$name = name;
final l$priority = priority;
final l$recordType = recordType;
final l$ttl = ttl;
final l$$__typename = $__typename;
return Object.hashAll(
[l$content, l$name, l$priority, l$recordType, l$ttl, l$$__typename]);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (!(other is Fragment$dnsRecordFields) ||
runtimeType != other.runtimeType) return false;
final l$content = content;
final lOther$content = other.content;
if (l$content != lOther$content) return false;
final l$name = name;
final lOther$name = other.name;
if (l$name != lOther$name) return false;
final l$priority = priority;
final lOther$priority = other.priority;
if (l$priority != lOther$priority) return false;
final l$recordType = recordType;
final lOther$recordType = other.recordType;
if (l$recordType != lOther$recordType) return false;
final l$ttl = ttl;
final lOther$ttl = other.ttl;
if (l$ttl != lOther$ttl) return false;
final l$$__typename = $__typename;
final lOther$$__typename = other.$__typename;
if (l$$__typename != lOther$$__typename) return false;
return true;
}
}
extension UtilityExtension$Fragment$dnsRecordFields
on Fragment$dnsRecordFields {
CopyWith$Fragment$dnsRecordFields<Fragment$dnsRecordFields> get copyWith =>
CopyWith$Fragment$dnsRecordFields(this, (i) => i);
}
abstract class CopyWith$Fragment$dnsRecordFields<TRes> {
factory CopyWith$Fragment$dnsRecordFields(Fragment$dnsRecordFields instance,
TRes Function(Fragment$dnsRecordFields) then) =
_CopyWithImpl$Fragment$dnsRecordFields;
factory CopyWith$Fragment$dnsRecordFields.stub(TRes res) =
_CopyWithStubImpl$Fragment$dnsRecordFields;
TRes call(
{String? content,
String? name,
int? priority,
String? recordType,
int? ttl,
String? $__typename});
}
class _CopyWithImpl$Fragment$dnsRecordFields<TRes>
implements CopyWith$Fragment$dnsRecordFields<TRes> {
_CopyWithImpl$Fragment$dnsRecordFields(this._instance, this._then);
final Fragment$dnsRecordFields _instance;
final TRes Function(Fragment$dnsRecordFields) _then;
static const _undefined = {};
TRes call(
{Object? content = _undefined,
Object? name = _undefined,
Object? priority = _undefined,
Object? recordType = _undefined,
Object? ttl = _undefined,
Object? $__typename = _undefined}) =>
_then(Fragment$dnsRecordFields(
content: content == _undefined || content == null
? _instance.content
: (content as String),
name: name == _undefined || name == null
? _instance.name
: (name as String),
priority:
priority == _undefined ? _instance.priority : (priority as int?),
recordType: recordType == _undefined || recordType == null
? _instance.recordType
: (recordType as String),
ttl: ttl == _undefined || ttl == null ? _instance.ttl : (ttl as int),
$__typename: $__typename == _undefined || $__typename == null
? _instance.$__typename
: ($__typename as String)));
}
class _CopyWithStubImpl$Fragment$dnsRecordFields<TRes>
implements CopyWith$Fragment$dnsRecordFields<TRes> {
_CopyWithStubImpl$Fragment$dnsRecordFields(this._res);
TRes _res;
call(
{String? content,
String? name,
int? priority,
String? recordType,
int? ttl,
String? $__typename}) =>
_res;
}
const fragmentDefinitiondnsRecordFields = FragmentDefinitionNode(
name: NameNode(value: 'dnsRecordFields'),
typeCondition: TypeConditionNode(
on: NamedTypeNode(
name: NameNode(value: 'DnsRecord'), isNonNull: false)),
directives: [],
selectionSet: SelectionSetNode(selections: [
FieldNode(
name: NameNode(value: 'content'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'name'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'priority'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'recordType'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'ttl'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: '__typename'),
alias: null,
arguments: [],
directives: [],
selectionSet: null)
]));
const documentNodeFragmentdnsRecordFields = DocumentNode(definitions: [
fragmentDefinitiondnsRecordFields,
]);
extension ClientExtension$Fragment$dnsRecordFields on graphql.GraphQLClient {
void writeFragment$dnsRecordFields(
{required Fragment$dnsRecordFields data,
required Map<String, dynamic> idFields,
bool broadcast = true}) =>
this.writeFragment(
graphql.FragmentRequest(
idFields: idFields,
fragment: const graphql.Fragment(
fragmentName: 'dnsRecordFields',
document: documentNodeFragmentdnsRecordFields)),
data: data.toJson(),
broadcast: broadcast);
Fragment$dnsRecordFields? readFragment$dnsRecordFields(
{required Map<String, dynamic> idFields, bool optimistic = true}) {
final result = this.readFragment(
graphql.FragmentRequest(
idFields: idFields,
fragment: const graphql.Fragment(
fragmentName: 'dnsRecordFields',
document: documentNodeFragmentdnsRecordFields)),
optimistic: optimistic);
return result == null ? null : Fragment$dnsRecordFields.fromJson(result);
}
}
const possibleTypesMap = { const possibleTypesMap = {
'MutationReturnInterface': { 'MutationReturnInterface': {
'ApiKeyMutationReturn', 'ApiKeyMutationReturn',

View File

@ -123,3 +123,25 @@ Map<String, dynamic> _$Input$UserMutationInputToJson(
'username': instance.username, 'username': instance.username,
'password': instance.password, 'password': instance.password,
}; };
Fragment$dnsRecordFields _$Fragment$dnsRecordFieldsFromJson(
Map<String, dynamic> json) =>
Fragment$dnsRecordFields(
content: json['content'] as String,
name: json['name'] as String,
priority: json['priority'] as int?,
recordType: json['recordType'] as String,
ttl: json['ttl'] as int,
$__typename: json['__typename'] as String,
);
Map<String, dynamic> _$Fragment$dnsRecordFieldsToJson(
Fragment$dnsRecordFields instance) =>
<String, dynamic>{
'content': instance.content,
'name': instance.name,
'priority': instance.priority,
'recordType': instance.recordType,
'ttl': instance.ttl,
'__typename': instance.$__typename,
};

View File

@ -35,11 +35,7 @@ query DomainInfo {
hostname hostname
provider provider
requiredDnsRecords { requiredDnsRecords {
content ...dnsRecordFields
name
priority
recordType
ttl
} }
} }
} }

View File

@ -1444,36 +1444,9 @@ const documentNodeQueryDomainInfo = DocumentNode(definitions: [
arguments: [], arguments: [],
directives: [], directives: [],
selectionSet: SelectionSetNode(selections: [ selectionSet: SelectionSetNode(selections: [
FieldNode( FragmentSpreadNode(
name: NameNode(value: 'content'), name: NameNode(value: 'dnsRecordFields'),
alias: null, directives: []),
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'name'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'priority'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'recordType'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'ttl'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode( FieldNode(
name: NameNode(value: '__typename'), name: NameNode(value: '__typename'),
alias: null, alias: null,
@ -1502,6 +1475,7 @@ const documentNodeQueryDomainInfo = DocumentNode(definitions: [
directives: [], directives: [],
selectionSet: null) selectionSet: null)
])), ])),
fragmentDefinitiondnsRecordFields,
]); ]);
Query$DomainInfo _parserFn$Query$DomainInfo(Map<String, dynamic> data) => Query$DomainInfo _parserFn$Query$DomainInfo(Map<String, dynamic> data) =>
Query$DomainInfo.fromJson(data); Query$DomainInfo.fromJson(data);
@ -1699,8 +1673,7 @@ class Query$DomainInfo$system$domainInfo {
@JsonKey(unknownEnumValue: Enum$DnsProvider.$unknown) @JsonKey(unknownEnumValue: Enum$DnsProvider.$unknown)
final Enum$DnsProvider provider; final Enum$DnsProvider provider;
final List<Query$DomainInfo$system$domainInfo$requiredDnsRecords> final List<Fragment$dnsRecordFields> requiredDnsRecords;
requiredDnsRecords;
@JsonKey(name: '__typename') @JsonKey(name: '__typename')
final String $__typename; final String $__typename;
@ -1775,14 +1748,12 @@ abstract class CopyWith$Query$DomainInfo$system$domainInfo<TRes> {
{String? domain, {String? domain,
String? hostname, String? hostname,
Enum$DnsProvider? provider, Enum$DnsProvider? provider,
List<Query$DomainInfo$system$domainInfo$requiredDnsRecords>? List<Fragment$dnsRecordFields>? requiredDnsRecords,
requiredDnsRecords,
String? $__typename}); String? $__typename});
TRes requiredDnsRecords( TRes requiredDnsRecords(
Iterable<Query$DomainInfo$system$domainInfo$requiredDnsRecords> Function( Iterable<Fragment$dnsRecordFields> Function(
Iterable< Iterable<
CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords< CopyWith$Fragment$dnsRecordFields<Fragment$dnsRecordFields>>)
Query$DomainInfo$system$domainInfo$requiredDnsRecords>>)
_fn); _fn);
} }
@ -1815,21 +1786,20 @@ class _CopyWithImpl$Query$DomainInfo$system$domainInfo<TRes>
requiredDnsRecords: requiredDnsRecords:
requiredDnsRecords == _undefined || requiredDnsRecords == null requiredDnsRecords == _undefined || requiredDnsRecords == null
? _instance.requiredDnsRecords ? _instance.requiredDnsRecords
: (requiredDnsRecords as List< : (requiredDnsRecords as List<Fragment$dnsRecordFields>),
Query$DomainInfo$system$domainInfo$requiredDnsRecords>),
$__typename: $__typename == _undefined || $__typename == null $__typename: $__typename == _undefined || $__typename == null
? _instance.$__typename ? _instance.$__typename
: ($__typename as String))); : ($__typename as String)));
TRes requiredDnsRecords( TRes requiredDnsRecords(
Iterable<Query$DomainInfo$system$domainInfo$requiredDnsRecords> Function( Iterable<Fragment$dnsRecordFields> Function(
Iterable< Iterable<
CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords< CopyWith$Fragment$dnsRecordFields<
Query$DomainInfo$system$domainInfo$requiredDnsRecords>>) Fragment$dnsRecordFields>>)
_fn) => _fn) =>
call( call(
requiredDnsRecords: _fn(_instance.requiredDnsRecords.map((e) => requiredDnsRecords: _fn(_instance.requiredDnsRecords
CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords( .map((e) => CopyWith$Fragment$dnsRecordFields(e, (i) => i)))
e, (i) => i))).toList()); .toList());
} }
class _CopyWithStubImpl$Query$DomainInfo$system$domainInfo<TRes> class _CopyWithStubImpl$Query$DomainInfo$system$domainInfo<TRes>
@ -1842,168 +1812,12 @@ class _CopyWithStubImpl$Query$DomainInfo$system$domainInfo<TRes>
{String? domain, {String? domain,
String? hostname, String? hostname,
Enum$DnsProvider? provider, Enum$DnsProvider? provider,
List<Query$DomainInfo$system$domainInfo$requiredDnsRecords>? List<Fragment$dnsRecordFields>? requiredDnsRecords,
requiredDnsRecords,
String? $__typename}) => String? $__typename}) =>
_res; _res;
requiredDnsRecords(_fn) => _res; requiredDnsRecords(_fn) => _res;
} }
@JsonSerializable(explicitToJson: true)
class Query$DomainInfo$system$domainInfo$requiredDnsRecords {
Query$DomainInfo$system$domainInfo$requiredDnsRecords(
{required this.content,
required this.name,
this.priority,
required this.recordType,
required this.ttl,
required this.$__typename});
@override
factory Query$DomainInfo$system$domainInfo$requiredDnsRecords.fromJson(
Map<String, dynamic> json) =>
_$Query$DomainInfo$system$domainInfo$requiredDnsRecordsFromJson(json);
final String content;
final String name;
final int? priority;
final String recordType;
final int ttl;
@JsonKey(name: '__typename')
final String $__typename;
Map<String, dynamic> toJson() =>
_$Query$DomainInfo$system$domainInfo$requiredDnsRecordsToJson(this);
int get hashCode {
final l$content = content;
final l$name = name;
final l$priority = priority;
final l$recordType = recordType;
final l$ttl = ttl;
final l$$__typename = $__typename;
return Object.hashAll(
[l$content, l$name, l$priority, l$recordType, l$ttl, l$$__typename]);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (!(other is Query$DomainInfo$system$domainInfo$requiredDnsRecords) ||
runtimeType != other.runtimeType) return false;
final l$content = content;
final lOther$content = other.content;
if (l$content != lOther$content) return false;
final l$name = name;
final lOther$name = other.name;
if (l$name != lOther$name) return false;
final l$priority = priority;
final lOther$priority = other.priority;
if (l$priority != lOther$priority) return false;
final l$recordType = recordType;
final lOther$recordType = other.recordType;
if (l$recordType != lOther$recordType) return false;
final l$ttl = ttl;
final lOther$ttl = other.ttl;
if (l$ttl != lOther$ttl) return false;
final l$$__typename = $__typename;
final lOther$$__typename = other.$__typename;
if (l$$__typename != lOther$$__typename) return false;
return true;
}
}
extension UtilityExtension$Query$DomainInfo$system$domainInfo$requiredDnsRecords
on Query$DomainInfo$system$domainInfo$requiredDnsRecords {
CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords<
Query$DomainInfo$system$domainInfo$requiredDnsRecords>
get copyWith =>
CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords(
this, (i) => i);
}
abstract class CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords<
TRes> {
factory CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords(
Query$DomainInfo$system$domainInfo$requiredDnsRecords instance,
TRes Function(Query$DomainInfo$system$domainInfo$requiredDnsRecords)
then) =
_CopyWithImpl$Query$DomainInfo$system$domainInfo$requiredDnsRecords;
factory CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords.stub(
TRes res) =
_CopyWithStubImpl$Query$DomainInfo$system$domainInfo$requiredDnsRecords;
TRes call(
{String? content,
String? name,
int? priority,
String? recordType,
int? ttl,
String? $__typename});
}
class _CopyWithImpl$Query$DomainInfo$system$domainInfo$requiredDnsRecords<TRes>
implements
CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords<TRes> {
_CopyWithImpl$Query$DomainInfo$system$domainInfo$requiredDnsRecords(
this._instance, this._then);
final Query$DomainInfo$system$domainInfo$requiredDnsRecords _instance;
final TRes Function(Query$DomainInfo$system$domainInfo$requiredDnsRecords)
_then;
static const _undefined = {};
TRes call(
{Object? content = _undefined,
Object? name = _undefined,
Object? priority = _undefined,
Object? recordType = _undefined,
Object? ttl = _undefined,
Object? $__typename = _undefined}) =>
_then(Query$DomainInfo$system$domainInfo$requiredDnsRecords(
content: content == _undefined || content == null
? _instance.content
: (content as String),
name: name == _undefined || name == null
? _instance.name
: (name as String),
priority:
priority == _undefined ? _instance.priority : (priority as int?),
recordType: recordType == _undefined || recordType == null
? _instance.recordType
: (recordType as String),
ttl: ttl == _undefined || ttl == null ? _instance.ttl : (ttl as int),
$__typename: $__typename == _undefined || $__typename == null
? _instance.$__typename
: ($__typename as String)));
}
class _CopyWithStubImpl$Query$DomainInfo$system$domainInfo$requiredDnsRecords<
TRes>
implements
CopyWith$Query$DomainInfo$system$domainInfo$requiredDnsRecords<TRes> {
_CopyWithStubImpl$Query$DomainInfo$system$domainInfo$requiredDnsRecords(
this._res);
TRes _res;
call(
{String? content,
String? name,
int? priority,
String? recordType,
int? ttl,
String? $__typename}) =>
_res;
}
@JsonSerializable(explicitToJson: true) @JsonSerializable(explicitToJson: true)
class Variables$Mutation$ChangeTimezone { class Variables$Mutation$ChangeTimezone {
Variables$Mutation$ChangeTimezone({required this.timezone}); Variables$Mutation$ChangeTimezone({required this.timezone});

View File

@ -190,8 +190,7 @@ Query$DomainInfo$system$domainInfo _$Query$DomainInfo$system$domainInfoFromJson(
unknownValue: Enum$DnsProvider.$unknown), unknownValue: Enum$DnsProvider.$unknown),
requiredDnsRecords: (json['requiredDnsRecords'] as List<dynamic>) requiredDnsRecords: (json['requiredDnsRecords'] as List<dynamic>)
.map((e) => .map((e) =>
Query$DomainInfo$system$domainInfo$requiredDnsRecords.fromJson( Fragment$dnsRecordFields.fromJson(e as Map<String, dynamic>))
e as Map<String, dynamic>))
.toList(), .toList(),
$__typename: json['__typename'] as String, $__typename: json['__typename'] as String,
); );
@ -212,30 +211,6 @@ const _$Enum$DnsProviderEnumMap = {
Enum$DnsProvider.$unknown: r'$unknown', Enum$DnsProvider.$unknown: r'$unknown',
}; };
Query$DomainInfo$system$domainInfo$requiredDnsRecords
_$Query$DomainInfo$system$domainInfo$requiredDnsRecordsFromJson(
Map<String, dynamic> json) =>
Query$DomainInfo$system$domainInfo$requiredDnsRecords(
content: json['content'] as String,
name: json['name'] as String,
priority: json['priority'] as int?,
recordType: json['recordType'] as String,
ttl: json['ttl'] as int,
$__typename: json['__typename'] as String,
);
Map<String, dynamic>
_$Query$DomainInfo$system$domainInfo$requiredDnsRecordsToJson(
Query$DomainInfo$system$domainInfo$requiredDnsRecords instance) =>
<String, dynamic>{
'content': instance.content,
'name': instance.name,
'priority': instance.priority,
'recordType': instance.recordType,
'ttl': instance.ttl,
'__typename': instance.$__typename,
};
Variables$Mutation$ChangeTimezone _$Variables$Mutation$ChangeTimezoneFromJson( Variables$Mutation$ChangeTimezone _$Variables$Mutation$ChangeTimezoneFromJson(
Map<String, dynamic> json) => Map<String, dynamic> json) =>
Variables$Mutation$ChangeTimezone( Variables$Mutation$ChangeTimezone(

View File

@ -10,11 +10,7 @@ query AllServices {
description description
displayName displayName
dnsRecords { dnsRecords {
content ...dnsRecordFields
name
priority
recordType
ttl
} }
id id
isEnabled isEnabled

View File

@ -312,36 +312,9 @@ const documentNodeQueryAllServices = DocumentNode(definitions: [
arguments: [], arguments: [],
directives: [], directives: [],
selectionSet: SelectionSetNode(selections: [ selectionSet: SelectionSetNode(selections: [
FieldNode( FragmentSpreadNode(
name: NameNode(value: 'content'), name: NameNode(value: 'dnsRecordFields'),
alias: null, directives: []),
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'name'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'priority'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'recordType'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'ttl'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode( FieldNode(
name: NameNode(value: '__typename'), name: NameNode(value: '__typename'),
alias: null, alias: null,
@ -456,6 +429,7 @@ const documentNodeQueryAllServices = DocumentNode(definitions: [
directives: [], directives: [],
selectionSet: null) selectionSet: null)
])), ])),
fragmentDefinitiondnsRecordFields,
]); ]);
Query$AllServices _parserFn$Query$AllServices(Map<String, dynamic> data) => Query$AllServices _parserFn$Query$AllServices(Map<String, dynamic> data) =>
Query$AllServices.fromJson(data); Query$AllServices.fromJson(data);
@ -679,7 +653,7 @@ class Query$AllServices$services$allServices {
final String displayName; final String displayName;
final List<Query$AllServices$services$allServices$dnsRecords>? dnsRecords; final List<Fragment$dnsRecordFields>? dnsRecords;
final String id; final String id;
@ -807,7 +781,7 @@ abstract class CopyWith$Query$AllServices$services$allServices<TRes> {
TRes call( TRes call(
{String? description, {String? description,
String? displayName, String? displayName,
List<Query$AllServices$services$allServices$dnsRecords>? dnsRecords, List<Fragment$dnsRecordFields>? dnsRecords,
String? id, String? id,
bool? isEnabled, bool? isEnabled,
bool? isMovable, bool? isMovable,
@ -818,10 +792,9 @@ abstract class CopyWith$Query$AllServices$services$allServices<TRes> {
String? url, String? url,
String? $__typename}); String? $__typename});
TRes dnsRecords( TRes dnsRecords(
Iterable<Query$AllServices$services$allServices$dnsRecords>? Function( Iterable<Fragment$dnsRecordFields>? Function(
Iterable< Iterable<
CopyWith$Query$AllServices$services$allServices$dnsRecords< CopyWith$Fragment$dnsRecordFields<Fragment$dnsRecordFields>>?)
Query$AllServices$services$allServices$dnsRecords>>?)
_fn); _fn);
CopyWith$Query$AllServices$services$allServices$storageUsage<TRes> CopyWith$Query$AllServices$services$allServices$storageUsage<TRes>
get storageUsage; get storageUsage;
@ -860,8 +833,7 @@ class _CopyWithImpl$Query$AllServices$services$allServices<TRes>
: (displayName as String), : (displayName as String),
dnsRecords: dnsRecords == _undefined dnsRecords: dnsRecords == _undefined
? _instance.dnsRecords ? _instance.dnsRecords
: (dnsRecords : (dnsRecords as List<Fragment$dnsRecordFields>?),
as List<Query$AllServices$services$allServices$dnsRecords>?),
id: id == _undefined || id == null ? _instance.id : (id as String), id: id == _undefined || id == null ? _instance.id : (id as String),
isEnabled: isEnabled == _undefined || isEnabled == null isEnabled: isEnabled == _undefined || isEnabled == null
? _instance.isEnabled ? _instance.isEnabled
@ -887,15 +859,15 @@ class _CopyWithImpl$Query$AllServices$services$allServices<TRes>
? _instance.$__typename ? _instance.$__typename
: ($__typename as String))); : ($__typename as String)));
TRes dnsRecords( TRes dnsRecords(
Iterable<Query$AllServices$services$allServices$dnsRecords>? Function( Iterable<Fragment$dnsRecordFields>? Function(
Iterable< Iterable<
CopyWith$Query$AllServices$services$allServices$dnsRecords< CopyWith$Fragment$dnsRecordFields<
Query$AllServices$services$allServices$dnsRecords>>?) Fragment$dnsRecordFields>>?)
_fn) => _fn) =>
call( call(
dnsRecords: _fn(_instance.dnsRecords?.map((e) => dnsRecords: _fn(_instance.dnsRecords
CopyWith$Query$AllServices$services$allServices$dnsRecords( ?.map((e) => CopyWith$Fragment$dnsRecordFields(e, (i) => i)))
e, (i) => i)))?.toList()); ?.toList());
CopyWith$Query$AllServices$services$allServices$storageUsage<TRes> CopyWith$Query$AllServices$services$allServices$storageUsage<TRes>
get storageUsage { get storageUsage {
final local$storageUsage = _instance.storageUsage; final local$storageUsage = _instance.storageUsage;
@ -913,7 +885,7 @@ class _CopyWithStubImpl$Query$AllServices$services$allServices<TRes>
call( call(
{String? description, {String? description,
String? displayName, String? displayName,
List<Query$AllServices$services$allServices$dnsRecords>? dnsRecords, List<Fragment$dnsRecordFields>? dnsRecords,
String? id, String? id,
bool? isEnabled, bool? isEnabled,
bool? isMovable, bool? isMovable,
@ -931,159 +903,6 @@ class _CopyWithStubImpl$Query$AllServices$services$allServices<TRes>
_res); _res);
} }
@JsonSerializable(explicitToJson: true)
class Query$AllServices$services$allServices$dnsRecords {
Query$AllServices$services$allServices$dnsRecords(
{required this.content,
required this.name,
this.priority,
required this.recordType,
required this.ttl,
required this.$__typename});
@override
factory Query$AllServices$services$allServices$dnsRecords.fromJson(
Map<String, dynamic> json) =>
_$Query$AllServices$services$allServices$dnsRecordsFromJson(json);
final String content;
final String name;
final int? priority;
final String recordType;
final int ttl;
@JsonKey(name: '__typename')
final String $__typename;
Map<String, dynamic> toJson() =>
_$Query$AllServices$services$allServices$dnsRecordsToJson(this);
int get hashCode {
final l$content = content;
final l$name = name;
final l$priority = priority;
final l$recordType = recordType;
final l$ttl = ttl;
final l$$__typename = $__typename;
return Object.hashAll(
[l$content, l$name, l$priority, l$recordType, l$ttl, l$$__typename]);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (!(other is Query$AllServices$services$allServices$dnsRecords) ||
runtimeType != other.runtimeType) return false;
final l$content = content;
final lOther$content = other.content;
if (l$content != lOther$content) return false;
final l$name = name;
final lOther$name = other.name;
if (l$name != lOther$name) return false;
final l$priority = priority;
final lOther$priority = other.priority;
if (l$priority != lOther$priority) return false;
final l$recordType = recordType;
final lOther$recordType = other.recordType;
if (l$recordType != lOther$recordType) return false;
final l$ttl = ttl;
final lOther$ttl = other.ttl;
if (l$ttl != lOther$ttl) return false;
final l$$__typename = $__typename;
final lOther$$__typename = other.$__typename;
if (l$$__typename != lOther$$__typename) return false;
return true;
}
}
extension UtilityExtension$Query$AllServices$services$allServices$dnsRecords
on Query$AllServices$services$allServices$dnsRecords {
CopyWith$Query$AllServices$services$allServices$dnsRecords<
Query$AllServices$services$allServices$dnsRecords>
get copyWith =>
CopyWith$Query$AllServices$services$allServices$dnsRecords(
this, (i) => i);
}
abstract class CopyWith$Query$AllServices$services$allServices$dnsRecords<
TRes> {
factory CopyWith$Query$AllServices$services$allServices$dnsRecords(
Query$AllServices$services$allServices$dnsRecords instance,
TRes Function(Query$AllServices$services$allServices$dnsRecords)
then) =
_CopyWithImpl$Query$AllServices$services$allServices$dnsRecords;
factory CopyWith$Query$AllServices$services$allServices$dnsRecords.stub(
TRes res) =
_CopyWithStubImpl$Query$AllServices$services$allServices$dnsRecords;
TRes call(
{String? content,
String? name,
int? priority,
String? recordType,
int? ttl,
String? $__typename});
}
class _CopyWithImpl$Query$AllServices$services$allServices$dnsRecords<TRes>
implements
CopyWith$Query$AllServices$services$allServices$dnsRecords<TRes> {
_CopyWithImpl$Query$AllServices$services$allServices$dnsRecords(
this._instance, this._then);
final Query$AllServices$services$allServices$dnsRecords _instance;
final TRes Function(Query$AllServices$services$allServices$dnsRecords) _then;
static const _undefined = {};
TRes call(
{Object? content = _undefined,
Object? name = _undefined,
Object? priority = _undefined,
Object? recordType = _undefined,
Object? ttl = _undefined,
Object? $__typename = _undefined}) =>
_then(Query$AllServices$services$allServices$dnsRecords(
content: content == _undefined || content == null
? _instance.content
: (content as String),
name: name == _undefined || name == null
? _instance.name
: (name as String),
priority:
priority == _undefined ? _instance.priority : (priority as int?),
recordType: recordType == _undefined || recordType == null
? _instance.recordType
: (recordType as String),
ttl: ttl == _undefined || ttl == null ? _instance.ttl : (ttl as int),
$__typename: $__typename == _undefined || $__typename == null
? _instance.$__typename
: ($__typename as String)));
}
class _CopyWithStubImpl$Query$AllServices$services$allServices$dnsRecords<TRes>
implements
CopyWith$Query$AllServices$services$allServices$dnsRecords<TRes> {
_CopyWithStubImpl$Query$AllServices$services$allServices$dnsRecords(
this._res);
TRes _res;
call(
{String? content,
String? name,
int? priority,
String? recordType,
int? ttl,
String? $__typename}) =>
_res;
}
@JsonSerializable(explicitToJson: true) @JsonSerializable(explicitToJson: true)
class Query$AllServices$services$allServices$storageUsage { class Query$AllServices$services$allServices$storageUsage {
Query$AllServices$services$allServices$storageUsage( Query$AllServices$services$allServices$storageUsage(

View File

@ -62,8 +62,7 @@ Query$AllServices$services$allServices
displayName: json['displayName'] as String, displayName: json['displayName'] as String,
dnsRecords: (json['dnsRecords'] as List<dynamic>?) dnsRecords: (json['dnsRecords'] as List<dynamic>?)
?.map((e) => ?.map((e) =>
Query$AllServices$services$allServices$dnsRecords.fromJson( Fragment$dnsRecordFields.fromJson(e as Map<String, dynamic>))
e as Map<String, dynamic>))
.toList(), .toList(),
id: json['id'] as String, id: json['id'] as String,
isEnabled: json['isEnabled'] as bool, isEnabled: json['isEnabled'] as bool,
@ -107,29 +106,6 @@ const _$Enum$ServiceStatusEnumEnumMap = {
Enum$ServiceStatusEnum.$unknown: r'$unknown', Enum$ServiceStatusEnum.$unknown: r'$unknown',
}; };
Query$AllServices$services$allServices$dnsRecords
_$Query$AllServices$services$allServices$dnsRecordsFromJson(
Map<String, dynamic> json) =>
Query$AllServices$services$allServices$dnsRecords(
content: json['content'] as String,
name: json['name'] as String,
priority: json['priority'] as int?,
recordType: json['recordType'] as String,
ttl: json['ttl'] as int,
$__typename: json['__typename'] as String,
);
Map<String, dynamic> _$Query$AllServices$services$allServices$dnsRecordsToJson(
Query$AllServices$services$allServices$dnsRecords instance) =>
<String, dynamic>{
'content': instance.content,
'name': instance.name,
'priority': instance.priority,
'recordType': instance.recordType,
'ttl': instance.ttl,
'__typename': instance.$__typename,
};
Query$AllServices$services$allServices$storageUsage Query$AllServices$services$allServices$storageUsage
_$Query$AllServices$services$allServices$storageUsageFromJson( _$Query$AllServices$services$allServices$storageUsageFromJson(
Map<String, dynamic> json) => Map<String, dynamic> json) =>

View File

@ -22,20 +22,22 @@ mixin JobsApi on ApiMap {
return jobsList; return jobsList;
} }
Future<GenericMutationResult> removeApiJob(final String uid) async { Future<GenericMutationResult<bool>> removeApiJob(final String uid) async {
try { try {
final GraphQLClient client = await getClient(); final GraphQLClient client = await getClient();
final variables = Variables$Mutation$RemoveJob(jobId: uid); final variables = Variables$Mutation$RemoveJob(jobId: uid);
final mutation = Options$Mutation$RemoveJob(variables: variables); final mutation = Options$Mutation$RemoveJob(variables: variables);
final response = await client.mutate$RemoveJob(mutation); final response = await client.mutate$RemoveJob(mutation);
return GenericMutationResult( return GenericMutationResult(
success: response.parsedData?.removeJob.success ?? false, data: response.parsedData?.removeJob.success ?? false,
success: true,
code: response.parsedData?.removeJob.code ?? 0, code: response.parsedData?.removeJob.code ?? 0,
message: response.parsedData?.removeJob.message, message: response.parsedData?.removeJob.message,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return GenericMutationResult( return GenericMutationResult(
data: false,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),

View File

@ -13,6 +13,7 @@ import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/json/api_token.dart'; import 'package:selfprivacy/logic/models/json/api_token.dart';
import 'package:selfprivacy/logic/models/json/backup.dart'; import 'package:selfprivacy/logic/models/json/backup.dart';
import 'package:selfprivacy/logic/models/json/device_token.dart'; import 'package:selfprivacy/logic/models/json/device_token.dart';
import 'package:selfprivacy/logic/models/json/dns_records.dart';
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart'; import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart'; import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
import 'package:selfprivacy/logic/models/json/server_job.dart'; import 'package:selfprivacy/logic/models/json/server_job.dart';
@ -26,39 +27,28 @@ part 'services_api.dart';
part 'users_api.dart'; part 'users_api.dart';
part 'volume_api.dart'; part 'volume_api.dart';
class GenericMutationResult { class GenericResult<T> {
GenericMutationResult({ GenericResult({
required this.success,
required this.code,
this.message,
});
final bool success;
final int code;
final String? message;
}
class GenericJobMutationReturn extends GenericMutationResult {
GenericJobMutationReturn({
required super.success,
required super.code,
super.message,
this.job,
});
final ServerJob? job;
}
@Deprecated(
'Extend GenericMutationResult for mutations, return data for queries',
)
class ApiResponse<D> {
ApiResponse({
required this.success, required this.success,
required this.data, required this.data,
this.message, this.message,
}); });
/// Whether was a response successfully received,
/// doesn't represent success of the request if `data<T>` is `bool`
final bool success; final bool success;
final String? message; final String? message;
final D data; final T data;
}
class GenericMutationResult<T> extends GenericResult<T> {
GenericMutationResult({
required super.success,
required this.code,
required super.data,
super.message,
});
final int code;
} }
class ServerApi extends ApiMap class ServerApi extends ApiMap
@ -196,7 +186,7 @@ class ServerApi extends ApiMap
return settings; return settings;
} }
Future<ApiResponse<RecoveryKeyStatus?>> getRecoveryTokenStatus() async { Future<GenericResult<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
RecoveryKeyStatus? key; RecoveryKeyStatus? key;
QueryResult<Query$RecoveryKey> response; QueryResult<Query$RecoveryKey> response;
String? error; String? error;
@ -213,18 +203,18 @@ class ServerApi extends ApiMap
print(e); print(e);
} }
return ApiResponse<RecoveryKeyStatus?>( return GenericResult<RecoveryKeyStatus?>(
success: error == null, success: error == null,
data: key, data: key,
message: error, message: error,
); );
} }
Future<ApiResponse<String>> generateRecoveryToken( Future<GenericResult<String>> generateRecoveryToken(
final DateTime? expirationDate, final DateTime? expirationDate,
final int? numberOfUses, final int? numberOfUses,
) async { ) async {
ApiResponse<String> key; GenericResult<String> key;
QueryResult<Mutation$GetNewRecoveryApiKey> response; QueryResult<Mutation$GetNewRecoveryApiKey> response;
try { try {
@ -245,19 +235,19 @@ class ServerApi extends ApiMap
); );
if (response.hasException) { if (response.hasException) {
print(response.exception.toString()); print(response.exception.toString());
key = ApiResponse<String>( key = GenericResult<String>(
success: false, success: false,
data: '', data: '',
message: response.exception.toString(), message: response.exception.toString(),
); );
} }
key = ApiResponse<String>( key = GenericResult<String>(
success: true, success: true,
data: response.parsedData!.getNewRecoveryApiKey.key!, data: response.parsedData!.getNewRecoveryApiKey.key!,
); );
} catch (e) { } catch (e) {
print(e); print(e);
key = ApiResponse<String>( key = GenericResult<String>(
success: false, success: false,
data: '', data: '',
message: e.toString(), message: e.toString(),
@ -267,11 +257,8 @@ class ServerApi extends ApiMap
return key; return key;
} }
@Deprecated( Future<List<DnsRecord>> getDnsRecords() async {
'Server now aware of all required DNS records. More general approach has to be implemented', List<DnsRecord> records = [];
)
Future<String?> getDkim() async {
String? dkim;
QueryResult<Query$DomainInfo> response; QueryResult<Query$DomainInfo> response;
try { try {
@ -280,25 +267,21 @@ class ServerApi extends ApiMap
if (response.hasException) { if (response.hasException) {
print(response.exception.toString()); print(response.exception.toString());
} }
dkim = response.parsedData!.system.domainInfo.requiredDnsRecords records = response.parsedData!.system.domainInfo.requiredDnsRecords
.firstWhere( .map<DnsRecord>(
( (final Fragment$dnsRecordFields fragment) =>
final Query$DomainInfo$system$domainInfo$requiredDnsRecords DnsRecord.fromGraphQL(fragment),
dnsRecord,
) =>
dnsRecord.name == 'selector._domainkey' &&
dnsRecord.recordType == 'TXT',
) )
.content; .toList();
} catch (e) { } catch (e) {
print(e); print(e);
} }
return dkim; return records;
} }
Future<ApiResponse<List<ApiToken>>> getApiTokens() async { Future<GenericResult<List<ApiToken>>> getApiTokens() async {
ApiResponse<List<ApiToken>> tokens; GenericResult<List<ApiToken>> tokens;
QueryResult<Query$GetApiTokens> response; QueryResult<Query$GetApiTokens> response;
try { try {
@ -307,7 +290,7 @@ class ServerApi extends ApiMap
if (response.hasException) { if (response.hasException) {
final message = response.exception.toString(); final message = response.exception.toString();
print(message); print(message);
tokens = ApiResponse<List<ApiToken>>( tokens = GenericResult<List<ApiToken>>(
success: false, success: false,
data: [], data: [],
message: message, message: message,
@ -321,13 +304,13 @@ class ServerApi extends ApiMap
ApiToken.fromGraphQL(device), ApiToken.fromGraphQL(device),
) )
.toList(); .toList();
tokens = ApiResponse<List<ApiToken>>( tokens = GenericResult<List<ApiToken>>(
success: true, success: true,
data: parsed, data: parsed,
); );
} catch (e) { } catch (e) {
print(e); print(e);
tokens = ApiResponse<List<ApiToken>>( tokens = GenericResult<List<ApiToken>>(
success: false, success: false,
data: [], data: [],
message: e.toString(), message: e.toString(),
@ -337,8 +320,8 @@ class ServerApi extends ApiMap
return tokens; return tokens;
} }
Future<ApiResponse<void>> deleteApiToken(final String name) async { Future<GenericResult<void>> deleteApiToken(final String name) async {
ApiResponse<void> returnable; GenericResult<void> returnable;
QueryResult<Mutation$DeleteDeviceApiToken> response; QueryResult<Mutation$DeleteDeviceApiToken> response;
try { try {
@ -355,19 +338,19 @@ class ServerApi extends ApiMap
); );
if (response.hasException) { if (response.hasException) {
print(response.exception.toString()); print(response.exception.toString());
returnable = ApiResponse<void>( returnable = GenericResult<void>(
success: false, success: false,
data: null, data: null,
message: response.exception.toString(), message: response.exception.toString(),
); );
} }
returnable = ApiResponse<void>( returnable = GenericResult<void>(
success: true, success: true,
data: null, data: null,
); );
} catch (e) { } catch (e) {
print(e); print(e);
returnable = ApiResponse<void>( returnable = GenericResult<void>(
success: false, success: false,
data: null, data: null,
message: e.toString(), message: e.toString(),
@ -377,8 +360,8 @@ class ServerApi extends ApiMap
return returnable; return returnable;
} }
Future<ApiResponse<String>> createDeviceToken() async { Future<GenericResult<String>> createDeviceToken() async {
ApiResponse<String> token; GenericResult<String> token;
QueryResult<Mutation$GetNewDeviceApiKey> response; QueryResult<Mutation$GetNewDeviceApiKey> response;
try { try {
@ -390,19 +373,19 @@ class ServerApi extends ApiMap
); );
if (response.hasException) { if (response.hasException) {
print(response.exception.toString()); print(response.exception.toString());
token = ApiResponse<String>( token = GenericResult<String>(
success: false, success: false,
data: '', data: '',
message: response.exception.toString(), message: response.exception.toString(),
); );
} }
token = ApiResponse<String>( token = GenericResult<String>(
success: true, success: true,
data: response.parsedData!.getNewDeviceApiKey.key!, data: response.parsedData!.getNewDeviceApiKey.key!,
); );
} catch (e) { } catch (e) {
print(e); print(e);
token = ApiResponse<String>( token = GenericResult<String>(
success: false, success: false,
data: '', data: '',
message: e.toString(), message: e.toString(),
@ -414,10 +397,10 @@ class ServerApi extends ApiMap
Future<bool> isHttpServerWorking() async => (await getApiVersion()) != null; Future<bool> isHttpServerWorking() async => (await getApiVersion()) != null;
Future<ApiResponse<String>> authorizeDevice( Future<GenericResult<String>> authorizeDevice(
final DeviceToken deviceToken, final DeviceToken deviceToken,
) async { ) async {
ApiResponse<String> token; GenericResult<String> token;
QueryResult<Mutation$AuthorizeWithNewDeviceApiKey> response; QueryResult<Mutation$AuthorizeWithNewDeviceApiKey> response;
try { try {
@ -439,19 +422,19 @@ class ServerApi extends ApiMap
); );
if (response.hasException) { if (response.hasException) {
print(response.exception.toString()); print(response.exception.toString());
token = ApiResponse<String>( token = GenericResult<String>(
success: false, success: false,
data: '', data: '',
message: response.exception.toString(), message: response.exception.toString(),
); );
} }
token = ApiResponse<String>( token = GenericResult<String>(
success: true, success: true,
data: response.parsedData!.authorizeWithNewDeviceApiKey.token!, data: response.parsedData!.authorizeWithNewDeviceApiKey.token!,
); );
} catch (e) { } catch (e) {
print(e); print(e);
token = ApiResponse<String>( token = GenericResult<String>(
success: false, success: false,
data: '', data: '',
message: e.toString(), message: e.toString(),
@ -461,10 +444,10 @@ class ServerApi extends ApiMap
return token; return token;
} }
Future<ApiResponse<String>> useRecoveryToken( Future<GenericResult<String>> useRecoveryToken(
final DeviceToken deviceToken, final DeviceToken deviceToken,
) async { ) async {
ApiResponse<String> token; GenericResult<String> token;
QueryResult<Mutation$UseRecoveryApiKey> response; QueryResult<Mutation$UseRecoveryApiKey> response;
try { try {
@ -486,19 +469,19 @@ class ServerApi extends ApiMap
); );
if (response.hasException) { if (response.hasException) {
print(response.exception.toString()); print(response.exception.toString());
token = ApiResponse<String>( token = GenericResult<String>(
success: false, success: false,
data: '', data: '',
message: response.exception.toString(), message: response.exception.toString(),
); );
} }
token = ApiResponse<String>( token = GenericResult<String>(
success: true, success: true,
data: response.parsedData!.useRecoveryApiKey.token!, data: response.parsedData!.useRecoveryApiKey.token!,
); );
} catch (e) { } catch (e) {
print(e); print(e);
token = ApiResponse<String>( token = GenericResult<String>(
success: false, success: false,
data: '', data: '',
message: e.toString(), message: e.toString(),

View File

@ -20,20 +20,24 @@ mixin ServicesApi on ApiMap {
return services; return services;
} }
Future<GenericMutationResult> enableService(final String serviceId) async { Future<GenericMutationResult<bool>> enableService(
final String serviceId,
) async {
try { try {
final GraphQLClient client = await getClient(); final GraphQLClient client = await getClient();
final variables = Variables$Mutation$EnableService(serviceId: serviceId); final variables = Variables$Mutation$EnableService(serviceId: serviceId);
final mutation = Options$Mutation$EnableService(variables: variables); final mutation = Options$Mutation$EnableService(variables: variables);
final response = await client.mutate$EnableService(mutation); final response = await client.mutate$EnableService(mutation);
return GenericMutationResult( return GenericMutationResult(
success: response.parsedData?.enableService.success ?? false, data: response.parsedData?.enableService.success ?? false,
success: true,
code: response.parsedData?.enableService.code ?? 0, code: response.parsedData?.enableService.code ?? 0,
message: response.parsedData?.enableService.message, message: response.parsedData?.enableService.message,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return GenericMutationResult( return GenericMutationResult(
data: false,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
@ -41,13 +45,16 @@ mixin ServicesApi on ApiMap {
} }
} }
Future<GenericMutationResult> disableService(final String serviceId) async { Future<GenericMutationResult<void>> disableService(
final String serviceId,
) async {
try { try {
final GraphQLClient client = await getClient(); final GraphQLClient client = await getClient();
final variables = Variables$Mutation$DisableService(serviceId: serviceId); final variables = Variables$Mutation$DisableService(serviceId: serviceId);
final mutation = Options$Mutation$DisableService(variables: variables); final mutation = Options$Mutation$DisableService(variables: variables);
final response = await client.mutate$DisableService(mutation); final response = await client.mutate$DisableService(mutation);
return GenericMutationResult( return GenericMutationResult(
data: null,
success: response.parsedData?.disableService.success ?? false, success: response.parsedData?.disableService.success ?? false,
code: response.parsedData?.disableService.code ?? 0, code: response.parsedData?.disableService.code ?? 0,
message: response.parsedData?.disableService.message, message: response.parsedData?.disableService.message,
@ -55,6 +62,7 @@ mixin ServicesApi on ApiMap {
} catch (e) { } catch (e) {
print(e); print(e);
return GenericMutationResult( return GenericMutationResult(
data: null,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
@ -62,20 +70,24 @@ mixin ServicesApi on ApiMap {
} }
} }
Future<GenericMutationResult> stopService(final String serviceId) async { Future<GenericMutationResult<bool>> stopService(
final String serviceId,
) async {
try { try {
final GraphQLClient client = await getClient(); final GraphQLClient client = await getClient();
final variables = Variables$Mutation$StopService(serviceId: serviceId); final variables = Variables$Mutation$StopService(serviceId: serviceId);
final mutation = Options$Mutation$StopService(variables: variables); final mutation = Options$Mutation$StopService(variables: variables);
final response = await client.mutate$StopService(mutation); final response = await client.mutate$StopService(mutation);
return GenericMutationResult( return GenericMutationResult(
success: response.parsedData?.stopService.success ?? false, data: response.parsedData?.stopService.success ?? false,
success: true,
code: response.parsedData?.stopService.code ?? 0, code: response.parsedData?.stopService.code ?? 0,
message: response.parsedData?.stopService.message, message: response.parsedData?.stopService.message,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return GenericMutationResult( return GenericMutationResult(
data: false,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
@ -90,6 +102,7 @@ mixin ServicesApi on ApiMap {
final mutation = Options$Mutation$StartService(variables: variables); final mutation = Options$Mutation$StartService(variables: variables);
final response = await client.mutate$StartService(mutation); final response = await client.mutate$StartService(mutation);
return GenericMutationResult( return GenericMutationResult(
data: null,
success: response.parsedData?.startService.success ?? false, success: response.parsedData?.startService.success ?? false,
code: response.parsedData?.startService.code ?? 0, code: response.parsedData?.startService.code ?? 0,
message: response.parsedData?.startService.message, message: response.parsedData?.startService.message,
@ -97,6 +110,7 @@ mixin ServicesApi on ApiMap {
} catch (e) { } catch (e) {
print(e); print(e);
return GenericMutationResult( return GenericMutationResult(
data: null,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
@ -104,20 +118,24 @@ mixin ServicesApi on ApiMap {
} }
} }
Future<GenericMutationResult> restartService(final String serviceId) async { Future<GenericMutationResult<bool>> restartService(
final String serviceId,
) async {
try { try {
final GraphQLClient client = await getClient(); final GraphQLClient client = await getClient();
final variables = Variables$Mutation$RestartService(serviceId: serviceId); final variables = Variables$Mutation$RestartService(serviceId: serviceId);
final mutation = Options$Mutation$RestartService(variables: variables); final mutation = Options$Mutation$RestartService(variables: variables);
final response = await client.mutate$RestartService(mutation); final response = await client.mutate$RestartService(mutation);
return GenericMutationResult( return GenericMutationResult(
success: response.parsedData?.restartService.success ?? false, data: response.parsedData?.restartService.success ?? false,
success: true,
code: response.parsedData?.restartService.code ?? 0, code: response.parsedData?.restartService.code ?? 0,
message: response.parsedData?.restartService.message, message: response.parsedData?.restartService.message,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return GenericMutationResult( return GenericMutationResult(
data: false,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
@ -125,7 +143,7 @@ mixin ServicesApi on ApiMap {
} }
} }
Future<GenericJobMutationReturn> moveService( Future<GenericMutationResult<ServerJob?>> moveService(
final String serviceId, final String serviceId,
final String destination, final String destination,
) async { ) async {
@ -140,19 +158,19 @@ mixin ServicesApi on ApiMap {
final mutation = Options$Mutation$MoveService(variables: variables); final mutation = Options$Mutation$MoveService(variables: variables);
final response = await client.mutate$MoveService(mutation); final response = await client.mutate$MoveService(mutation);
final jobJson = response.parsedData?.moveService.job?.toJson(); final jobJson = response.parsedData?.moveService.job?.toJson();
return GenericJobMutationReturn( return GenericMutationResult(
success: response.parsedData?.moveService.success ?? false, success: true,
code: response.parsedData?.moveService.code ?? 0, code: response.parsedData?.moveService.code ?? 0,
message: response.parsedData?.moveService.message, message: response.parsedData?.moveService.message,
job: jobJson != null ? ServerJob.fromJson(jobJson) : null, data: jobJson != null ? ServerJob.fromJson(jobJson) : null,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return GenericJobMutationReturn( return GenericMutationResult(
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
job: null, data: null,
); );
} }
} }

View File

@ -1,16 +1,5 @@
part of 'server.dart'; part of 'server.dart';
class UserMutationResult extends GenericMutationResult {
UserMutationResult({
required super.success,
required super.code,
super.message,
this.user,
});
final User? user;
}
mixin UsersApi on ApiMap { mixin UsersApi on ApiMap {
Future<List<User>> getAllUsers() async { Future<List<User>> getAllUsers() async {
QueryResult<Query$AllUsers> response; QueryResult<Query$AllUsers> response;
@ -56,7 +45,7 @@ mixin UsersApi on ApiMap {
return user; return user;
} }
Future<UserMutationResult> createUser( Future<GenericMutationResult<User?>> createUser(
final String username, final String username,
final String password, final String password,
) async { ) async {
@ -67,25 +56,26 @@ mixin UsersApi on ApiMap {
); );
final mutation = Options$Mutation$CreateUser(variables: variables); final mutation = Options$Mutation$CreateUser(variables: variables);
final response = await client.mutate$CreateUser(mutation); final response = await client.mutate$CreateUser(mutation);
return UserMutationResult( return GenericMutationResult(
success: response.parsedData?.createUser.success ?? false, success: true,
code: response.parsedData?.createUser.code ?? 500, code: response.parsedData?.createUser.code ?? 500,
message: response.parsedData?.createUser.message, message: response.parsedData?.createUser.message,
user: response.parsedData?.createUser.user != null data: response.parsedData?.createUser.user != null
? User.fromGraphQL(response.parsedData!.createUser.user!) ? User.fromGraphQL(response.parsedData!.createUser.user!)
: null, : null,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return UserMutationResult( return GenericMutationResult(
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
data: null,
); );
} }
} }
Future<GenericMutationResult> deleteUser( Future<GenericMutationResult<bool>> deleteUser(
final String username, final String username,
) async { ) async {
try { try {
@ -94,13 +84,15 @@ mixin UsersApi on ApiMap {
final mutation = Options$Mutation$DeleteUser(variables: variables); final mutation = Options$Mutation$DeleteUser(variables: variables);
final response = await client.mutate$DeleteUser(mutation); final response = await client.mutate$DeleteUser(mutation);
return GenericMutationResult( return GenericMutationResult(
success: response.parsedData?.deleteUser.success ?? false, data: response.parsedData?.deleteUser.success ?? false,
success: true,
code: response.parsedData?.deleteUser.code ?? 500, code: response.parsedData?.deleteUser.code ?? 500,
message: response.parsedData?.deleteUser.message, message: response.parsedData?.deleteUser.message,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return GenericMutationResult( return GenericMutationResult(
data: false,
success: false, success: false,
code: 500, code: 500,
message: e.toString(), message: e.toString(),
@ -108,7 +100,7 @@ mixin UsersApi on ApiMap {
} }
} }
Future<UserMutationResult> updateUser( Future<GenericMutationResult<User?>> updateUser(
final String username, final String username,
final String password, final String password,
) async { ) async {
@ -119,17 +111,18 @@ mixin UsersApi on ApiMap {
); );
final mutation = Options$Mutation$UpdateUser(variables: variables); final mutation = Options$Mutation$UpdateUser(variables: variables);
final response = await client.mutate$UpdateUser(mutation); final response = await client.mutate$UpdateUser(mutation);
return UserMutationResult( return GenericMutationResult(
success: response.parsedData?.updateUser.success ?? false, success: true,
code: response.parsedData?.updateUser.code ?? 500, code: response.parsedData?.updateUser.code ?? 500,
message: response.parsedData?.updateUser.message, message: response.parsedData?.updateUser.message,
user: response.parsedData?.updateUser.user != null data: response.parsedData?.updateUser.user != null
? User.fromGraphQL(response.parsedData!.updateUser.user!) ? User.fromGraphQL(response.parsedData!.updateUser.user!)
: null, : null,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return UserMutationResult( return GenericMutationResult(
data: null,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
@ -137,7 +130,7 @@ mixin UsersApi on ApiMap {
} }
} }
Future<UserMutationResult> addSshKey( Future<GenericMutationResult<User?>> addSshKey(
final String username, final String username,
final String sshKey, final String sshKey,
) async { ) async {
@ -151,17 +144,18 @@ mixin UsersApi on ApiMap {
); );
final mutation = Options$Mutation$AddSshKey(variables: variables); final mutation = Options$Mutation$AddSshKey(variables: variables);
final response = await client.mutate$AddSshKey(mutation); final response = await client.mutate$AddSshKey(mutation);
return UserMutationResult( return GenericMutationResult(
success: response.parsedData?.addSshKey.success ?? false, success: true,
code: response.parsedData?.addSshKey.code ?? 500, code: response.parsedData?.addSshKey.code ?? 500,
message: response.parsedData?.addSshKey.message, message: response.parsedData?.addSshKey.message,
user: response.parsedData?.addSshKey.user != null data: response.parsedData?.addSshKey.user != null
? User.fromGraphQL(response.parsedData!.addSshKey.user!) ? User.fromGraphQL(response.parsedData!.addSshKey.user!)
: null, : null,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return UserMutationResult( return GenericMutationResult(
data: null,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
@ -169,7 +163,7 @@ mixin UsersApi on ApiMap {
} }
} }
Future<UserMutationResult> removeSshKey( Future<GenericMutationResult<User?>> removeSshKey(
final String username, final String username,
final String sshKey, final String sshKey,
) async { ) async {
@ -183,17 +177,18 @@ mixin UsersApi on ApiMap {
); );
final mutation = Options$Mutation$RemoveSshKey(variables: variables); final mutation = Options$Mutation$RemoveSshKey(variables: variables);
final response = await client.mutate$RemoveSshKey(mutation); final response = await client.mutate$RemoveSshKey(mutation);
return UserMutationResult( return GenericMutationResult(
success: response.parsedData?.removeSshKey.success ?? false, success: response.parsedData?.removeSshKey.success ?? false,
code: response.parsedData?.removeSshKey.code ?? 500, code: response.parsedData?.removeSshKey.code ?? 500,
message: response.parsedData?.removeSshKey.message, message: response.parsedData?.removeSshKey.message,
user: response.parsedData?.removeSshKey.user != null data: response.parsedData?.removeSshKey.user != null
? User.fromGraphQL(response.parsedData!.removeSshKey.user!) ? User.fromGraphQL(response.parsedData!.removeSshKey.user!)
: null, : null,
); );
} catch (e) { } catch (e) {
print(e); print(e);
return UserMutationResult( return GenericMutationResult(
data: null,
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),

View File

@ -1,15 +1,5 @@
part of 'server.dart'; part of 'server.dart';
class MigrateToBindsMutationReturn extends GenericMutationResult {
MigrateToBindsMutationReturn({
required super.success,
required super.code,
super.message,
this.jobUid,
});
final String? jobUid;
}
mixin VolumeApi on ApiMap { mixin VolumeApi on ApiMap {
Future<List<ServerDiskVolume>> getServerDiskVolumes() async { Future<List<ServerDiskVolume>> getServerDiskVolumes() async {
QueryResult response; QueryResult response;
@ -67,10 +57,10 @@ mixin VolumeApi on ApiMap {
} }
} }
Future<MigrateToBindsMutationReturn> migrateToBinds( Future<GenericMutationResult<String?>> migrateToBinds(
final Map<String, String> serviceToDisk, final Map<String, String> serviceToDisk,
) async { ) async {
MigrateToBindsMutationReturn? mutation; GenericMutationResult<String?>? mutation;
try { try {
final GraphQLClient client = await getClient(); final GraphQLClient client = await getClient();
@ -88,19 +78,19 @@ mixin VolumeApi on ApiMap {
await client.mutate$MigrateToBinds( await client.mutate$MigrateToBinds(
migrateMutation, migrateMutation,
); );
mutation = mutation = MigrateToBindsMutationReturn( mutation = mutation = GenericMutationResult(
success: result.parsedData!.migrateToBinds.success, success: true,
code: result.parsedData!.migrateToBinds.code, code: result.parsedData!.migrateToBinds.code,
message: result.parsedData!.migrateToBinds.message, message: result.parsedData!.migrateToBinds.message,
jobUid: result.parsedData!.migrateToBinds.job?.uid, data: result.parsedData!.migrateToBinds.job?.uid,
); );
} catch (e) { } catch (e) {
print(e); print(e);
mutation = MigrateToBindsMutationReturn( mutation = GenericMutationResult(
success: false, success: false,
code: 0, code: 0,
message: e.toString(), message: e.toString(),
jobUid: null, data: null,
); );
} }

View File

@ -242,25 +242,18 @@ class CloudflareApi extends DnsProviderApi {
} }
@override @override
Future<void> setDkim( Future<void> setDnsRecord(
final String dkimRecordString, final DnsRecord record,
final ServerDomain domain, final ServerDomain domain,
) async { ) async {
final String domainZoneId = domain.zoneId; final String domainZoneId = domain.zoneId;
final String url = '$rootAddress/zones/$domainZoneId/dns_records'; final String url = '$rootAddress/zones/$domainZoneId/dns_records';
final DnsRecord dkimRecord = DnsRecord(
type: 'TXT',
name: 'selector._domainkey',
content: dkimRecordString,
ttl: 18000,
);
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
await client.post( await client.post(
url, url,
data: dkimRecord.toJson(), data: record.toJson(),
); );
} catch (e) { } catch (e) {
print(e); print(e);

View File

@ -19,8 +19,8 @@ abstract class DnsProviderApi extends ApiMap {
required final ServerDomain domain, required final ServerDomain domain,
final String? ip4, final String? ip4,
}); });
Future<void> setDkim( Future<void> setDnsRecord(
final String dkimRecordString, final DnsRecord record,
final ServerDomain domain, final ServerDomain domain,
); );
Future<String?> getZoneId(final String domain); Future<String?> getZoneId(final String domain);

View File

@ -35,7 +35,7 @@ class ApiDevicesCubit
} }
Future<List<ApiToken>?> _getApiTokens() async { Future<List<ApiToken>?> _getApiTokens() async {
final ApiResponse<List<ApiToken>> response = await api.getApiTokens(); final GenericResult<List<ApiToken>> response = await api.getApiTokens();
if (response.success) { if (response.success) {
return response.data; return response.data;
} else { } else {
@ -44,7 +44,7 @@ class ApiDevicesCubit
} }
Future<void> deleteDevice(final ApiToken device) async { Future<void> deleteDevice(final ApiToken device) async {
final ApiResponse<void> response = await api.deleteApiToken(device.name); final GenericResult<void> response = await api.deleteApiToken(device.name);
if (response.success) { if (response.success) {
emit( emit(
ApiDevicesState( ApiDevicesState(
@ -59,7 +59,7 @@ class ApiDevicesCubit
} }
Future<String?> getNewDeviceKey() async { Future<String?> getNewDeviceKey() async {
final ApiResponse<String> response = await api.createDeviceToken(); final GenericResult<String> response = await api.createDeviceToken();
if (response.success) { if (response.success) {
return response.data; return response.data;
} else { } else {

View File

@ -8,6 +8,7 @@ import 'package:selfprivacy/logic/models/hive/server_domain.dart';
import 'package:selfprivacy/logic/models/json/dns_records.dart'; import 'package:selfprivacy/logic/models/json/dns_records.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
import 'package:selfprivacy/utils/network_utils.dart';
part 'dns_records_state.dart'; part 'dns_records_state.dart';
@ -32,7 +33,7 @@ class DnsRecordsCubit
emit( emit(
DnsRecordsState( DnsRecordsState(
dnsState: DnsRecordsStatus.refreshing, dnsState: DnsRecordsStatus.refreshing,
dnsRecords: _getDesiredDnsRecords( dnsRecords: getDesiredDnsRecords(
serverInstallationCubit.state.serverDomain?.domainName, serverInstallationCubit.state.serverDomain?.domainName,
'', '',
'', '',
@ -48,9 +49,10 @@ class DnsRecordsCubit
final List<DnsRecord> records = await dnsProviderApiFactory! final List<DnsRecord> records = await dnsProviderApiFactory!
.getDnsProvider() .getDnsProvider()
.getDnsRecords(domain: domain); .getDnsRecords(domain: domain);
final String? dkimPublicKey = await api.getDkim(); final String? dkimPublicKey =
extractDkimRecord(await api.getDnsRecords())?.content;
final List<DesiredDnsRecord> desiredRecords = final List<DesiredDnsRecord> desiredRecords =
_getDesiredDnsRecords(domain.domainName, ipAddress, dkimPublicKey); getDesiredDnsRecords(domain.domainName, ipAddress, dkimPublicKey);
final List<DesiredDnsRecord> foundRecords = []; final List<DesiredDnsRecord> foundRecords = [];
for (final DesiredDnsRecord record in desiredRecords) { for (final DesiredDnsRecord record in desiredRecords) {
if (record.description == 'record.dkim') { if (record.description == 'record.dkim') {
@ -123,7 +125,6 @@ class DnsRecordsCubit
emit(state.copyWith(dnsState: DnsRecordsStatus.refreshing)); emit(state.copyWith(dnsState: DnsRecordsStatus.refreshing));
final ServerDomain? domain = serverInstallationCubit.state.serverDomain; final ServerDomain? domain = serverInstallationCubit.state.serverDomain;
final String? ipAddress = serverInstallationCubit.state.serverDetails?.ip4; final String? ipAddress = serverInstallationCubit.state.serverDetails?.ip4;
final String? dkimPublicKey = await api.getDkim();
final DnsProviderApi dnsProviderApi = final DnsProviderApi dnsProviderApi =
dnsProviderApiFactory!.getDnsProvider(); dnsProviderApiFactory!.getDnsProvider();
await dnsProviderApi.removeSimilarRecords(domain: domain!); await dnsProviderApi.removeSimilarRecords(domain: domain!);
@ -131,88 +132,13 @@ class DnsRecordsCubit
domain: domain, domain: domain,
ip4: ipAddress, ip4: ipAddress,
); );
await dnsProviderApi.setDkim(dkimPublicKey ?? '', domain);
final List<DnsRecord> records = await api.getDnsRecords();
final DnsRecord? dkimRecord = extractDkimRecord(records);
if (dkimRecord != null) {
await dnsProviderApi.setDnsRecord(dkimRecord, domain);
}
await load(); await load();
} }
List<DesiredDnsRecord> _getDesiredDnsRecords(
final String? domainName,
final String? ipAddress,
final String? dkimPublicKey,
) {
if (domainName == null || ipAddress == null) {
return [];
}
return [
DesiredDnsRecord(
name: domainName,
content: ipAddress,
description: 'record.root',
),
DesiredDnsRecord(
name: 'api.$domainName',
content: ipAddress,
description: 'record.api',
),
DesiredDnsRecord(
name: 'cloud.$domainName',
content: ipAddress,
description: 'record.cloud',
),
DesiredDnsRecord(
name: 'git.$domainName',
content: ipAddress,
description: 'record.git',
),
DesiredDnsRecord(
name: 'meet.$domainName',
content: ipAddress,
description: 'record.meet',
),
DesiredDnsRecord(
name: 'social.$domainName',
content: ipAddress,
description: 'record.social',
),
DesiredDnsRecord(
name: 'password.$domainName',
content: ipAddress,
description: 'record.password',
),
DesiredDnsRecord(
name: 'vpn.$domainName',
content: ipAddress,
description: 'record.vpn',
),
DesiredDnsRecord(
name: domainName,
content: domainName,
description: 'record.mx',
type: 'MX',
category: DnsRecordsCategory.email,
),
DesiredDnsRecord(
name: '_dmarc.$domainName',
content: 'v=DMARC1; p=none',
description: 'record.dmarc',
type: 'TXT',
category: DnsRecordsCategory.email,
),
DesiredDnsRecord(
name: domainName,
content: 'v=spf1 a mx ip4:$ipAddress -all',
description: 'record.spf',
type: 'TXT',
category: DnsRecordsCategory.email,
),
if (dkimPublicKey != null)
DesiredDnsRecord(
name: 'selector._domainkey.$domainName',
content: dkimPublicKey,
description: 'record.dkim',
type: 'TXT',
category: DnsRecordsCategory.email,
),
];
}
} }

View File

@ -7,12 +7,6 @@ enum DnsRecordsStatus {
error, error,
} }
enum DnsRecordsCategory {
services,
email,
other,
}
class DnsRecordsState extends ServerInstallationDependendState { class DnsRecordsState extends ServerInstallationDependendState {
const DnsRecordsState({ const DnsRecordsState({
this.dnsState = DnsRecordsStatus.uninitialized, this.dnsState = DnsRecordsStatus.uninitialized,
@ -37,38 +31,3 @@ class DnsRecordsState extends ServerInstallationDependendState {
dnsRecords: dnsRecords ?? this.dnsRecords, dnsRecords: dnsRecords ?? this.dnsRecords,
); );
} }
class DesiredDnsRecord {
const DesiredDnsRecord({
required this.name,
required this.content,
this.type = 'A',
this.description = '',
this.category = DnsRecordsCategory.services,
this.isSatisfied = false,
});
final String name;
final String type;
final String content;
final String description;
final DnsRecordsCategory category;
final bool isSatisfied;
DesiredDnsRecord copyWith({
final String? name,
final String? type,
final String? content,
final String? description,
final DnsRecordsCategory? category,
final bool? isSatisfied,
}) =>
DesiredDnsRecord(
name: name ?? this.name,
type: type ?? this.type,
content: content ?? this.content,
description: description ?? this.description,
category: category ?? this.category,
isSatisfied: isSatisfied ?? this.isSatisfied,
);
}

View File

@ -32,7 +32,7 @@ class RecoveryKeyCubit
} }
Future<RecoveryKeyStatus?> _getRecoveryKeyStatus() async { Future<RecoveryKeyStatus?> _getRecoveryKeyStatus() async {
final ApiResponse<RecoveryKeyStatus?> response = final GenericResult<RecoveryKeyStatus?> response =
await api.getRecoveryTokenStatus(); await api.getRecoveryTokenStatus();
if (response.success) { if (response.success) {
return response.data; return response.data;
@ -57,7 +57,7 @@ class RecoveryKeyCubit
final DateTime? expirationDate, final DateTime? expirationDate,
final int? numberOfUses, final int? numberOfUses,
}) async { }) async {
final ApiResponse<String> response = final GenericResult<String> response =
await api.generateRecoveryToken(expirationDate, numberOfUses); await api.generateRecoveryToken(expirationDate, numberOfUses);
if (response.success) { if (response.success) {
refresh(); refresh();

View File

@ -23,11 +23,13 @@ import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/hive/server_domain.dart'; import 'package:selfprivacy/logic/models/hive/server_domain.dart';
import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/json/device_token.dart'; import 'package:selfprivacy/logic/models/json/device_token.dart';
import 'package:selfprivacy/logic/models/json/dns_records.dart';
import 'package:selfprivacy/logic/models/message.dart'; import 'package:selfprivacy/logic/models/message.dart';
import 'package:selfprivacy/logic/models/server_basic_info.dart'; import 'package:selfprivacy/logic/models/server_basic_info.dart';
import 'package:selfprivacy/logic/models/server_type.dart'; import 'package:selfprivacy/logic/models/server_type.dart';
import 'package:selfprivacy/ui/components/action_button/action_button.dart'; import 'package:selfprivacy/ui/components/action_button/action_button.dart';
import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart'; import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart';
import 'package:selfprivacy/utils/network_utils.dart';
class IpNotFoundException implements Exception { class IpNotFoundException implements Exception {
IpNotFoundException(this.message); IpNotFoundException(this.message);
@ -301,7 +303,7 @@ class ServerInstallationRepository {
], ],
), ),
); );
} else if (e.response!.data['error']['code'] == 'resource_unavailable') { } else {
final NavigationService nav = getIt.get<NavigationService>(); final NavigationService nav = getIt.get<NavigationService>();
nav.showPopUpDialog( nav.showPopUpDialog(
BrandAlert( BrandAlert(
@ -406,15 +408,15 @@ class ServerInstallationRepository {
dnsProviderApiFactory!.getDnsProvider(); dnsProviderApiFactory!.getDnsProvider();
final ServerApi api = ServerApi(); final ServerApi api = ServerApi();
String dkimRecordString = ''; late DnsRecord record;
try { try {
dkimRecordString = (await api.getDkim())!; record = extractDkimRecord(await api.getDnsRecords())!;
} catch (e) { } catch (e) {
print(e); print(e);
rethrow; rethrow;
} }
await dnsProviderApi.setDkim(dkimRecordString, cloudFlareDomain); await dnsProviderApi.setDnsRecord(record, cloudFlareDomain);
} }
Future<bool> isHttpServerWorking() async { Future<bool> isHttpServerWorking() async {
@ -510,13 +512,13 @@ class ServerInstallationRepository {
overrideDomain: serverDomain.domainName, overrideDomain: serverDomain.domainName,
); );
final String serverIp = await getServerIpFromDomain(serverDomain); final String serverIp = await getServerIpFromDomain(serverDomain);
final ApiResponse<String> apiResponse = await serverApi.authorizeDevice( final GenericResult<String> result = await serverApi.authorizeDevice(
DeviceToken(device: await getDeviceName(), token: newDeviceKey), DeviceToken(device: await getDeviceName(), token: newDeviceKey),
); );
if (apiResponse.success) { if (result.success) {
return ServerHostingDetails( return ServerHostingDetails(
apiToken: apiResponse.data, apiToken: result.data,
volume: ServerVolume( volume: ServerVolume(
id: 0, id: 0,
name: '', name: '',
@ -533,7 +535,7 @@ class ServerInstallationRepository {
} }
throw ServerAuthorizationException( throw ServerAuthorizationException(
apiResponse.message ?? apiResponse.data, result.message ?? result.data,
); );
} }
@ -547,13 +549,13 @@ class ServerInstallationRepository {
overrideDomain: serverDomain.domainName, overrideDomain: serverDomain.domainName,
); );
final String serverIp = await getServerIpFromDomain(serverDomain); final String serverIp = await getServerIpFromDomain(serverDomain);
final ApiResponse<String> apiResponse = await serverApi.useRecoveryToken( final GenericResult<String> result = await serverApi.useRecoveryToken(
DeviceToken(device: await getDeviceName(), token: recoveryKey), DeviceToken(device: await getDeviceName(), token: recoveryKey),
); );
if (apiResponse.success) { if (result.success) {
return ServerHostingDetails( return ServerHostingDetails(
apiToken: apiResponse.data, apiToken: result.data,
volume: ServerVolume( volume: ServerVolume(
id: 0, id: 0,
name: '', name: '',
@ -570,7 +572,7 @@ class ServerInstallationRepository {
} }
throw ServerAuthorizationException( throw ServerAuthorizationException(
apiResponse.message ?? apiResponse.data, result.message ?? result.data,
); );
} }
@ -608,15 +610,15 @@ class ServerInstallationRepository {
); );
} }
} }
final ApiResponse<String> deviceAuthKey = final GenericResult<String> deviceAuthKey =
await serverApi.createDeviceToken(); await serverApi.createDeviceToken();
final ApiResponse<String> apiResponse = await serverApi.authorizeDevice( final GenericResult<String> result = await serverApi.authorizeDevice(
DeviceToken(device: await getDeviceName(), token: deviceAuthKey.data), DeviceToken(device: await getDeviceName(), token: deviceAuthKey.data),
); );
if (apiResponse.success) { if (result.success) {
return ServerHostingDetails( return ServerHostingDetails(
apiToken: apiResponse.data, apiToken: result.data,
volume: ServerVolume( volume: ServerVolume(
id: 0, id: 0,
name: '', name: '',
@ -633,7 +635,7 @@ class ServerInstallationRepository {
} }
throw ServerAuthorizationException( throw ServerAuthorizationException(
apiResponse.message ?? apiResponse.data, result.message ?? result.data,
); );
} }

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
@ -46,14 +47,14 @@ class ServerJobsCubit
Future<void> migrateToBinds(final Map<String, String> serviceToDisk) async { Future<void> migrateToBinds(final Map<String, String> serviceToDisk) async {
final result = await api.migrateToBinds(serviceToDisk); final result = await api.migrateToBinds(serviceToDisk);
if (!result.success || result.jobUid == null) { if (result.data == null) {
getIt<NavigationService>().showSnackBar(result.message!); getIt<NavigationService>().showSnackBar(result.message!);
return; return;
} }
emit( emit(
ServerJobsState( ServerJobsState(
migrationJobUid: result.jobUid, migrationJobUid: result.data,
), ),
); );
} }
@ -75,7 +76,13 @@ class ServerJobsCubit
Future<void> removeServerJob(final String uid) async { Future<void> removeServerJob(final String uid) async {
final result = await api.removeApiJob(uid); final result = await api.removeApiJob(uid);
if (!result.success) { if (!result.success) {
getIt<NavigationService>().showSnackBar(result.message!); getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
return;
}
if (!result.data) {
getIt<NavigationService>()
.showSnackBar(result.message ?? 'jobs.generic_error'.tr());
return; return;
} }
@ -87,7 +94,6 @@ class ServerJobsCubit
], ],
), ),
); );
print('removed job $uid');
} }
Future<void> removeAllFinishedJobs() async { Future<void> removeAllFinishedJobs() async {

View File

@ -1,5 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
import 'package:selfprivacy/logic/models/service.dart'; import 'package:selfprivacy/logic/models/service.dart';
@ -39,7 +41,17 @@ class ServicesCubit extends ServerInstallationDependendCubit<ServicesState> {
Future<void> restart(final String serviceId) async { Future<void> restart(final String serviceId) async {
emit(state.copyWith(lockedServices: [...state.lockedServices, serviceId])); emit(state.copyWith(lockedServices: [...state.lockedServices, serviceId]));
await api.restartService(serviceId); final result = await api.restartService(serviceId);
if (!result.success) {
getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
return;
}
if (!result.data) {
getIt<NavigationService>()
.showSnackBar(result.message ?? 'jobs.generic_error'.tr());
return;
}
await Future.delayed(const Duration(seconds: 2)); await Future.delayed(const Duration(seconds: 2));
reload(); reload();
await Future.delayed(const Duration(seconds: 10)); await Future.delayed(const Duration(seconds: 10));

View File

@ -78,17 +78,16 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
return; return;
} }
// If API returned error, do nothing // If API returned error, do nothing
final UserMutationResult result = final GenericMutationResult<User?> result =
await api.createUser(user.login, password); await api.createUser(user.login, password);
final User? createdUser = result.user; if (result.data == null) {
if (!result.success || createdUser == null) {
getIt<NavigationService>() getIt<NavigationService>()
.showSnackBar(result.message ?? 'users.could_not_create_user'.tr()); .showSnackBar(result.message ?? 'users.could_not_create_user'.tr());
return; return;
} }
final List<User> loadedUsers = List<User>.from(state.users); final List<User> loadedUsers = List<User>.from(state.users);
loadedUsers.add(createdUser); loadedUsers.add(result.data!);
await box.clear(); await box.clear();
await box.addAll(loadedUsers); await box.addAll(loadedUsers);
emit(state.copyWith(users: loadedUsers)); emit(state.copyWith(users: loadedUsers));
@ -103,14 +102,20 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
} }
final List<User> loadedUsers = List<User>.from(state.users); final List<User> loadedUsers = List<User>.from(state.users);
final GenericMutationResult result = await api.deleteUser(user.login); final GenericMutationResult result = await api.deleteUser(user.login);
if (result.success) { if (result.success && result.data) {
loadedUsers.removeWhere((final User u) => u.login == user.login); loadedUsers.removeWhere((final User u) => u.login == user.login);
await box.clear(); await box.clear();
await box.addAll(loadedUsers); await box.addAll(loadedUsers);
emit(state.copyWith(users: loadedUsers)); emit(state.copyWith(users: loadedUsers));
} else { }
if (!result.success) {
getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
}
if (!result.data) {
getIt<NavigationService>() getIt<NavigationService>()
.showSnackBar(result.message ?? 'users.could_not_delete_user'.tr()); .showSnackBar(result.message ?? 'jobs.generic_error'.tr());
} }
} }
@ -123,9 +128,9 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
.showSnackBar('users.could_not_change_password'.tr()); .showSnackBar('users.could_not_change_password'.tr());
return; return;
} }
final UserMutationResult result = final GenericMutationResult<User?> result =
await api.updateUser(user.login, newPassword); await api.updateUser(user.login, newPassword);
if (!result.success) { if (result.data == null) {
getIt<NavigationService>().showSnackBar( getIt<NavigationService>().showSnackBar(
result.message ?? 'users.could_not_change_password'.tr(), result.message ?? 'users.could_not_change_password'.tr(),
); );
@ -133,10 +138,10 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
} }
Future<void> addSshKey(final User user, final String publicKey) async { Future<void> addSshKey(final User user, final String publicKey) async {
final UserMutationResult result = final GenericMutationResult<User?> result =
await api.addSshKey(user.login, publicKey); await api.addSshKey(user.login, publicKey);
if (result.success) { if (result.data != null) {
final User updatedUser = result.user!; final User updatedUser = result.data!;
final int index = final int index =
state.users.indexWhere((final User u) => u.login == user.login); state.users.indexWhere((final User u) => u.login == user.login);
await box.putAt(index, updatedUser); await box.putAt(index, updatedUser);
@ -152,10 +157,10 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
} }
Future<void> deleteSshKey(final User user, final String publicKey) async { Future<void> deleteSshKey(final User user, final String publicKey) async {
final UserMutationResult result = final GenericMutationResult<User?> result =
await api.removeSshKey(user.login, publicKey); await api.removeSshKey(user.login, publicKey);
if (result.success) { if (result.data != null) {
final User updatedUser = result.user!; final User updatedUser = result.data!;
final int index = final int index =
state.users.indexWhere((final User u) => u.login == user.login); state.users.indexWhere((final User u) => u.login == user.login);
await box.putAt(index, updatedUser); await box.putAt(index, updatedUser);

View File

@ -1,5 +1,5 @@
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/services.graphql.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
part 'dns_records.g.dart'; part 'dns_records.g.dart';
@ -15,7 +15,7 @@ class DnsRecord {
}); });
DnsRecord.fromGraphQL( DnsRecord.fromGraphQL(
final Query$AllServices$services$allServices$dnsRecords record, final Fragment$dnsRecordFields record,
) : this( ) : this(
type: record.recordType, type: record.recordType,
name: record.name, name: record.name,

View File

@ -23,7 +23,10 @@ class Service {
// Decode the base64 encoded svg icon to text. // Decode the base64 encoded svg icon to text.
svgIcon: utf8.decode(base64.decode(service.svgIcon)), svgIcon: utf8.decode(base64.decode(service.svgIcon)),
dnsRecords: service.dnsRecords dnsRecords: service.dnsRecords
?.map((final record) => DnsRecord.fromGraphQL(record)) ?.map(
(final Fragment$dnsRecordFields record) =>
DnsRecord.fromGraphQL(record),
)
.toList() ?? .toList() ??
[], [],
url: service.url, url: service.url,

View File

@ -6,6 +6,7 @@ import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart';
import 'package:selfprivacy/ui/components/brand_cards/filled_card.dart'; import 'package:selfprivacy/ui/components/brand_cards/filled_card.dart';
import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart';
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
import 'package:selfprivacy/utils/network_utils.dart';
class DnsDetailsPage extends StatefulWidget { class DnsDetailsPage extends StatefulWidget {
const DnsDetailsPage({super.key}); const DnsDetailsPage({super.key});

View File

@ -0,0 +1,135 @@
import 'package:selfprivacy/logic/models/json/dns_records.dart';
enum DnsRecordsCategory {
services,
email,
other,
}
class DesiredDnsRecord {
const DesiredDnsRecord({
required this.name,
required this.content,
this.type = 'A',
this.description = '',
this.category = DnsRecordsCategory.services,
this.isSatisfied = false,
});
final String name;
final String type;
final String content;
final String description;
final DnsRecordsCategory category;
final bool isSatisfied;
DesiredDnsRecord copyWith({
final String? name,
final String? type,
final String? content,
final String? description,
final DnsRecordsCategory? category,
final bool? isSatisfied,
}) =>
DesiredDnsRecord(
name: name ?? this.name,
type: type ?? this.type,
content: content ?? this.content,
description: description ?? this.description,
category: category ?? this.category,
isSatisfied: isSatisfied ?? this.isSatisfied,
);
}
List<DesiredDnsRecord> getDesiredDnsRecords(
final String? domainName,
final String? ipAddress,
final String? dkimPublicKey,
) {
if (domainName == null || ipAddress == null) {
return [];
}
return [
DesiredDnsRecord(
name: domainName,
content: ipAddress,
description: 'record.root',
),
DesiredDnsRecord(
name: 'api.$domainName',
content: ipAddress,
description: 'record.api',
),
DesiredDnsRecord(
name: 'cloud.$domainName',
content: ipAddress,
description: 'record.cloud',
),
DesiredDnsRecord(
name: 'git.$domainName',
content: ipAddress,
description: 'record.git',
),
DesiredDnsRecord(
name: 'meet.$domainName',
content: ipAddress,
description: 'record.meet',
),
DesiredDnsRecord(
name: 'social.$domainName',
content: ipAddress,
description: 'record.social',
),
DesiredDnsRecord(
name: 'password.$domainName',
content: ipAddress,
description: 'record.password',
),
DesiredDnsRecord(
name: 'vpn.$domainName',
content: ipAddress,
description: 'record.vpn',
),
DesiredDnsRecord(
name: domainName,
content: domainName,
description: 'record.mx',
type: 'MX',
category: DnsRecordsCategory.email,
),
DesiredDnsRecord(
name: '_dmarc.$domainName',
content: 'v=DMARC1; p=none',
description: 'record.dmarc',
type: 'TXT',
category: DnsRecordsCategory.email,
),
DesiredDnsRecord(
name: domainName,
content: 'v=spf1 a mx ip4:$ipAddress -all',
description: 'record.spf',
type: 'TXT',
category: DnsRecordsCategory.email,
),
if (dkimPublicKey != null)
DesiredDnsRecord(
name: 'selector._domainkey.$domainName',
content: dkimPublicKey,
description: 'record.dkim',
type: 'TXT',
category: DnsRecordsCategory.email,
),
];
}
DnsRecord? extractDkimRecord(final List<DnsRecord> records) {
DnsRecord? dkimRecord;
for (final DnsRecord record in records) {
if (record.type == 'TXT' && record.name == 'selector._domainkey') {
dkimRecord = record;
}
}
return dkimRecord;
}