mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-07 00:24:18 +00:00
Merge pull request 'Release 0.7.0' (#116) from graphql into master
Reviewed-on: https://git.selfprivacy.org/kherel/selfprivacy.org.app/pulls/116 Reviewed-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
commit
81c97e5249
|
@ -13,6 +13,7 @@ analyzer:
|
||||||
exclude:
|
exclude:
|
||||||
- lib/generated_plugin_registrant.dart
|
- lib/generated_plugin_registrant.dart
|
||||||
- lib/**.g.dart
|
- lib/**.g.dart
|
||||||
|
- lib/**.graphql.dart
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
# The lint rules applied to this project can be customized in the
|
# The lint rules applied to this project can be customized in the
|
||||||
|
|
|
@ -26,7 +26,9 @@ apply plugin: 'kotlin-android'
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion flutter.compileSdkVersion
|
namespace 'org.selfprivacy.app'
|
||||||
|
|
||||||
|
compileSdkVersion flutter.compileSdkVersion
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
@ -48,7 +50,7 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "pro.kherel.selfprivacy"
|
applicationId "org.selfprivacy.app"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 31
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
|
@ -62,6 +64,21 @@ android {
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flavorDimensions "default"
|
||||||
|
productFlavors {
|
||||||
|
fdroid {
|
||||||
|
applicationId "pro.kherel.selfprivacy"
|
||||||
|
}
|
||||||
|
production {
|
||||||
|
applicationIdSuffix ""
|
||||||
|
}
|
||||||
|
nightly {
|
||||||
|
applicationIdSuffix ".nightly"
|
||||||
|
versionCode project.getVersionCode()
|
||||||
|
versionName "nightly-" + project.getVersionCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="pro.kherel.selfprivacy">
|
package="org.selfprivacy.app">
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="pro.kherel.selfprivacy">
|
package="org.selfprivacy.app">
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package pro.kherel.selfprivacy
|
package org.selfprivacy.app
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="pro.kherel.selfprivacy">
|
package="org.selfprivacy.app">
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.6.10'
|
ext.kotlin_version = '1.6.10'
|
||||||
|
ext.getVersionCode = { ->
|
||||||
|
try {
|
||||||
|
def stdout = new ByteArrayOutputStream()
|
||||||
|
exec {
|
||||||
|
commandLine 'git', 'rev-list', '--first-parent', '--count', 'origin/master'
|
||||||
|
standardOutput = stdout
|
||||||
|
}
|
||||||
|
return Integer.parseInt(stdout.toString().trim())
|
||||||
|
}
|
||||||
|
catch (ignored) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
android.enableR8=true
|
|
||||||
|
|
BIN
assets/images/pics/myprofile.png
Normal file
BIN
assets/images/pics/myprofile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
assets/images/pics/permissions.png
Normal file
BIN
assets/images/pics/permissions.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -1,11 +1,14 @@
|
||||||
### Как получить Cloudflare API Token
|
### Как получить Cloudflare API Token
|
||||||
1. Переходим по [ссылке](https://dash.cloudflare.com/) и авторизуемся в ранее созданном аккаунте. https://dash.cloudflare.com/
|
1. Переходим по [ссылке](https://dash.cloudflare.com/) и авторизуемся в ранее созданном аккаунте. https://dash.cloudflare.com/
|
||||||
В правом углу кликаем на иконку профиля (человечек в кружочке). Для мобильной версии сайта, в верхнем левом углу, нажимаем кнопку **Меню** (три горизонтальных полоски), в выпавшем меню, ищем пункт **My Profile**.
|
2. В правом верхнем углу кликаем на иконку профиля (для мобильной версии сайта: в верхнем левом углу нажимаем кнопку **Меню** с тремя горизонтальными полосками). В выпавшем меню кликаем на пункт **My Profile**.
|
||||||
|
![My profile](resource:assets/images/pics/myprofile.png)
|
||||||
3. Нам предлагается на выбор, четыре категории настройки: **Preferences**, **Authentication**, **API Tokens**, **Sessions**. Выбираем **API Tokens**.
|
3. Нам предлагается на выбор, четыре категории настройки: **Preferences**, **Authentication**, **API Tokens**, **Sessions**. Выбираем **API Tokens**.
|
||||||
4. Самым первым пунктом видим кнопку **Create Token**. С полной уверенностью в себе и желанием обрести приватность, нажимаем на неё.
|
4. Самым первым пунктом видим кнопку **Create Token**. С полной уверенностью в себе и желанием обрести приватность, нажимаем на неё.
|
||||||
5. Спускаемся в самый низ и видим поле **Create Custom Token** и кнопку **Get Started** с правой стороны. Нажимаем.
|
5. Спускаемся в самый низ и видим поле **Create Custom Token** и кнопку **Get Started** с правой стороны. Нажимаем.
|
||||||
6. В поле **Token Name** даём своему токену имя. Можете покреативить и отнестись к этому как к наименованию домашнего зверька :)
|
6. В поле **Token Name** даём своему токену имя. Можете покреативить и отнестись к этому как к наименованию домашнего зверька :)
|
||||||
7. Далее, у нас **Permissions**. В первом поле выбираем Zone. Во втором поле, по центру, выбираем **DNS**. В последнем поле выбираем **Edit**.
|
7. Далее, у нас **Permissions**. В первом поле выбираем **Zone**. Во втором поле, по центру, выбираем **DNS**. В последнем поле выбираем **Edit**.
|
||||||
|
8. Нажимаем на синюю надпись снизу **+ Add more** (сразу же под левым полем которое мы заполняли ранее). Вуаля, у нас появились новые поля. Заполняем по аналогии с предыдущим пунктом, в первом поле выбираем **Zone**, во-втором тоже **Zone**. А уже в третьем нажимаем на **Read**. Давайте сверим с тем, что у вас получилось:
|
||||||
|
![Permissions](resource:assets/images/pics/permissions.png)
|
||||||
8. Далее смотрим на **Zone Resources**. Под этой надписью есть строка с двумя полями. В первом должно быть **Include**, а во втором — **Specific Zone**. Как только Вы выберите **Specific Zone**, справа появится ещё одно поле. В нём выбираем наш домен.
|
8. Далее смотрим на **Zone Resources**. Под этой надписью есть строка с двумя полями. В первом должно быть **Include**, а во втором — **Specific Zone**. Как только Вы выберите **Specific Zone**, справа появится ещё одно поле. В нём выбираем наш домен.
|
||||||
9. Листаем в самый низ и нажимаем на синюю кнопку **Continue to Summary**.
|
9. Листаем в самый низ и нажимаем на синюю кнопку **Continue to Summary**.
|
||||||
10. Проверяем, всё ли мы правильно выбрали. Должна присутствовать подобная строка: ваш.домен — **DNS:Edit, Zone:Read**.
|
10. Проверяем, всё ли мы правильно выбрали. Должна присутствовать подобная строка: ваш.домен — **DNS:Edit, Zone:Read**.
|
||||||
|
|
|
@ -52,7 +52,8 @@
|
||||||
"copied_ssh": "SSH copied to clipboard",
|
"copied_ssh": "SSH copied to clipboard",
|
||||||
"delete_ssh_text": "Delete SSH key?",
|
"delete_ssh_text": "Delete SSH key?",
|
||||||
"about_app_page": {
|
"about_app_page": {
|
||||||
"text": "Application version v.{}"
|
"application_version_text": "Application version v.{}",
|
||||||
|
"api_version_text": "Server API version v.{}"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "Application settings",
|
"title": "Application settings",
|
||||||
|
@ -99,7 +100,33 @@
|
||||||
"chart": {
|
"chart": {
|
||||||
"month": "Month",
|
"month": "Month",
|
||||||
"day": "Day",
|
"day": "Day",
|
||||||
"hour": "Hour"
|
"hour": "Hour",
|
||||||
|
"cpu_title": "CPU Usage",
|
||||||
|
"network_title": "Network Usage",
|
||||||
|
"in": "In",
|
||||||
|
"out": "Out"
|
||||||
|
},
|
||||||
|
"resource_usage": "Resource usage",
|
||||||
|
"settings": {
|
||||||
|
"allow_autoupgrade": "Allow auto-upgrade",
|
||||||
|
"allow_autoupgrade_hint": "Allow automatic packages upgrades on server",
|
||||||
|
"reboot_after_upgrade": "Reboot after upgrade",
|
||||||
|
"reboot_after_upgrade_hint": "Reboot without prompt after applying changes on server",
|
||||||
|
"server_timezone": "Server timezone",
|
||||||
|
"select_timezone": "Select timezone"
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"server_id": "Server ID",
|
||||||
|
"status": "Status",
|
||||||
|
"cpu": "CPU",
|
||||||
|
"ram": "Memory",
|
||||||
|
"disk": "Disk local",
|
||||||
|
"monthly_cost": "Monthly cost",
|
||||||
|
"location": "Location",
|
||||||
|
"core_count": {
|
||||||
|
"one": "{} core",
|
||||||
|
"other": "{} cores"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"domain": {
|
"domain": {
|
||||||
|
@ -162,6 +189,28 @@
|
||||||
"refresh": "Refresh status",
|
"refresh": "Refresh status",
|
||||||
"refetchBackups": "Refetch backup list",
|
"refetchBackups": "Refetch backup list",
|
||||||
"refetchingList": "In a few minutes list will be updated"
|
"refetchingList": "In a few minutes list will be updated"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"card_title": "Server Storage",
|
||||||
|
"status_ok": "Disk usage is OK",
|
||||||
|
"status_error": "Low disk space",
|
||||||
|
"disk_usage": "{} used",
|
||||||
|
"disk_total": "{} total · {}",
|
||||||
|
"gb": "{} GB",
|
||||||
|
"mb": "{} MB",
|
||||||
|
"kb": "{} KB",
|
||||||
|
"extend_volume_button": "Extend volume",
|
||||||
|
"extending_volume_title": "Extending volume",
|
||||||
|
"extending_volume_description": "Resizing volume will allow you to store more data on your server without extending the server itself. Volume can only be extended: shrinking is not possible.",
|
||||||
|
"extending_volume_price_info": "Price includes VAT and is estimated from pricing data provided by Hetzner. Server will be rebooted after resizing.",
|
||||||
|
"extending_volume_error": "Couldn't initialize volume extending.",
|
||||||
|
"size": "Size",
|
||||||
|
"euro": "Euro",
|
||||||
|
"data_migration_title": "Data migration",
|
||||||
|
"data_migration_notice": "During migration all services will be turned off.",
|
||||||
|
"start_migration_button": "Start migration",
|
||||||
|
"migration_process": "Migrating...",
|
||||||
|
"migration_done": "Finish"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"not_ready_card": {
|
"not_ready_card": {
|
||||||
|
@ -172,8 +221,16 @@
|
||||||
"in_menu": "Server is not set up yet. Please finish setup using setup wizard for further work."
|
"in_menu": "Server is not set up yet. Please finish setup using setup wizard for further work."
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"_comment": "Вкладка сервисы",
|
"_comment": "Services",
|
||||||
"title": "Your personal, private and independent services.",
|
"title": "Your personal, private and independent services.",
|
||||||
|
"service_page": {
|
||||||
|
"open_in_browser": "Open in browser",
|
||||||
|
"restart": "Restart service",
|
||||||
|
"disable": "Disable service",
|
||||||
|
"enable": "Enable service",
|
||||||
|
"move": "Move to another volume",
|
||||||
|
"uses": "Uses {usage} on {volume}"
|
||||||
|
},
|
||||||
"mail": {
|
"mail": {
|
||||||
"title": "E-Mail",
|
"title": "E-Mail",
|
||||||
"subtitle": "E-Mail for company and family.",
|
"subtitle": "E-Mail for company and family.",
|
||||||
|
@ -237,12 +294,22 @@
|
||||||
"bottom_sheet": {
|
"bottom_sheet": {
|
||||||
"1": "Openconnect VPN Server. Engine for secure and scalable VPN infrastructure"
|
"1": "Openconnect VPN Server. Engine for secure and scalable VPN infrastructure"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
"up_and_running": "Up and running",
|
||||||
|
"resource_usage": "Resource usage",
|
||||||
|
"disk_used": "{} of disk space used",
|
||||||
|
"users": "Users",
|
||||||
|
"controlled_by": "Controlled by {}",
|
||||||
|
"apps": "Apps",
|
||||||
|
"settings": "Settings and maintenance"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"_comment": "'Users' tab",
|
"_comment": "'Users' tab",
|
||||||
"add_new_user": "Add a first user",
|
"add_new_user": "Add a first user",
|
||||||
"new_user": "New user",
|
"new_user": "New user",
|
||||||
|
"delete_user": "Delete user",
|
||||||
"not_ready": "Please connect server, domain and DNS in the Providers tab, to be able to add a first user",
|
"not_ready": "Please connect server, domain and DNS in the Providers tab, to be able to add a first user",
|
||||||
"nobody_here": "Nobody here",
|
"nobody_here": "Nobody here",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
|
@ -252,13 +319,24 @@
|
||||||
"delete_confirm_question": "Are you sure?",
|
"delete_confirm_question": "Are you sure?",
|
||||||
"reset_password": "Reset password",
|
"reset_password": "Reset password",
|
||||||
"account": "Account",
|
"account": "Account",
|
||||||
"send_registration_data": "Share login credentials"
|
"send_registration_data": "Share login credentials",
|
||||||
|
"could_not_fetch_users": "Couldn't fetch users list",
|
||||||
|
"could_not_fetch_description": "Please check your internet connection and try again",
|
||||||
|
"refresh_users": "Refresh users list",
|
||||||
|
"could_not_create_user": "Couldn't create user",
|
||||||
|
"could_not_delete_user": "Couldn't delete user",
|
||||||
|
"could_not_add_ssh_key": "Couldn't add SSH key",
|
||||||
|
"email_login": "Email login",
|
||||||
|
"no_sso_notice": "Only email and SSH accounts are created for this user. Single Sign On for all services is coming soon."
|
||||||
},
|
},
|
||||||
"initializing": {
|
"initializing": {
|
||||||
"_comment": "initializing page",
|
"_comment": "initializing page",
|
||||||
"1": "Connect a server",
|
"1": "Connect a server",
|
||||||
"2": "A place where your data and SelfPrivacy services will reside:",
|
"2": "A place where your data and SelfPrivacy services will reside:",
|
||||||
"how": "How to obtain API token",
|
"how": "How to obtain API token",
|
||||||
|
"hetzner_bad_key_error": "Hetzner API key is invalid",
|
||||||
|
"cloudflare_bad_key_error": "Cloudflare API key is invalid",
|
||||||
|
"backblaze_bad_key_error": "Backblaze storage information is invalid",
|
||||||
"3": "Connect CloudFlare",
|
"3": "Connect CloudFlare",
|
||||||
"4": "To manage your domain's DNS",
|
"4": "To manage your domain's DNS",
|
||||||
"5": "CloudFlare API Token",
|
"5": "CloudFlare API Token",
|
||||||
|
@ -275,13 +353,14 @@
|
||||||
"15": "Server created. DNS checks and server boot in progress...",
|
"15": "Server created. DNS checks and server boot in progress...",
|
||||||
"16": "Until the next check: ",
|
"16": "Until the next check: ",
|
||||||
"17": "Check",
|
"17": "Check",
|
||||||
|
"18": "How to obtain Hetzner API Token:'",
|
||||||
"19": "1 Go via this link ",
|
"19": "1 Go via this link ",
|
||||||
"20": "\n",
|
"20": "\n",
|
||||||
"21": "One more restart to apply your security certificates.",
|
"21": "One more restart to apply your security certificates.",
|
||||||
"22": "Create master account",
|
"22": "Create master account",
|
||||||
"23": "Enter a nickname and strong password",
|
"23": "Enter a nickname and strong password",
|
||||||
"finish": "Everything is initialized",
|
"finish": "Everything is initialized",
|
||||||
"checks": "Checks have been completed \n{} ouf of {}"
|
"checks": "Checks have been completed \n{} out of {}"
|
||||||
},
|
},
|
||||||
"recovering": {
|
"recovering": {
|
||||||
"recovery_main_header": "Connect to an existing server",
|
"recovery_main_header": "Connect to an existing server",
|
||||||
|
@ -373,8 +452,10 @@
|
||||||
},
|
},
|
||||||
"modals": {
|
"modals": {
|
||||||
"_comment": "messages in modals",
|
"_comment": "messages in modals",
|
||||||
"1": "Server with such name, already exist",
|
"1": "Server with such name, already exist.",
|
||||||
|
"1_1": "Unexpected error during placement from the provider side.",
|
||||||
"2": "Destroy server and create a new one?",
|
"2": "Destroy server and create a new one?",
|
||||||
|
"2_2": "Try again?",
|
||||||
"3": "Are you sure?",
|
"3": "Are you sure?",
|
||||||
"4": "Purge all authentication keys?",
|
"4": "Purge all authentication keys?",
|
||||||
"5": "Yes, purge all my tokens",
|
"5": "Yes, purge all my tokens",
|
||||||
|
@ -408,7 +489,9 @@
|
||||||
"upgradeServer": "Upgrade server",
|
"upgradeServer": "Upgrade server",
|
||||||
"rebootServer": "Reboot server",
|
"rebootServer": "Reboot server",
|
||||||
"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",
|
||||||
|
"resetUserPassword": "Reset password of user"
|
||||||
},
|
},
|
||||||
"validations": {
|
"validations": {
|
||||||
"required": "Required.",
|
"required": "Required.",
|
||||||
|
|
|
@ -52,7 +52,8 @@
|
||||||
"copied_ssh": "SSH ключ cкопирован в буфер",
|
"copied_ssh": "SSH ключ cкопирован в буфер",
|
||||||
"delete_ssh_text": "Удалить SSH ключ?",
|
"delete_ssh_text": "Удалить SSH ключ?",
|
||||||
"about_app_page": {
|
"about_app_page": {
|
||||||
"text": "Версия приложения: v.{}"
|
"application_version_text": "Версия приложения v.{}",
|
||||||
|
"api_version_text": "Версия API сервера v.{}"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "Настройки приложения",
|
"title": "Настройки приложения",
|
||||||
|
@ -99,7 +100,35 @@
|
||||||
"chart": {
|
"chart": {
|
||||||
"month": "Месяц",
|
"month": "Месяц",
|
||||||
"day": "День",
|
"day": "День",
|
||||||
"hour": "Час"
|
"hour": "Час",
|
||||||
|
"cpu_title": "Использование процессора",
|
||||||
|
"network_title": "Использование сети",
|
||||||
|
"in": "Получено",
|
||||||
|
"out": "Отправлено"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"allow_autoupgrade": "Разрешить авто-обноления",
|
||||||
|
"allow_autoupgrade_hint": "Разрешить автоматичесую установку обновлений на сервер",
|
||||||
|
"reboot_after_upgrade": "Перезагружать после обновлений",
|
||||||
|
"reboot_after_upgrade_hint": "Автоматически перезагружать сервер после применения обновлений",
|
||||||
|
"server_timezone": "Часовой пояс сервера",
|
||||||
|
"select_timezone": "Выберите часовой пояс"
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"server_id": "ID сервера",
|
||||||
|
"status": "Статус",
|
||||||
|
"cpu": "Процессор",
|
||||||
|
"ram": "Операивная память",
|
||||||
|
"disk": "Диск",
|
||||||
|
"monthly_cost": "Ежемесячная стоимость",
|
||||||
|
"location": "Размещение",
|
||||||
|
"core_count": {
|
||||||
|
"one": "{} ядро",
|
||||||
|
"two": "{} ядра",
|
||||||
|
"few": "{} ядра",
|
||||||
|
"many": "{} ядер",
|
||||||
|
"other": "{} ядер"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"domain": {
|
"domain": {
|
||||||
|
@ -162,7 +191,28 @@
|
||||||
"refresh": "Обновить статус",
|
"refresh": "Обновить статус",
|
||||||
"refetchBackups": "Обновить список копий",
|
"refetchBackups": "Обновить список копий",
|
||||||
"refetchingList": "Через несколько минут список будет обновлён"
|
"refetchingList": "Через несколько минут список будет обновлён"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"card_title": "Хранилище",
|
||||||
|
"status_ok": "Проблем на диске не обнаружено",
|
||||||
|
"status_error": "Заканчивается место на диске",
|
||||||
|
"disk_usage": "{} использовано",
|
||||||
|
"disk_total": "{} всего · {}",
|
||||||
|
"gb": "{} GB",
|
||||||
|
"mb": "{} MB",
|
||||||
|
"kb": "{} KB",
|
||||||
|
"extend_volume_button": "Расширить хранилище",
|
||||||
|
"extending_volume_title": "Расширение хранилища",
|
||||||
|
"extending_volume_description": "Изменение размера хранилища позволит вам держать больше данных на вашем сервере без расширения самого сервера. Объем можно только увеличить: уменьшить нельзя.",
|
||||||
|
"extending_volume_price_info": "Цена включает НДС и рассчитана на основе данных о ценах, предоставленных Hetzner. Сервер будет перезагружен во время процесса.",
|
||||||
|
"extending_volume_error": "Не удалось начать расширение хранилища.",
|
||||||
|
"size": "Размер",
|
||||||
|
"euro": "Евро",
|
||||||
|
"data_migration_title": "Миграция данных",
|
||||||
|
"data_migration_notice": "На время миграции данных все сервисы будут выключены.",
|
||||||
|
"start_migration_button": "Начать миграцию",
|
||||||
|
"migration_process": "Мигрируем...",
|
||||||
|
"migration_done": "Завершить"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"not_ready_card": {
|
"not_ready_card": {
|
||||||
|
@ -175,6 +225,14 @@
|
||||||
"services": {
|
"services": {
|
||||||
"_comment": "Вкладка сервисы",
|
"_comment": "Вкладка сервисы",
|
||||||
"title": "Ваши личные, приватные и независимые сервисы:",
|
"title": "Ваши личные, приватные и независимые сервисы:",
|
||||||
|
"service_page": {
|
||||||
|
"open_in_browser": "Открыть в браузере",
|
||||||
|
"restart": "Перезапустить сервис",
|
||||||
|
"disable": "Выключить сервис",
|
||||||
|
"enable": "Включить сервис",
|
||||||
|
"move": "Переместить на другой диск",
|
||||||
|
"uses": "Использует {usage} на {volume}"
|
||||||
|
},
|
||||||
"mail": {
|
"mail": {
|
||||||
"title": "Почта",
|
"title": "Почта",
|
||||||
"subtitle": "Электронная почта для семьи или компании.",
|
"subtitle": "Электронная почта для семьи или компании.",
|
||||||
|
@ -238,6 +296,15 @@
|
||||||
"bottom_sheet": {
|
"bottom_sheet": {
|
||||||
"1": "Создать подключиться к VPN-серверу. Движок для безопасной и масштабируемой инфраструктуры VPN"
|
"1": "Создать подключиться к VPN-серверу. Движок для безопасной и масштабируемой инфраструктуры VPN"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
"up_and_running": "Запущен и работает",
|
||||||
|
"resource_usage": "Потребление ресурсов",
|
||||||
|
"disk_used": "{} использовано места на диске",
|
||||||
|
"users": "Пользователи",
|
||||||
|
"controlled_by": "Контролируется {}",
|
||||||
|
"apps": "Приложения",
|
||||||
|
"settings": "Настройки"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
|
@ -260,6 +327,9 @@
|
||||||
"1": "Подключите сервер",
|
"1": "Подключите сервер",
|
||||||
"2": "Здесь будут жить наши данные и SelfPrivacy-сервисы",
|
"2": "Здесь будут жить наши данные и SelfPrivacy-сервисы",
|
||||||
"how": "Как получить API Token",
|
"how": "Как получить API Token",
|
||||||
|
"hetzner_bad_key_error": "Hetzner API ключ неверен",
|
||||||
|
"cloudflare_bad_key_error": "Cloudflare API ключ неверен",
|
||||||
|
"backblaze_bad_key_error": "Информация о Backblaze хранилище неверна",
|
||||||
"3": "Подключите CloudFlare",
|
"3": "Подключите CloudFlare",
|
||||||
"4": "Для управления DNS вашего домена",
|
"4": "Для управления DNS вашего домена",
|
||||||
"5": "CloudFlare API Token",
|
"5": "CloudFlare API Token",
|
||||||
|
@ -318,6 +388,10 @@
|
||||||
"domain_not_available_on_token": "Введённый токен не имеет доступа к нужному домену.",
|
"domain_not_available_on_token": "Введённый токен не имеет доступа к нужному домену.",
|
||||||
"modal_confirmation_title": "Это действительно ваш сервер?",
|
"modal_confirmation_title": "Это действительно ваш сервер?",
|
||||||
"modal_confirmation_description": "Подключение к неправильному серверу может привести к деструктивным последствиям.",
|
"modal_confirmation_description": "Подключение к неправильному серверу может привести к деструктивным последствиям.",
|
||||||
|
"modal_confirmation_dns_valid": "Обратный DNS корректен",
|
||||||
|
"modal_confirmation_dns_invalid": "Обратный DNS указывает на другой домен",
|
||||||
|
"modal_confirmation_ip_valid": "IP совпадает с указанным в DNS записи",
|
||||||
|
"modal_confirmation_ip_invalid": "IP не совпадает с указанным в DNS записи",
|
||||||
"confirm_cloudflare": "Подключение к Cloudflare",
|
"confirm_cloudflare": "Подключение к Cloudflare",
|
||||||
"confirm_cloudflare_description": "Введите токен Cloudflare, который имеет права на {}:",
|
"confirm_cloudflare_description": "Введите токен Cloudflare, который имеет права на {}:",
|
||||||
"confirm_backblze": "Подключение к Backblaze",
|
"confirm_backblze": "Подключение к Backblaze",
|
||||||
|
@ -371,8 +445,10 @@
|
||||||
},
|
},
|
||||||
"modals": {
|
"modals": {
|
||||||
"_comment": "messages in modals",
|
"_comment": "messages in modals",
|
||||||
"1": "Сервер с таким именем уже существует",
|
"1": "Сервер с таким именем уже существует.",
|
||||||
|
"1.1": "Непредвиденная ошибка при создании со стороны провайдера.",
|
||||||
"2": "Уничтожить сервер и создать новый?",
|
"2": "Уничтожить сервер и создать новый?",
|
||||||
|
"2.2": "Попробовать ещё раз?",
|
||||||
"3": "Подтвердите",
|
"3": "Подтвердите",
|
||||||
"4": "Сбросить все ключи?",
|
"4": "Сбросить все ключи?",
|
||||||
"5": "Да, сбросить",
|
"5": "Да, сбросить",
|
||||||
|
@ -406,7 +482,9 @@
|
||||||
"upgradeServer": "Обновить сервер",
|
"upgradeServer": "Обновить сервер",
|
||||||
"rebootServer": "Перезагрузить сервер",
|
"rebootServer": "Перезагрузить сервер",
|
||||||
"create_ssh_key": "Создать SSH ключ для {}",
|
"create_ssh_key": "Создать SSH ключ для {}",
|
||||||
"delete_ssh_key": "Удалить SSH ключ для {}"
|
"delete_ssh_key": "Удалить SSH ключ для {}",
|
||||||
|
"server_jobs": "Задачи на сервере",
|
||||||
|
"resetUserPassword": "Сбросить пароль пользователя"
|
||||||
},
|
},
|
||||||
"validations": {
|
"validations": {
|
||||||
"required": "Обязательное поле.",
|
"required": "Обязательное поле.",
|
||||||
|
|
12
build.yaml
12
build.yaml
|
@ -1,7 +1,17 @@
|
||||||
targets:
|
targets:
|
||||||
$default:
|
$default:
|
||||||
builders:
|
builders:
|
||||||
|
graphql_codegen:
|
||||||
|
options:
|
||||||
|
scalars:
|
||||||
|
DateTime:
|
||||||
|
type: DateTime
|
||||||
|
fromJsonFunctionName: dateTimeFromJson
|
||||||
|
toJsonFunctionName: dateTimeToJson
|
||||||
|
import: package:selfprivacy/utils/scalars.dart
|
||||||
|
clients:
|
||||||
|
- graphql
|
||||||
json_serializable:
|
json_serializable:
|
||||||
options:
|
options:
|
||||||
create_factory: true
|
create_factory: true
|
||||||
create_to_json: false
|
create_to_json: true
|
||||||
|
|
3
fastlane/metadata/android/en-US/changelogs/0.6.1.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/0.6.1.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
- Fixed routing errors and broken "back" buttons on recovery stages
|
||||||
|
- Fixed broken validation on api token fields
|
||||||
|
- Minor improvements
|
9
fastlane/metadata/android/en-US/changelogs/0.7.0.txt
Normal file
9
fastlane/metadata/android/en-US/changelogs/0.7.0.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
- Server storage management
|
||||||
|
- New screen for service management
|
||||||
|
- New users management screen
|
||||||
|
- User passwords can be changed
|
||||||
|
- Server auto upgrade settings can be changed now
|
||||||
|
- Server timezone can be changed
|
||||||
|
- Fixed bugs related to users list synchronization
|
||||||
|
- UI fixes
|
||||||
|
- Minor bug fixes
|
|
@ -2,14 +2,18 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/devices/devices_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/devices/devices_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/recovery_key/recovery_key_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/recovery_key/recovery_key_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
|
||||||
|
|
||||||
class BlocAndProviderConfig extends StatelessWidget {
|
class BlocAndProviderConfig extends StatelessWidget {
|
||||||
const BlocAndProviderConfig({final super.key, this.child});
|
const BlocAndProviderConfig({final super.key, this.child});
|
||||||
|
@ -26,6 +30,12 @@ class BlocAndProviderConfig extends StatelessWidget {
|
||||||
final dnsRecordsCubit = DnsRecordsCubit(serverInstallationCubit);
|
final dnsRecordsCubit = DnsRecordsCubit(serverInstallationCubit);
|
||||||
final recoveryKeyCubit = RecoveryKeyCubit(serverInstallationCubit);
|
final recoveryKeyCubit = RecoveryKeyCubit(serverInstallationCubit);
|
||||||
final apiDevicesCubit = ApiDevicesCubit(serverInstallationCubit);
|
final apiDevicesCubit = ApiDevicesCubit(serverInstallationCubit);
|
||||||
|
final apiVolumesCubit = ApiProviderVolumeCubit(serverInstallationCubit);
|
||||||
|
final apiServerVolumesCubit =
|
||||||
|
ApiServerVolumeCubit(serverInstallationCubit, apiVolumesCubit);
|
||||||
|
final serverJobsCubit = ServerJobsCubit(serverInstallationCubit);
|
||||||
|
final serverDetailsCubit = ServerDetailsCubit(serverInstallationCubit);
|
||||||
|
|
||||||
return MultiProvider(
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
|
@ -38,7 +48,9 @@ class BlocAndProviderConfig extends StatelessWidget {
|
||||||
create: (final _) => serverInstallationCubit,
|
create: (final _) => serverInstallationCubit,
|
||||||
lazy: false,
|
lazy: false,
|
||||||
),
|
),
|
||||||
BlocProvider(create: (final _) => ProvidersCubit()),
|
BlocProvider(
|
||||||
|
create: (final _) => ProvidersCubit(),
|
||||||
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (final _) => usersCubit..load(),
|
create: (final _) => usersCubit..load(),
|
||||||
lazy: false,
|
lazy: false,
|
||||||
|
@ -61,8 +73,22 @@ class BlocAndProviderConfig extends StatelessWidget {
|
||||||
create: (final _) => apiDevicesCubit..load(),
|
create: (final _) => apiDevicesCubit..load(),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (final _) =>
|
create: (final _) => apiVolumesCubit..load(),
|
||||||
JobsCubit(usersCubit: usersCubit, servicesCubit: servicesCubit),
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (final _) => apiServerVolumesCubit..load(),
|
||||||
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (final _) => serverJobsCubit..load(),
|
||||||
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (final _) => serverDetailsCubit..load(),
|
||||||
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (final _) => JobsCubit(
|
||||||
|
usersCubit: usersCubit,
|
||||||
|
servicesCubit: servicesCubit,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: child,
|
child: child,
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:selfprivacy/ui/components/error/error.dart';
|
|
||||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
|
||||||
|
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
|
||||||
|
@ -14,15 +11,8 @@ class SimpleBlocObserver extends BlocObserver {
|
||||||
final Object error,
|
final Object error,
|
||||||
final StackTrace stackTrace,
|
final StackTrace stackTrace,
|
||||||
) {
|
) {
|
||||||
final NavigatorState navigator = getIt.get<NavigationService>().navigator!;
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Bloc error: ${error.toString()}',
|
||||||
navigator.push(
|
|
||||||
materialRoute(
|
|
||||||
BrandError(
|
|
||||||
error: error,
|
|
||||||
stackTrace: stackTrace,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
super.onError(bloc, error, stackTrace);
|
super.onError(bloc, error, stackTrace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ class HiveConfig {
|
||||||
|
|
||||||
Hive.registerAdapter(DnsProviderAdapter());
|
Hive.registerAdapter(DnsProviderAdapter());
|
||||||
Hive.registerAdapter(ServerProviderAdapter());
|
Hive.registerAdapter(ServerProviderAdapter());
|
||||||
|
Hive.registerAdapter(UserTypeAdapter());
|
||||||
|
|
||||||
await Hive.openBox(BNames.appSettingsBox);
|
await Hive.openBox(BNames.appSettingsBox);
|
||||||
|
|
||||||
|
|
55
lib/logic/api_maps/graphql_maps/api_map.dart
Normal file
55
lib/logic/api_maps/graphql_maps/api_map.dart
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
|
||||||
|
abstract class ApiMap {
|
||||||
|
Future<GraphQLClient> getClient() async {
|
||||||
|
final httpLink = HttpLink(
|
||||||
|
'https://api.$rootAddress/graphql',
|
||||||
|
);
|
||||||
|
|
||||||
|
final String token = _getApiToken();
|
||||||
|
|
||||||
|
final Link graphQLLink = isWithToken
|
||||||
|
? AuthLink(
|
||||||
|
getToken: () async =>
|
||||||
|
customToken == '' ? 'Bearer $token' : customToken,
|
||||||
|
).concat(httpLink)
|
||||||
|
: httpLink;
|
||||||
|
|
||||||
|
return GraphQLClient(
|
||||||
|
cache: GraphQLCache(),
|
||||||
|
link: graphQLLink,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GraphQLClient> getSubscriptionClient() async {
|
||||||
|
final String token = _getApiToken();
|
||||||
|
|
||||||
|
final WebSocketLink webSocketLink = WebSocketLink(
|
||||||
|
'ws://api.$rootAddress/graphql',
|
||||||
|
config: SocketClientConfig(
|
||||||
|
autoReconnect: true,
|
||||||
|
headers: token.isEmpty ? null : {'Authorization': 'Bearer $token'},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return GraphQLClient(
|
||||||
|
cache: GraphQLCache(),
|
||||||
|
link: webSocketLink,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getApiToken() {
|
||||||
|
String token = '';
|
||||||
|
final serverDetails = getIt<ApiConfigModel>().serverDetails;
|
||||||
|
if (serverDetails != null) {
|
||||||
|
token = getIt<ApiConfigModel>().serverDetails!.apiToken;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract final String? rootAddress;
|
||||||
|
abstract final bool hasLogger;
|
||||||
|
abstract final bool isWithToken;
|
||||||
|
abstract final String customToken;
|
||||||
|
}
|
69
lib/logic/api_maps/graphql_maps/schema/disk_volumes.graphql
Normal file
69
lib/logic/api_maps/graphql_maps/schema/disk_volumes.graphql
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
fragment basicMutationReturnFields on MutationReturnInterface{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
|
||||||
|
query GetServerDiskVolumes {
|
||||||
|
storage {
|
||||||
|
volumes {
|
||||||
|
freeSpace
|
||||||
|
model
|
||||||
|
name
|
||||||
|
root
|
||||||
|
serial
|
||||||
|
totalSpace
|
||||||
|
type
|
||||||
|
usages {
|
||||||
|
title
|
||||||
|
usedSpace
|
||||||
|
__typename
|
||||||
|
... on ServiceStorageUsage {
|
||||||
|
service {
|
||||||
|
id
|
||||||
|
isMovable
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usedSpace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation MountVolume($name: String!) {
|
||||||
|
mountVolume(name: $name) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation ResizeVolume($name: String!) {
|
||||||
|
resizeVolume(name: $name) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation UnmountVolume($name: String!) {
|
||||||
|
unmountVolume(name: $name) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation MigrateToBinds($input: MigrateToBindsInput!) {
|
||||||
|
migrateToBinds(input: $input) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
job {
|
||||||
|
createdAt
|
||||||
|
description
|
||||||
|
error
|
||||||
|
finishedAt
|
||||||
|
name
|
||||||
|
progress
|
||||||
|
result
|
||||||
|
status
|
||||||
|
statusText
|
||||||
|
uid
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3295
lib/logic/api_maps/graphql_maps/schema/disk_volumes.graphql.dart
Normal file
3295
lib/logic/api_maps/graphql_maps/schema/disk_volumes.graphql.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,376 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'disk_volumes.graphql.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Fragment$basicMutationReturnFields _$Fragment$basicMutationReturnFieldsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Fragment$basicMutationReturnFields(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Fragment$basicMutationReturnFieldsToJson(
|
||||||
|
Fragment$basicMutationReturnFields instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetServerDiskVolumes _$Query$GetServerDiskVolumesFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetServerDiskVolumes(
|
||||||
|
storage: Query$GetServerDiskVolumes$storage.fromJson(
|
||||||
|
json['storage'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetServerDiskVolumesToJson(
|
||||||
|
Query$GetServerDiskVolumes instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'storage': instance.storage.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetServerDiskVolumes$storage _$Query$GetServerDiskVolumes$storageFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetServerDiskVolumes$storage(
|
||||||
|
volumes: (json['volumes'] as List<dynamic>)
|
||||||
|
.map((e) => Query$GetServerDiskVolumes$storage$volumes.fromJson(
|
||||||
|
e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetServerDiskVolumes$storageToJson(
|
||||||
|
Query$GetServerDiskVolumes$storage instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'volumes': instance.volumes.map((e) => e.toJson()).toList(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes
|
||||||
|
_$Query$GetServerDiskVolumes$storage$volumesFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes(
|
||||||
|
freeSpace: json['freeSpace'] as String,
|
||||||
|
model: json['model'] as String?,
|
||||||
|
name: json['name'] as String,
|
||||||
|
root: json['root'] as bool,
|
||||||
|
serial: json['serial'] as String?,
|
||||||
|
totalSpace: json['totalSpace'] as String,
|
||||||
|
type: json['type'] as String,
|
||||||
|
usages: (json['usages'] as List<dynamic>)
|
||||||
|
.map((e) =>
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages.fromJson(
|
||||||
|
e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
usedSpace: json['usedSpace'] as String,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetServerDiskVolumes$storage$volumesToJson(
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'freeSpace': instance.freeSpace,
|
||||||
|
'model': instance.model,
|
||||||
|
'name': instance.name,
|
||||||
|
'root': instance.root,
|
||||||
|
'serial': instance.serial,
|
||||||
|
'totalSpace': instance.totalSpace,
|
||||||
|
'type': instance.type,
|
||||||
|
'usages': instance.usages.map((e) => e.toJson()).toList(),
|
||||||
|
'usedSpace': instance.usedSpace,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages
|
||||||
|
_$Query$GetServerDiskVolumes$storage$volumes$usagesFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages(
|
||||||
|
title: json['title'] as String,
|
||||||
|
usedSpace: json['usedSpace'] as String,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetServerDiskVolumes$storage$volumes$usagesToJson(
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'title': instance.title,
|
||||||
|
'usedSpace': instance.usedSpace,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage
|
||||||
|
_$Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsageFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage(
|
||||||
|
title: json['title'] as String,
|
||||||
|
usedSpace: json['usedSpace'] as String,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
service: json['service'] == null
|
||||||
|
? null
|
||||||
|
: Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage$service
|
||||||
|
.fromJson(json['service'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic>
|
||||||
|
_$Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsageToJson(
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage
|
||||||
|
instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'title': instance.title,
|
||||||
|
'usedSpace': instance.usedSpace,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'service': instance.service?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage$service
|
||||||
|
_$Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage$serviceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage$service(
|
||||||
|
id: json['id'] as String,
|
||||||
|
isMovable: json['isMovable'] as bool,
|
||||||
|
displayName: json['displayName'] as String,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic>
|
||||||
|
_$Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage$serviceToJson(
|
||||||
|
Query$GetServerDiskVolumes$storage$volumes$usages$$ServiceStorageUsage$service
|
||||||
|
instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'isMovable': instance.isMovable,
|
||||||
|
'displayName': instance.displayName,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$MountVolume _$Variables$Mutation$MountVolumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$MountVolume(
|
||||||
|
name: json['name'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$MountVolumeToJson(
|
||||||
|
Variables$Mutation$MountVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'name': instance.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$MountVolume _$Mutation$MountVolumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$MountVolume(
|
||||||
|
mountVolume: Mutation$MountVolume$mountVolume.fromJson(
|
||||||
|
json['mountVolume'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$MountVolumeToJson(
|
||||||
|
Mutation$MountVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'mountVolume': instance.mountVolume.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$MountVolume$mountVolume _$Mutation$MountVolume$mountVolumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$MountVolume$mountVolume(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$MountVolume$mountVolumeToJson(
|
||||||
|
Mutation$MountVolume$mountVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$ResizeVolume _$Variables$Mutation$ResizeVolumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$ResizeVolume(
|
||||||
|
name: json['name'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$ResizeVolumeToJson(
|
||||||
|
Variables$Mutation$ResizeVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'name': instance.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$ResizeVolume _$Mutation$ResizeVolumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$ResizeVolume(
|
||||||
|
resizeVolume: Mutation$ResizeVolume$resizeVolume.fromJson(
|
||||||
|
json['resizeVolume'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$ResizeVolumeToJson(
|
||||||
|
Mutation$ResizeVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'resizeVolume': instance.resizeVolume.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$ResizeVolume$resizeVolume _$Mutation$ResizeVolume$resizeVolumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$ResizeVolume$resizeVolume(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$ResizeVolume$resizeVolumeToJson(
|
||||||
|
Mutation$ResizeVolume$resizeVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$UnmountVolume _$Variables$Mutation$UnmountVolumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$UnmountVolume(
|
||||||
|
name: json['name'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$UnmountVolumeToJson(
|
||||||
|
Variables$Mutation$UnmountVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'name': instance.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$UnmountVolume _$Mutation$UnmountVolumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$UnmountVolume(
|
||||||
|
unmountVolume: Mutation$UnmountVolume$unmountVolume.fromJson(
|
||||||
|
json['unmountVolume'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$UnmountVolumeToJson(
|
||||||
|
Mutation$UnmountVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'unmountVolume': instance.unmountVolume.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$UnmountVolume$unmountVolume
|
||||||
|
_$Mutation$UnmountVolume$unmountVolumeFromJson(Map<String, dynamic> json) =>
|
||||||
|
Mutation$UnmountVolume$unmountVolume(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$UnmountVolume$unmountVolumeToJson(
|
||||||
|
Mutation$UnmountVolume$unmountVolume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$MigrateToBinds _$Variables$Mutation$MigrateToBindsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$MigrateToBinds(
|
||||||
|
input: Input$MigrateToBindsInput.fromJson(
|
||||||
|
json['input'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$MigrateToBindsToJson(
|
||||||
|
Variables$Mutation$MigrateToBinds instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'input': instance.input.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$MigrateToBinds _$Mutation$MigrateToBindsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$MigrateToBinds(
|
||||||
|
migrateToBinds: Mutation$MigrateToBinds$migrateToBinds.fromJson(
|
||||||
|
json['migrateToBinds'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$MigrateToBindsToJson(
|
||||||
|
Mutation$MigrateToBinds instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'migrateToBinds': instance.migrateToBinds.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$MigrateToBinds$migrateToBinds
|
||||||
|
_$Mutation$MigrateToBinds$migrateToBindsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$MigrateToBinds$migrateToBinds(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
job: json['job'] == null
|
||||||
|
? null
|
||||||
|
: Mutation$MigrateToBinds$migrateToBinds$job.fromJson(
|
||||||
|
json['job'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$MigrateToBinds$migrateToBindsToJson(
|
||||||
|
Mutation$MigrateToBinds$migrateToBinds instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'job': instance.job?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$MigrateToBinds$migrateToBinds$job
|
||||||
|
_$Mutation$MigrateToBinds$migrateToBinds$jobFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$MigrateToBinds$migrateToBinds$job(
|
||||||
|
createdAt: dateTimeFromJson(json['createdAt']),
|
||||||
|
description: json['description'] as String,
|
||||||
|
error: json['error'] as String?,
|
||||||
|
finishedAt: _nullable$dateTimeFromJson(json['finishedAt']),
|
||||||
|
name: json['name'] as String,
|
||||||
|
progress: json['progress'] as int?,
|
||||||
|
result: json['result'] as String?,
|
||||||
|
status: json['status'] as String,
|
||||||
|
statusText: json['statusText'] as String?,
|
||||||
|
uid: json['uid'] as String,
|
||||||
|
updatedAt: dateTimeFromJson(json['updatedAt']),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$MigrateToBinds$migrateToBinds$jobToJson(
|
||||||
|
Mutation$MigrateToBinds$migrateToBinds$job instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'createdAt': dateTimeToJson(instance.createdAt),
|
||||||
|
'description': instance.description,
|
||||||
|
'error': instance.error,
|
||||||
|
'finishedAt': _nullable$dateTimeToJson(instance.finishedAt),
|
||||||
|
'name': instance.name,
|
||||||
|
'progress': instance.progress,
|
||||||
|
'result': instance.result,
|
||||||
|
'status': instance.status,
|
||||||
|
'statusText': instance.statusText,
|
||||||
|
'uid': instance.uid,
|
||||||
|
'updatedAt': dateTimeToJson(instance.updatedAt),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
351
lib/logic/api_maps/graphql_maps/schema/schema.graphql
Normal file
351
lib/logic/api_maps/graphql_maps/schema/schema.graphql
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
type Alert {
|
||||||
|
message: String!
|
||||||
|
severity: Severity!
|
||||||
|
timestamp: DateTime
|
||||||
|
title: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Api {
|
||||||
|
devices: [ApiDevice!]!
|
||||||
|
recoveryKey: ApiRecoveryKeyStatus!
|
||||||
|
version: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiDevice {
|
||||||
|
creationDate: DateTime!
|
||||||
|
isCaller: Boolean!
|
||||||
|
name: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiJob {
|
||||||
|
createdAt: DateTime!
|
||||||
|
description: String!
|
||||||
|
error: String
|
||||||
|
finishedAt: DateTime
|
||||||
|
name: String!
|
||||||
|
progress: Int
|
||||||
|
result: String
|
||||||
|
status: String!
|
||||||
|
statusText: String
|
||||||
|
uid: String!
|
||||||
|
updatedAt: DateTime!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiKeyMutationReturn implements MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
key: String
|
||||||
|
message: String!
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiRecoveryKeyStatus {
|
||||||
|
creationDate: DateTime
|
||||||
|
exists: Boolean!
|
||||||
|
expirationDate: DateTime
|
||||||
|
usesLeft: Int
|
||||||
|
valid: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type AutoUpgradeOptions {
|
||||||
|
allowReboot: Boolean!
|
||||||
|
enable: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
input AutoUpgradeSettingsInput {
|
||||||
|
enableAutoUpgrade: Boolean = null
|
||||||
|
allowReboot: Boolean = null
|
||||||
|
}
|
||||||
|
|
||||||
|
type AutoUpgradeSettingsMutationReturn implements MutationReturnInterface {
|
||||||
|
allowReboot: Boolean!
|
||||||
|
code: Int!
|
||||||
|
enableAutoUpgrade: Boolean!
|
||||||
|
message: String!
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""Date with time (isoformat)"""
|
||||||
|
scalar DateTime
|
||||||
|
|
||||||
|
type DeviceApiTokenMutationReturn implements MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
message: String!
|
||||||
|
success: Boolean!
|
||||||
|
token: String
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DnsProvider {
|
||||||
|
CLOUDFLARE
|
||||||
|
}
|
||||||
|
|
||||||
|
type DnsRecord {
|
||||||
|
content: String!
|
||||||
|
name: String!
|
||||||
|
priority: Int
|
||||||
|
recordType: String!
|
||||||
|
ttl: Int!
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenericJobButationReturn implements MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
job: ApiJob
|
||||||
|
message: String!
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenericMutationReturn implements MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
message: String!
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Job {
|
||||||
|
getJob(jobId: String!): ApiJob
|
||||||
|
getJobs: [ApiJob!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
input MigrateToBindsInput {
|
||||||
|
emailBlockDevice: String!
|
||||||
|
bitwardenBlockDevice: String!
|
||||||
|
giteaBlockDevice: String!
|
||||||
|
nextcloudBlockDevice: String!
|
||||||
|
pleromaBlockDevice: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
input MoveServiceInput {
|
||||||
|
serviceId: String!
|
||||||
|
location: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mutation {
|
||||||
|
addSshKey(sshInput: SshMutationInput!): UserMutationReturn!
|
||||||
|
authorizeWithNewDeviceApiKey(input: UseNewDeviceKeyInput!): DeviceApiTokenMutationReturn!
|
||||||
|
changeAutoUpgradeSettings(settings: AutoUpgradeSettingsInput!): AutoUpgradeSettingsMutationReturn!
|
||||||
|
changeTimezone(timezone: String!): TimezoneMutationReturn!
|
||||||
|
createUser(user: UserMutationInput!): UserMutationReturn!
|
||||||
|
deleteDeviceApiToken(device: String!): GenericMutationReturn!
|
||||||
|
deleteUser(username: String!): GenericMutationReturn!
|
||||||
|
disableService(serviceId: String!): ServiceMutationReturn!
|
||||||
|
enableService(serviceId: String!): ServiceMutationReturn!
|
||||||
|
getNewDeviceApiKey: ApiKeyMutationReturn!
|
||||||
|
getNewRecoveryApiKey(limits: RecoveryKeyLimitsInput = null): ApiKeyMutationReturn!
|
||||||
|
invalidateNewDeviceApiKey: GenericMutationReturn!
|
||||||
|
migrateToBinds(input: MigrateToBindsInput!): GenericJobButationReturn!
|
||||||
|
mountVolume(name: String!): GenericMutationReturn!
|
||||||
|
moveService(input: MoveServiceInput!): ServiceJobMutationReturn!
|
||||||
|
pullRepositoryChanges: GenericMutationReturn!
|
||||||
|
rebootSystem: GenericMutationReturn!
|
||||||
|
refreshDeviceApiToken: DeviceApiTokenMutationReturn!
|
||||||
|
removeJob(jobId: String!): GenericMutationReturn!
|
||||||
|
removeSshKey(sshInput: SshMutationInput!): UserMutationReturn!
|
||||||
|
resizeVolume(name: String!): GenericMutationReturn!
|
||||||
|
restartService(serviceId: String!): ServiceMutationReturn!
|
||||||
|
runSystemRebuild: GenericMutationReturn!
|
||||||
|
runSystemRollback: GenericMutationReturn!
|
||||||
|
runSystemUpgrade: GenericMutationReturn!
|
||||||
|
startService(serviceId: String!): ServiceMutationReturn!
|
||||||
|
stopService(serviceId: String!): ServiceMutationReturn!
|
||||||
|
testMutation: GenericMutationReturn!
|
||||||
|
unmountVolume(name: String!): GenericMutationReturn!
|
||||||
|
updateUser(user: UserMutationInput!): UserMutationReturn!
|
||||||
|
useRecoveryApiKey(input: UseRecoveryKeyInput!): DeviceApiTokenMutationReturn!
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
message: String!
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query {
|
||||||
|
api: Api!
|
||||||
|
jobs: Job!
|
||||||
|
services: Services!
|
||||||
|
storage: Storage!
|
||||||
|
system: System!
|
||||||
|
users: Users!
|
||||||
|
}
|
||||||
|
|
||||||
|
input RecoveryKeyLimitsInput {
|
||||||
|
expirationDate: DateTime = null
|
||||||
|
uses: Int = null
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ServerProvider {
|
||||||
|
HETZNER
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service {
|
||||||
|
description: String!
|
||||||
|
displayName: String!
|
||||||
|
dnsRecords: [DnsRecord!]
|
||||||
|
id: String!
|
||||||
|
isEnabled: Boolean!
|
||||||
|
isMovable: Boolean!
|
||||||
|
isRequired: Boolean!
|
||||||
|
status: ServiceStatusEnum!
|
||||||
|
storageUsage: ServiceStorageUsage!
|
||||||
|
svgIcon: String!
|
||||||
|
url: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceJobMutationReturn implements MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
job: ApiJob
|
||||||
|
message: String!
|
||||||
|
service: Service
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceMutationReturn implements MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
message: String!
|
||||||
|
service: Service
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ServiceStatusEnum {
|
||||||
|
ACTIVATING
|
||||||
|
ACTIVE
|
||||||
|
DEACTIVATING
|
||||||
|
FAILED
|
||||||
|
INACTIVE
|
||||||
|
OFF
|
||||||
|
RELOADING
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceStorageUsage implements StorageUsageInterface {
|
||||||
|
service: Service
|
||||||
|
title: String!
|
||||||
|
usedSpace: String!
|
||||||
|
volume: StorageVolume
|
||||||
|
}
|
||||||
|
|
||||||
|
type Services {
|
||||||
|
allServices: [Service!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Severity {
|
||||||
|
CRITICAL
|
||||||
|
ERROR
|
||||||
|
INFO
|
||||||
|
SUCCESS
|
||||||
|
WARNING
|
||||||
|
}
|
||||||
|
|
||||||
|
input SshMutationInput {
|
||||||
|
username: String!
|
||||||
|
sshKey: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type SshSettings {
|
||||||
|
enable: Boolean!
|
||||||
|
passwordAuthentication: Boolean!
|
||||||
|
rootSshKeys: [String!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Storage {
|
||||||
|
volumes: [StorageVolume!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StorageUsageInterface {
|
||||||
|
title: String!
|
||||||
|
usedSpace: String!
|
||||||
|
volume: StorageVolume
|
||||||
|
}
|
||||||
|
|
||||||
|
type StorageVolume {
|
||||||
|
freeSpace: String!
|
||||||
|
model: String
|
||||||
|
name: String!
|
||||||
|
root: Boolean!
|
||||||
|
serial: String
|
||||||
|
totalSpace: String!
|
||||||
|
type: String!
|
||||||
|
usages: [StorageUsageInterface!]!
|
||||||
|
usedSpace: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Subscription {
|
||||||
|
count(target: Int! = 100): Int!
|
||||||
|
}
|
||||||
|
|
||||||
|
type System {
|
||||||
|
busy: Boolean!
|
||||||
|
domainInfo: SystemDomainInfo!
|
||||||
|
info: SystemInfo!
|
||||||
|
provider: SystemProviderInfo!
|
||||||
|
settings: SystemSettings!
|
||||||
|
status: Alert!
|
||||||
|
workingDirectory: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemDomainInfo {
|
||||||
|
domain: String!
|
||||||
|
hostname: String!
|
||||||
|
provider: DnsProvider!
|
||||||
|
requiredDnsRecords: [DnsRecord!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemInfo {
|
||||||
|
pythonVersion: String!
|
||||||
|
systemVersion: String!
|
||||||
|
usingBinds: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemProviderInfo {
|
||||||
|
id: String!
|
||||||
|
provider: ServerProvider!
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemSettings {
|
||||||
|
autoUpgrade: AutoUpgradeOptions!
|
||||||
|
ssh: SshSettings!
|
||||||
|
timezone: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type TimezoneMutationReturn implements MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
message: String!
|
||||||
|
success: Boolean!
|
||||||
|
timezone: String
|
||||||
|
}
|
||||||
|
|
||||||
|
input UseNewDeviceKeyInput {
|
||||||
|
key: String!
|
||||||
|
deviceName: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
input UseRecoveryKeyInput {
|
||||||
|
key: String!
|
||||||
|
deviceName: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type User {
|
||||||
|
sshKeys: [String!]!
|
||||||
|
userType: UserType!
|
||||||
|
username: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
input UserMutationInput {
|
||||||
|
username: String!
|
||||||
|
password: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserMutationReturn implements MutationReturnInterface {
|
||||||
|
code: Int!
|
||||||
|
message: String!
|
||||||
|
success: Boolean!
|
||||||
|
user: User
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UserType {
|
||||||
|
NORMAL
|
||||||
|
PRIMARY
|
||||||
|
ROOT
|
||||||
|
}
|
||||||
|
|
||||||
|
type Users {
|
||||||
|
allUsers: [User!]!
|
||||||
|
getUser(username: String!): User
|
||||||
|
}
|
756
lib/logic/api_maps/graphql_maps/schema/schema.graphql.dart
Normal file
756
lib/logic/api_maps/graphql_maps/schema/schema.graphql.dart
Normal file
|
@ -0,0 +1,756 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:selfprivacy/utils/scalars.dart';
|
||||||
|
part 'schema.graphql.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Input$AutoUpgradeSettingsInput {
|
||||||
|
Input$AutoUpgradeSettingsInput({this.enableAutoUpgrade, this.allowReboot});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Input$AutoUpgradeSettingsInput.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$Input$AutoUpgradeSettingsInputFromJson(json);
|
||||||
|
|
||||||
|
final bool? enableAutoUpgrade;
|
||||||
|
|
||||||
|
final bool? allowReboot;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Input$AutoUpgradeSettingsInputToJson(this);
|
||||||
|
int get hashCode {
|
||||||
|
final l$enableAutoUpgrade = enableAutoUpgrade;
|
||||||
|
final l$allowReboot = allowReboot;
|
||||||
|
return Object.hashAll([l$enableAutoUpgrade, l$allowReboot]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (!(other is Input$AutoUpgradeSettingsInput) ||
|
||||||
|
runtimeType != other.runtimeType) return false;
|
||||||
|
final l$enableAutoUpgrade = enableAutoUpgrade;
|
||||||
|
final lOther$enableAutoUpgrade = other.enableAutoUpgrade;
|
||||||
|
if (l$enableAutoUpgrade != lOther$enableAutoUpgrade) return false;
|
||||||
|
final l$allowReboot = allowReboot;
|
||||||
|
final lOther$allowReboot = other.allowReboot;
|
||||||
|
if (l$allowReboot != lOther$allowReboot) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyWith$Input$AutoUpgradeSettingsInput<Input$AutoUpgradeSettingsInput>
|
||||||
|
get copyWith => CopyWith$Input$AutoUpgradeSettingsInput(this, (i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CopyWith$Input$AutoUpgradeSettingsInput<TRes> {
|
||||||
|
factory CopyWith$Input$AutoUpgradeSettingsInput(
|
||||||
|
Input$AutoUpgradeSettingsInput instance,
|
||||||
|
TRes Function(Input$AutoUpgradeSettingsInput) then) =
|
||||||
|
_CopyWithImpl$Input$AutoUpgradeSettingsInput;
|
||||||
|
|
||||||
|
factory CopyWith$Input$AutoUpgradeSettingsInput.stub(TRes res) =
|
||||||
|
_CopyWithStubImpl$Input$AutoUpgradeSettingsInput;
|
||||||
|
|
||||||
|
TRes call({bool? enableAutoUpgrade, bool? allowReboot});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithImpl$Input$AutoUpgradeSettingsInput<TRes>
|
||||||
|
implements CopyWith$Input$AutoUpgradeSettingsInput<TRes> {
|
||||||
|
_CopyWithImpl$Input$AutoUpgradeSettingsInput(this._instance, this._then);
|
||||||
|
|
||||||
|
final Input$AutoUpgradeSettingsInput _instance;
|
||||||
|
|
||||||
|
final TRes Function(Input$AutoUpgradeSettingsInput) _then;
|
||||||
|
|
||||||
|
static const _undefined = {};
|
||||||
|
|
||||||
|
TRes call(
|
||||||
|
{Object? enableAutoUpgrade = _undefined,
|
||||||
|
Object? allowReboot = _undefined}) =>
|
||||||
|
_then(Input$AutoUpgradeSettingsInput(
|
||||||
|
enableAutoUpgrade: enableAutoUpgrade == _undefined
|
||||||
|
? _instance.enableAutoUpgrade
|
||||||
|
: (enableAutoUpgrade as bool?),
|
||||||
|
allowReboot: allowReboot == _undefined
|
||||||
|
? _instance.allowReboot
|
||||||
|
: (allowReboot as bool?)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithStubImpl$Input$AutoUpgradeSettingsInput<TRes>
|
||||||
|
implements CopyWith$Input$AutoUpgradeSettingsInput<TRes> {
|
||||||
|
_CopyWithStubImpl$Input$AutoUpgradeSettingsInput(this._res);
|
||||||
|
|
||||||
|
TRes _res;
|
||||||
|
|
||||||
|
call({bool? enableAutoUpgrade, bool? allowReboot}) => _res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Input$MigrateToBindsInput {
|
||||||
|
Input$MigrateToBindsInput(
|
||||||
|
{required this.emailBlockDevice,
|
||||||
|
required this.bitwardenBlockDevice,
|
||||||
|
required this.giteaBlockDevice,
|
||||||
|
required this.nextcloudBlockDevice,
|
||||||
|
required this.pleromaBlockDevice});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Input$MigrateToBindsInput.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$Input$MigrateToBindsInputFromJson(json);
|
||||||
|
|
||||||
|
final String emailBlockDevice;
|
||||||
|
|
||||||
|
final String bitwardenBlockDevice;
|
||||||
|
|
||||||
|
final String giteaBlockDevice;
|
||||||
|
|
||||||
|
final String nextcloudBlockDevice;
|
||||||
|
|
||||||
|
final String pleromaBlockDevice;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Input$MigrateToBindsInputToJson(this);
|
||||||
|
int get hashCode {
|
||||||
|
final l$emailBlockDevice = emailBlockDevice;
|
||||||
|
final l$bitwardenBlockDevice = bitwardenBlockDevice;
|
||||||
|
final l$giteaBlockDevice = giteaBlockDevice;
|
||||||
|
final l$nextcloudBlockDevice = nextcloudBlockDevice;
|
||||||
|
final l$pleromaBlockDevice = pleromaBlockDevice;
|
||||||
|
return Object.hashAll([
|
||||||
|
l$emailBlockDevice,
|
||||||
|
l$bitwardenBlockDevice,
|
||||||
|
l$giteaBlockDevice,
|
||||||
|
l$nextcloudBlockDevice,
|
||||||
|
l$pleromaBlockDevice
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (!(other is Input$MigrateToBindsInput) ||
|
||||||
|
runtimeType != other.runtimeType) return false;
|
||||||
|
final l$emailBlockDevice = emailBlockDevice;
|
||||||
|
final lOther$emailBlockDevice = other.emailBlockDevice;
|
||||||
|
if (l$emailBlockDevice != lOther$emailBlockDevice) return false;
|
||||||
|
final l$bitwardenBlockDevice = bitwardenBlockDevice;
|
||||||
|
final lOther$bitwardenBlockDevice = other.bitwardenBlockDevice;
|
||||||
|
if (l$bitwardenBlockDevice != lOther$bitwardenBlockDevice) return false;
|
||||||
|
final l$giteaBlockDevice = giteaBlockDevice;
|
||||||
|
final lOther$giteaBlockDevice = other.giteaBlockDevice;
|
||||||
|
if (l$giteaBlockDevice != lOther$giteaBlockDevice) return false;
|
||||||
|
final l$nextcloudBlockDevice = nextcloudBlockDevice;
|
||||||
|
final lOther$nextcloudBlockDevice = other.nextcloudBlockDevice;
|
||||||
|
if (l$nextcloudBlockDevice != lOther$nextcloudBlockDevice) return false;
|
||||||
|
final l$pleromaBlockDevice = pleromaBlockDevice;
|
||||||
|
final lOther$pleromaBlockDevice = other.pleromaBlockDevice;
|
||||||
|
if (l$pleromaBlockDevice != lOther$pleromaBlockDevice) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyWith$Input$MigrateToBindsInput<Input$MigrateToBindsInput> get copyWith =>
|
||||||
|
CopyWith$Input$MigrateToBindsInput(this, (i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CopyWith$Input$MigrateToBindsInput<TRes> {
|
||||||
|
factory CopyWith$Input$MigrateToBindsInput(Input$MigrateToBindsInput instance,
|
||||||
|
TRes Function(Input$MigrateToBindsInput) then) =
|
||||||
|
_CopyWithImpl$Input$MigrateToBindsInput;
|
||||||
|
|
||||||
|
factory CopyWith$Input$MigrateToBindsInput.stub(TRes res) =
|
||||||
|
_CopyWithStubImpl$Input$MigrateToBindsInput;
|
||||||
|
|
||||||
|
TRes call(
|
||||||
|
{String? emailBlockDevice,
|
||||||
|
String? bitwardenBlockDevice,
|
||||||
|
String? giteaBlockDevice,
|
||||||
|
String? nextcloudBlockDevice,
|
||||||
|
String? pleromaBlockDevice});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithImpl$Input$MigrateToBindsInput<TRes>
|
||||||
|
implements CopyWith$Input$MigrateToBindsInput<TRes> {
|
||||||
|
_CopyWithImpl$Input$MigrateToBindsInput(this._instance, this._then);
|
||||||
|
|
||||||
|
final Input$MigrateToBindsInput _instance;
|
||||||
|
|
||||||
|
final TRes Function(Input$MigrateToBindsInput) _then;
|
||||||
|
|
||||||
|
static const _undefined = {};
|
||||||
|
|
||||||
|
TRes call(
|
||||||
|
{Object? emailBlockDevice = _undefined,
|
||||||
|
Object? bitwardenBlockDevice = _undefined,
|
||||||
|
Object? giteaBlockDevice = _undefined,
|
||||||
|
Object? nextcloudBlockDevice = _undefined,
|
||||||
|
Object? pleromaBlockDevice = _undefined}) =>
|
||||||
|
_then(Input$MigrateToBindsInput(
|
||||||
|
emailBlockDevice:
|
||||||
|
emailBlockDevice == _undefined || emailBlockDevice == null
|
||||||
|
? _instance.emailBlockDevice
|
||||||
|
: (emailBlockDevice as String),
|
||||||
|
bitwardenBlockDevice:
|
||||||
|
bitwardenBlockDevice == _undefined || bitwardenBlockDevice == null
|
||||||
|
? _instance.bitwardenBlockDevice
|
||||||
|
: (bitwardenBlockDevice as String),
|
||||||
|
giteaBlockDevice:
|
||||||
|
giteaBlockDevice == _undefined || giteaBlockDevice == null
|
||||||
|
? _instance.giteaBlockDevice
|
||||||
|
: (giteaBlockDevice as String),
|
||||||
|
nextcloudBlockDevice:
|
||||||
|
nextcloudBlockDevice == _undefined || nextcloudBlockDevice == null
|
||||||
|
? _instance.nextcloudBlockDevice
|
||||||
|
: (nextcloudBlockDevice as String),
|
||||||
|
pleromaBlockDevice:
|
||||||
|
pleromaBlockDevice == _undefined || pleromaBlockDevice == null
|
||||||
|
? _instance.pleromaBlockDevice
|
||||||
|
: (pleromaBlockDevice as String)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithStubImpl$Input$MigrateToBindsInput<TRes>
|
||||||
|
implements CopyWith$Input$MigrateToBindsInput<TRes> {
|
||||||
|
_CopyWithStubImpl$Input$MigrateToBindsInput(this._res);
|
||||||
|
|
||||||
|
TRes _res;
|
||||||
|
|
||||||
|
call(
|
||||||
|
{String? emailBlockDevice,
|
||||||
|
String? bitwardenBlockDevice,
|
||||||
|
String? giteaBlockDevice,
|
||||||
|
String? nextcloudBlockDevice,
|
||||||
|
String? pleromaBlockDevice}) =>
|
||||||
|
_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Input$MoveServiceInput {
|
||||||
|
Input$MoveServiceInput({required this.serviceId, required this.location});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Input$MoveServiceInput.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$Input$MoveServiceInputFromJson(json);
|
||||||
|
|
||||||
|
final String serviceId;
|
||||||
|
|
||||||
|
final String location;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Input$MoveServiceInputToJson(this);
|
||||||
|
int get hashCode {
|
||||||
|
final l$serviceId = serviceId;
|
||||||
|
final l$location = location;
|
||||||
|
return Object.hashAll([l$serviceId, l$location]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (!(other is Input$MoveServiceInput) || runtimeType != other.runtimeType)
|
||||||
|
return false;
|
||||||
|
final l$serviceId = serviceId;
|
||||||
|
final lOther$serviceId = other.serviceId;
|
||||||
|
if (l$serviceId != lOther$serviceId) return false;
|
||||||
|
final l$location = location;
|
||||||
|
final lOther$location = other.location;
|
||||||
|
if (l$location != lOther$location) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyWith$Input$MoveServiceInput<Input$MoveServiceInput> get copyWith =>
|
||||||
|
CopyWith$Input$MoveServiceInput(this, (i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CopyWith$Input$MoveServiceInput<TRes> {
|
||||||
|
factory CopyWith$Input$MoveServiceInput(Input$MoveServiceInput instance,
|
||||||
|
TRes Function(Input$MoveServiceInput) then) =
|
||||||
|
_CopyWithImpl$Input$MoveServiceInput;
|
||||||
|
|
||||||
|
factory CopyWith$Input$MoveServiceInput.stub(TRes res) =
|
||||||
|
_CopyWithStubImpl$Input$MoveServiceInput;
|
||||||
|
|
||||||
|
TRes call({String? serviceId, String? location});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithImpl$Input$MoveServiceInput<TRes>
|
||||||
|
implements CopyWith$Input$MoveServiceInput<TRes> {
|
||||||
|
_CopyWithImpl$Input$MoveServiceInput(this._instance, this._then);
|
||||||
|
|
||||||
|
final Input$MoveServiceInput _instance;
|
||||||
|
|
||||||
|
final TRes Function(Input$MoveServiceInput) _then;
|
||||||
|
|
||||||
|
static const _undefined = {};
|
||||||
|
|
||||||
|
TRes call({Object? serviceId = _undefined, Object? location = _undefined}) =>
|
||||||
|
_then(Input$MoveServiceInput(
|
||||||
|
serviceId: serviceId == _undefined || serviceId == null
|
||||||
|
? _instance.serviceId
|
||||||
|
: (serviceId as String),
|
||||||
|
location: location == _undefined || location == null
|
||||||
|
? _instance.location
|
||||||
|
: (location as String)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithStubImpl$Input$MoveServiceInput<TRes>
|
||||||
|
implements CopyWith$Input$MoveServiceInput<TRes> {
|
||||||
|
_CopyWithStubImpl$Input$MoveServiceInput(this._res);
|
||||||
|
|
||||||
|
TRes _res;
|
||||||
|
|
||||||
|
call({String? serviceId, String? location}) => _res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Input$RecoveryKeyLimitsInput {
|
||||||
|
Input$RecoveryKeyLimitsInput({this.expirationDate, this.uses});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Input$RecoveryKeyLimitsInput.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$Input$RecoveryKeyLimitsInputFromJson(json);
|
||||||
|
|
||||||
|
@JsonKey(
|
||||||
|
fromJson: _nullable$dateTimeFromJson, toJson: _nullable$dateTimeToJson)
|
||||||
|
final DateTime? expirationDate;
|
||||||
|
|
||||||
|
final int? uses;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Input$RecoveryKeyLimitsInputToJson(this);
|
||||||
|
int get hashCode {
|
||||||
|
final l$expirationDate = expirationDate;
|
||||||
|
final l$uses = uses;
|
||||||
|
return Object.hashAll([l$expirationDate, l$uses]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (!(other is Input$RecoveryKeyLimitsInput) ||
|
||||||
|
runtimeType != other.runtimeType) return false;
|
||||||
|
final l$expirationDate = expirationDate;
|
||||||
|
final lOther$expirationDate = other.expirationDate;
|
||||||
|
if (l$expirationDate != lOther$expirationDate) return false;
|
||||||
|
final l$uses = uses;
|
||||||
|
final lOther$uses = other.uses;
|
||||||
|
if (l$uses != lOther$uses) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyWith$Input$RecoveryKeyLimitsInput<Input$RecoveryKeyLimitsInput>
|
||||||
|
get copyWith => CopyWith$Input$RecoveryKeyLimitsInput(this, (i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CopyWith$Input$RecoveryKeyLimitsInput<TRes> {
|
||||||
|
factory CopyWith$Input$RecoveryKeyLimitsInput(
|
||||||
|
Input$RecoveryKeyLimitsInput instance,
|
||||||
|
TRes Function(Input$RecoveryKeyLimitsInput) then) =
|
||||||
|
_CopyWithImpl$Input$RecoveryKeyLimitsInput;
|
||||||
|
|
||||||
|
factory CopyWith$Input$RecoveryKeyLimitsInput.stub(TRes res) =
|
||||||
|
_CopyWithStubImpl$Input$RecoveryKeyLimitsInput;
|
||||||
|
|
||||||
|
TRes call({DateTime? expirationDate, int? uses});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithImpl$Input$RecoveryKeyLimitsInput<TRes>
|
||||||
|
implements CopyWith$Input$RecoveryKeyLimitsInput<TRes> {
|
||||||
|
_CopyWithImpl$Input$RecoveryKeyLimitsInput(this._instance, this._then);
|
||||||
|
|
||||||
|
final Input$RecoveryKeyLimitsInput _instance;
|
||||||
|
|
||||||
|
final TRes Function(Input$RecoveryKeyLimitsInput) _then;
|
||||||
|
|
||||||
|
static const _undefined = {};
|
||||||
|
|
||||||
|
TRes call({Object? expirationDate = _undefined, Object? uses = _undefined}) =>
|
||||||
|
_then(Input$RecoveryKeyLimitsInput(
|
||||||
|
expirationDate: expirationDate == _undefined
|
||||||
|
? _instance.expirationDate
|
||||||
|
: (expirationDate as DateTime?),
|
||||||
|
uses: uses == _undefined ? _instance.uses : (uses as int?)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithStubImpl$Input$RecoveryKeyLimitsInput<TRes>
|
||||||
|
implements CopyWith$Input$RecoveryKeyLimitsInput<TRes> {
|
||||||
|
_CopyWithStubImpl$Input$RecoveryKeyLimitsInput(this._res);
|
||||||
|
|
||||||
|
TRes _res;
|
||||||
|
|
||||||
|
call({DateTime? expirationDate, int? uses}) => _res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Input$SshMutationInput {
|
||||||
|
Input$SshMutationInput({required this.username, required this.sshKey});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Input$SshMutationInput.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$Input$SshMutationInputFromJson(json);
|
||||||
|
|
||||||
|
final String username;
|
||||||
|
|
||||||
|
final String sshKey;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Input$SshMutationInputToJson(this);
|
||||||
|
int get hashCode {
|
||||||
|
final l$username = username;
|
||||||
|
final l$sshKey = sshKey;
|
||||||
|
return Object.hashAll([l$username, l$sshKey]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (!(other is Input$SshMutationInput) || runtimeType != other.runtimeType)
|
||||||
|
return false;
|
||||||
|
final l$username = username;
|
||||||
|
final lOther$username = other.username;
|
||||||
|
if (l$username != lOther$username) return false;
|
||||||
|
final l$sshKey = sshKey;
|
||||||
|
final lOther$sshKey = other.sshKey;
|
||||||
|
if (l$sshKey != lOther$sshKey) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyWith$Input$SshMutationInput<Input$SshMutationInput> get copyWith =>
|
||||||
|
CopyWith$Input$SshMutationInput(this, (i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CopyWith$Input$SshMutationInput<TRes> {
|
||||||
|
factory CopyWith$Input$SshMutationInput(Input$SshMutationInput instance,
|
||||||
|
TRes Function(Input$SshMutationInput) then) =
|
||||||
|
_CopyWithImpl$Input$SshMutationInput;
|
||||||
|
|
||||||
|
factory CopyWith$Input$SshMutationInput.stub(TRes res) =
|
||||||
|
_CopyWithStubImpl$Input$SshMutationInput;
|
||||||
|
|
||||||
|
TRes call({String? username, String? sshKey});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithImpl$Input$SshMutationInput<TRes>
|
||||||
|
implements CopyWith$Input$SshMutationInput<TRes> {
|
||||||
|
_CopyWithImpl$Input$SshMutationInput(this._instance, this._then);
|
||||||
|
|
||||||
|
final Input$SshMutationInput _instance;
|
||||||
|
|
||||||
|
final TRes Function(Input$SshMutationInput) _then;
|
||||||
|
|
||||||
|
static const _undefined = {};
|
||||||
|
|
||||||
|
TRes call({Object? username = _undefined, Object? sshKey = _undefined}) =>
|
||||||
|
_then(Input$SshMutationInput(
|
||||||
|
username: username == _undefined || username == null
|
||||||
|
? _instance.username
|
||||||
|
: (username as String),
|
||||||
|
sshKey: sshKey == _undefined || sshKey == null
|
||||||
|
? _instance.sshKey
|
||||||
|
: (sshKey as String)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithStubImpl$Input$SshMutationInput<TRes>
|
||||||
|
implements CopyWith$Input$SshMutationInput<TRes> {
|
||||||
|
_CopyWithStubImpl$Input$SshMutationInput(this._res);
|
||||||
|
|
||||||
|
TRes _res;
|
||||||
|
|
||||||
|
call({String? username, String? sshKey}) => _res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Input$UseNewDeviceKeyInput {
|
||||||
|
Input$UseNewDeviceKeyInput({required this.key, required this.deviceName});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Input$UseNewDeviceKeyInput.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$Input$UseNewDeviceKeyInputFromJson(json);
|
||||||
|
|
||||||
|
final String key;
|
||||||
|
|
||||||
|
final String deviceName;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Input$UseNewDeviceKeyInputToJson(this);
|
||||||
|
int get hashCode {
|
||||||
|
final l$key = key;
|
||||||
|
final l$deviceName = deviceName;
|
||||||
|
return Object.hashAll([l$key, l$deviceName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (!(other is Input$UseNewDeviceKeyInput) ||
|
||||||
|
runtimeType != other.runtimeType) return false;
|
||||||
|
final l$key = key;
|
||||||
|
final lOther$key = other.key;
|
||||||
|
if (l$key != lOther$key) return false;
|
||||||
|
final l$deviceName = deviceName;
|
||||||
|
final lOther$deviceName = other.deviceName;
|
||||||
|
if (l$deviceName != lOther$deviceName) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyWith$Input$UseNewDeviceKeyInput<Input$UseNewDeviceKeyInput>
|
||||||
|
get copyWith => CopyWith$Input$UseNewDeviceKeyInput(this, (i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CopyWith$Input$UseNewDeviceKeyInput<TRes> {
|
||||||
|
factory CopyWith$Input$UseNewDeviceKeyInput(
|
||||||
|
Input$UseNewDeviceKeyInput instance,
|
||||||
|
TRes Function(Input$UseNewDeviceKeyInput) then) =
|
||||||
|
_CopyWithImpl$Input$UseNewDeviceKeyInput;
|
||||||
|
|
||||||
|
factory CopyWith$Input$UseNewDeviceKeyInput.stub(TRes res) =
|
||||||
|
_CopyWithStubImpl$Input$UseNewDeviceKeyInput;
|
||||||
|
|
||||||
|
TRes call({String? key, String? deviceName});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithImpl$Input$UseNewDeviceKeyInput<TRes>
|
||||||
|
implements CopyWith$Input$UseNewDeviceKeyInput<TRes> {
|
||||||
|
_CopyWithImpl$Input$UseNewDeviceKeyInput(this._instance, this._then);
|
||||||
|
|
||||||
|
final Input$UseNewDeviceKeyInput _instance;
|
||||||
|
|
||||||
|
final TRes Function(Input$UseNewDeviceKeyInput) _then;
|
||||||
|
|
||||||
|
static const _undefined = {};
|
||||||
|
|
||||||
|
TRes call({Object? key = _undefined, Object? deviceName = _undefined}) =>
|
||||||
|
_then(Input$UseNewDeviceKeyInput(
|
||||||
|
key: key == _undefined || key == null
|
||||||
|
? _instance.key
|
||||||
|
: (key as String),
|
||||||
|
deviceName: deviceName == _undefined || deviceName == null
|
||||||
|
? _instance.deviceName
|
||||||
|
: (deviceName as String)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithStubImpl$Input$UseNewDeviceKeyInput<TRes>
|
||||||
|
implements CopyWith$Input$UseNewDeviceKeyInput<TRes> {
|
||||||
|
_CopyWithStubImpl$Input$UseNewDeviceKeyInput(this._res);
|
||||||
|
|
||||||
|
TRes _res;
|
||||||
|
|
||||||
|
call({String? key, String? deviceName}) => _res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Input$UseRecoveryKeyInput {
|
||||||
|
Input$UseRecoveryKeyInput({required this.key, required this.deviceName});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Input$UseRecoveryKeyInput.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$Input$UseRecoveryKeyInputFromJson(json);
|
||||||
|
|
||||||
|
final String key;
|
||||||
|
|
||||||
|
final String deviceName;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Input$UseRecoveryKeyInputToJson(this);
|
||||||
|
int get hashCode {
|
||||||
|
final l$key = key;
|
||||||
|
final l$deviceName = deviceName;
|
||||||
|
return Object.hashAll([l$key, l$deviceName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (!(other is Input$UseRecoveryKeyInput) ||
|
||||||
|
runtimeType != other.runtimeType) return false;
|
||||||
|
final l$key = key;
|
||||||
|
final lOther$key = other.key;
|
||||||
|
if (l$key != lOther$key) return false;
|
||||||
|
final l$deviceName = deviceName;
|
||||||
|
final lOther$deviceName = other.deviceName;
|
||||||
|
if (l$deviceName != lOther$deviceName) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyWith$Input$UseRecoveryKeyInput<Input$UseRecoveryKeyInput> get copyWith =>
|
||||||
|
CopyWith$Input$UseRecoveryKeyInput(this, (i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CopyWith$Input$UseRecoveryKeyInput<TRes> {
|
||||||
|
factory CopyWith$Input$UseRecoveryKeyInput(Input$UseRecoveryKeyInput instance,
|
||||||
|
TRes Function(Input$UseRecoveryKeyInput) then) =
|
||||||
|
_CopyWithImpl$Input$UseRecoveryKeyInput;
|
||||||
|
|
||||||
|
factory CopyWith$Input$UseRecoveryKeyInput.stub(TRes res) =
|
||||||
|
_CopyWithStubImpl$Input$UseRecoveryKeyInput;
|
||||||
|
|
||||||
|
TRes call({String? key, String? deviceName});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithImpl$Input$UseRecoveryKeyInput<TRes>
|
||||||
|
implements CopyWith$Input$UseRecoveryKeyInput<TRes> {
|
||||||
|
_CopyWithImpl$Input$UseRecoveryKeyInput(this._instance, this._then);
|
||||||
|
|
||||||
|
final Input$UseRecoveryKeyInput _instance;
|
||||||
|
|
||||||
|
final TRes Function(Input$UseRecoveryKeyInput) _then;
|
||||||
|
|
||||||
|
static const _undefined = {};
|
||||||
|
|
||||||
|
TRes call({Object? key = _undefined, Object? deviceName = _undefined}) =>
|
||||||
|
_then(Input$UseRecoveryKeyInput(
|
||||||
|
key: key == _undefined || key == null
|
||||||
|
? _instance.key
|
||||||
|
: (key as String),
|
||||||
|
deviceName: deviceName == _undefined || deviceName == null
|
||||||
|
? _instance.deviceName
|
||||||
|
: (deviceName as String)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithStubImpl$Input$UseRecoveryKeyInput<TRes>
|
||||||
|
implements CopyWith$Input$UseRecoveryKeyInput<TRes> {
|
||||||
|
_CopyWithStubImpl$Input$UseRecoveryKeyInput(this._res);
|
||||||
|
|
||||||
|
TRes _res;
|
||||||
|
|
||||||
|
call({String? key, String? deviceName}) => _res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class Input$UserMutationInput {
|
||||||
|
Input$UserMutationInput({required this.username, required this.password});
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Input$UserMutationInput.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$Input$UserMutationInputFromJson(json);
|
||||||
|
|
||||||
|
final String username;
|
||||||
|
|
||||||
|
final String password;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$Input$UserMutationInputToJson(this);
|
||||||
|
int get hashCode {
|
||||||
|
final l$username = username;
|
||||||
|
final l$password = password;
|
||||||
|
return Object.hashAll([l$username, l$password]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (!(other is Input$UserMutationInput) || runtimeType != other.runtimeType)
|
||||||
|
return false;
|
||||||
|
final l$username = username;
|
||||||
|
final lOther$username = other.username;
|
||||||
|
if (l$username != lOther$username) return false;
|
||||||
|
final l$password = password;
|
||||||
|
final lOther$password = other.password;
|
||||||
|
if (l$password != lOther$password) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyWith$Input$UserMutationInput<Input$UserMutationInput> get copyWith =>
|
||||||
|
CopyWith$Input$UserMutationInput(this, (i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CopyWith$Input$UserMutationInput<TRes> {
|
||||||
|
factory CopyWith$Input$UserMutationInput(Input$UserMutationInput instance,
|
||||||
|
TRes Function(Input$UserMutationInput) then) =
|
||||||
|
_CopyWithImpl$Input$UserMutationInput;
|
||||||
|
|
||||||
|
factory CopyWith$Input$UserMutationInput.stub(TRes res) =
|
||||||
|
_CopyWithStubImpl$Input$UserMutationInput;
|
||||||
|
|
||||||
|
TRes call({String? username, String? password});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithImpl$Input$UserMutationInput<TRes>
|
||||||
|
implements CopyWith$Input$UserMutationInput<TRes> {
|
||||||
|
_CopyWithImpl$Input$UserMutationInput(this._instance, this._then);
|
||||||
|
|
||||||
|
final Input$UserMutationInput _instance;
|
||||||
|
|
||||||
|
final TRes Function(Input$UserMutationInput) _then;
|
||||||
|
|
||||||
|
static const _undefined = {};
|
||||||
|
|
||||||
|
TRes call({Object? username = _undefined, Object? password = _undefined}) =>
|
||||||
|
_then(Input$UserMutationInput(
|
||||||
|
username: username == _undefined || username == null
|
||||||
|
? _instance.username
|
||||||
|
: (username as String),
|
||||||
|
password: password == _undefined || password == null
|
||||||
|
? _instance.password
|
||||||
|
: (password as String)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CopyWithStubImpl$Input$UserMutationInput<TRes>
|
||||||
|
implements CopyWith$Input$UserMutationInput<TRes> {
|
||||||
|
_CopyWithStubImpl$Input$UserMutationInput(this._res);
|
||||||
|
|
||||||
|
TRes _res;
|
||||||
|
|
||||||
|
call({String? username, String? password}) => _res;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Enum$DnsProvider {
|
||||||
|
@JsonValue('CLOUDFLARE')
|
||||||
|
CLOUDFLARE,
|
||||||
|
$unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Enum$ServerProvider {
|
||||||
|
@JsonValue('HETZNER')
|
||||||
|
HETZNER,
|
||||||
|
$unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Enum$ServiceStatusEnum {
|
||||||
|
@JsonValue('ACTIVATING')
|
||||||
|
ACTIVATING,
|
||||||
|
@JsonValue('ACTIVE')
|
||||||
|
ACTIVE,
|
||||||
|
@JsonValue('DEACTIVATING')
|
||||||
|
DEACTIVATING,
|
||||||
|
@JsonValue('FAILED')
|
||||||
|
FAILED,
|
||||||
|
@JsonValue('INACTIVE')
|
||||||
|
INACTIVE,
|
||||||
|
@JsonValue('OFF')
|
||||||
|
OFF,
|
||||||
|
@JsonValue('RELOADING')
|
||||||
|
RELOADING,
|
||||||
|
$unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Enum$Severity {
|
||||||
|
@JsonValue('CRITICAL')
|
||||||
|
CRITICAL,
|
||||||
|
@JsonValue('ERROR')
|
||||||
|
ERROR,
|
||||||
|
@JsonValue('INFO')
|
||||||
|
INFO,
|
||||||
|
@JsonValue('SUCCESS')
|
||||||
|
SUCCESS,
|
||||||
|
@JsonValue('WARNING')
|
||||||
|
WARNING,
|
||||||
|
$unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Enum$UserType {
|
||||||
|
@JsonValue('NORMAL')
|
||||||
|
NORMAL,
|
||||||
|
@JsonValue('PRIMARY')
|
||||||
|
PRIMARY,
|
||||||
|
@JsonValue('ROOT')
|
||||||
|
ROOT,
|
||||||
|
$unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
const possibleTypesMap = {
|
||||||
|
'MutationReturnInterface': {
|
||||||
|
'ApiKeyMutationReturn',
|
||||||
|
'AutoUpgradeSettingsMutationReturn',
|
||||||
|
'DeviceApiTokenMutationReturn',
|
||||||
|
'GenericJobButationReturn',
|
||||||
|
'GenericMutationReturn',
|
||||||
|
'ServiceJobMutationReturn',
|
||||||
|
'ServiceMutationReturn',
|
||||||
|
'TimezoneMutationReturn',
|
||||||
|
'UserMutationReturn'
|
||||||
|
},
|
||||||
|
'StorageUsageInterface': {'ServiceStorageUsage'}
|
||||||
|
};
|
||||||
|
DateTime? _nullable$dateTimeFromJson(dynamic data) =>
|
||||||
|
data == null ? null : dateTimeFromJson(data);
|
||||||
|
dynamic _nullable$dateTimeToJson(DateTime? data) =>
|
||||||
|
data == null ? null : dateTimeToJson(data);
|
125
lib/logic/api_maps/graphql_maps/schema/schema.graphql.g.dart
Normal file
125
lib/logic/api_maps/graphql_maps/schema/schema.graphql.g.dart
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'schema.graphql.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Input$AutoUpgradeSettingsInput _$Input$AutoUpgradeSettingsInputFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Input$AutoUpgradeSettingsInput(
|
||||||
|
enableAutoUpgrade: json['enableAutoUpgrade'] as bool?,
|
||||||
|
allowReboot: json['allowReboot'] as bool?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Input$AutoUpgradeSettingsInputToJson(
|
||||||
|
Input$AutoUpgradeSettingsInput instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'enableAutoUpgrade': instance.enableAutoUpgrade,
|
||||||
|
'allowReboot': instance.allowReboot,
|
||||||
|
};
|
||||||
|
|
||||||
|
Input$MigrateToBindsInput _$Input$MigrateToBindsInputFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Input$MigrateToBindsInput(
|
||||||
|
emailBlockDevice: json['emailBlockDevice'] as String,
|
||||||
|
bitwardenBlockDevice: json['bitwardenBlockDevice'] as String,
|
||||||
|
giteaBlockDevice: json['giteaBlockDevice'] as String,
|
||||||
|
nextcloudBlockDevice: json['nextcloudBlockDevice'] as String,
|
||||||
|
pleromaBlockDevice: json['pleromaBlockDevice'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Input$MigrateToBindsInputToJson(
|
||||||
|
Input$MigrateToBindsInput instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'emailBlockDevice': instance.emailBlockDevice,
|
||||||
|
'bitwardenBlockDevice': instance.bitwardenBlockDevice,
|
||||||
|
'giteaBlockDevice': instance.giteaBlockDevice,
|
||||||
|
'nextcloudBlockDevice': instance.nextcloudBlockDevice,
|
||||||
|
'pleromaBlockDevice': instance.pleromaBlockDevice,
|
||||||
|
};
|
||||||
|
|
||||||
|
Input$MoveServiceInput _$Input$MoveServiceInputFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Input$MoveServiceInput(
|
||||||
|
serviceId: json['serviceId'] as String,
|
||||||
|
location: json['location'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Input$MoveServiceInputToJson(
|
||||||
|
Input$MoveServiceInput instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'serviceId': instance.serviceId,
|
||||||
|
'location': instance.location,
|
||||||
|
};
|
||||||
|
|
||||||
|
Input$RecoveryKeyLimitsInput _$Input$RecoveryKeyLimitsInputFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Input$RecoveryKeyLimitsInput(
|
||||||
|
expirationDate: _nullable$dateTimeFromJson(json['expirationDate']),
|
||||||
|
uses: json['uses'] as int?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Input$RecoveryKeyLimitsInputToJson(
|
||||||
|
Input$RecoveryKeyLimitsInput instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'expirationDate': _nullable$dateTimeToJson(instance.expirationDate),
|
||||||
|
'uses': instance.uses,
|
||||||
|
};
|
||||||
|
|
||||||
|
Input$SshMutationInput _$Input$SshMutationInputFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Input$SshMutationInput(
|
||||||
|
username: json['username'] as String,
|
||||||
|
sshKey: json['sshKey'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Input$SshMutationInputToJson(
|
||||||
|
Input$SshMutationInput instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'username': instance.username,
|
||||||
|
'sshKey': instance.sshKey,
|
||||||
|
};
|
||||||
|
|
||||||
|
Input$UseNewDeviceKeyInput _$Input$UseNewDeviceKeyInputFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Input$UseNewDeviceKeyInput(
|
||||||
|
key: json['key'] as String,
|
||||||
|
deviceName: json['deviceName'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Input$UseNewDeviceKeyInputToJson(
|
||||||
|
Input$UseNewDeviceKeyInput instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'key': instance.key,
|
||||||
|
'deviceName': instance.deviceName,
|
||||||
|
};
|
||||||
|
|
||||||
|
Input$UseRecoveryKeyInput _$Input$UseRecoveryKeyInputFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Input$UseRecoveryKeyInput(
|
||||||
|
key: json['key'] as String,
|
||||||
|
deviceName: json['deviceName'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Input$UseRecoveryKeyInputToJson(
|
||||||
|
Input$UseRecoveryKeyInput instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'key': instance.key,
|
||||||
|
'deviceName': instance.deviceName,
|
||||||
|
};
|
||||||
|
|
||||||
|
Input$UserMutationInput _$Input$UserMutationInputFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Input$UserMutationInput(
|
||||||
|
username: json['username'] as String,
|
||||||
|
password: json['password'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Input$UserMutationInputToJson(
|
||||||
|
Input$UserMutationInput instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'username': instance.username,
|
||||||
|
'password': instance.password,
|
||||||
|
};
|
134
lib/logic/api_maps/graphql_maps/schema/server_api.graphql
Normal file
134
lib/logic/api_maps/graphql_maps/schema/server_api.graphql
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
fragment basicMutationReturnFields on MutationReturnInterface{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
|
||||||
|
query GetApiVersion {
|
||||||
|
api {
|
||||||
|
version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query GetApiJobs {
|
||||||
|
jobs {
|
||||||
|
getJobs {
|
||||||
|
createdAt
|
||||||
|
description
|
||||||
|
error
|
||||||
|
finishedAt
|
||||||
|
name
|
||||||
|
progress
|
||||||
|
result
|
||||||
|
status
|
||||||
|
statusText
|
||||||
|
uid
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation RemoveJob($jobId: String!) {
|
||||||
|
removeJob(jobId: $jobId) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation RunSystemRebuild {
|
||||||
|
runSystemRebuild {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation RunSystemRollback {
|
||||||
|
runSystemRollback {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation RunSystemUpgrade {
|
||||||
|
runSystemUpgrade {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation PullRepositoryChanges {
|
||||||
|
pullRepositoryChanges {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation RebootSystem {
|
||||||
|
rebootSystem {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query GetApiTokens {
|
||||||
|
api {
|
||||||
|
devices {
|
||||||
|
creationDate
|
||||||
|
isCaller
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query RecoveryKey {
|
||||||
|
api {
|
||||||
|
recoveryKey {
|
||||||
|
creationDate
|
||||||
|
exists
|
||||||
|
expirationDate
|
||||||
|
usesLeft
|
||||||
|
valid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation GetNewRecoveryApiKey($limits: RecoveryKeyLimitsInput) {
|
||||||
|
getNewRecoveryApiKey(limits: $limits) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation UseRecoveryApiKey($input: UseRecoveryKeyInput!) {
|
||||||
|
useRecoveryApiKey(input: $input) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation RefreshDeviceApiToken {
|
||||||
|
refreshDeviceApiToken {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation DeleteDeviceApiToken($device: String!) {
|
||||||
|
deleteDeviceApiToken(device: $device) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation GetNewDeviceApiKey {
|
||||||
|
getNewDeviceApiKey {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation InvalidateNewDeviceApiKey {
|
||||||
|
invalidateNewDeviceApiKey {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation AuthorizeWithNewDeviceApiKey($input: UseNewDeviceKeyInput!) {
|
||||||
|
authorizeWithNewDeviceApiKey(input: $input) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
token
|
||||||
|
}
|
||||||
|
}
|
7090
lib/logic/api_maps/graphql_maps/schema/server_api.graphql.dart
Normal file
7090
lib/logic/api_maps/graphql_maps/schema/server_api.graphql.dart
Normal file
File diff suppressed because it is too large
Load diff
745
lib/logic/api_maps/graphql_maps/schema/server_api.graphql.g.dart
Normal file
745
lib/logic/api_maps/graphql_maps/schema/server_api.graphql.g.dart
Normal file
|
@ -0,0 +1,745 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'server_api.graphql.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Fragment$basicMutationReturnFields _$Fragment$basicMutationReturnFieldsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Fragment$basicMutationReturnFields(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Fragment$basicMutationReturnFieldsToJson(
|
||||||
|
Fragment$basicMutationReturnFields instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetApiVersion _$Query$GetApiVersionFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$GetApiVersion(
|
||||||
|
api:
|
||||||
|
Query$GetApiVersion$api.fromJson(json['api'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetApiVersionToJson(
|
||||||
|
Query$GetApiVersion instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'api': instance.api.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetApiVersion$api _$Query$GetApiVersion$apiFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetApiVersion$api(
|
||||||
|
version: json['version'] as String,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetApiVersion$apiToJson(
|
||||||
|
Query$GetApiVersion$api instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'version': instance.version,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetApiJobs _$Query$GetApiJobsFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$GetApiJobs(
|
||||||
|
jobs:
|
||||||
|
Query$GetApiJobs$jobs.fromJson(json['jobs'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetApiJobsToJson(Query$GetApiJobs instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'jobs': instance.jobs.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetApiJobs$jobs _$Query$GetApiJobs$jobsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetApiJobs$jobs(
|
||||||
|
getJobs: (json['getJobs'] as List<dynamic>)
|
||||||
|
.map((e) =>
|
||||||
|
Query$GetApiJobs$jobs$getJobs.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetApiJobs$jobsToJson(
|
||||||
|
Query$GetApiJobs$jobs instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'getJobs': instance.getJobs.map((e) => e.toJson()).toList(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetApiJobs$jobs$getJobs _$Query$GetApiJobs$jobs$getJobsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetApiJobs$jobs$getJobs(
|
||||||
|
createdAt: dateTimeFromJson(json['createdAt']),
|
||||||
|
description: json['description'] as String,
|
||||||
|
error: json['error'] as String?,
|
||||||
|
finishedAt: _nullable$dateTimeFromJson(json['finishedAt']),
|
||||||
|
name: json['name'] as String,
|
||||||
|
progress: json['progress'] as int?,
|
||||||
|
result: json['result'] as String?,
|
||||||
|
status: json['status'] as String,
|
||||||
|
statusText: json['statusText'] as String?,
|
||||||
|
uid: json['uid'] as String,
|
||||||
|
updatedAt: dateTimeFromJson(json['updatedAt']),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetApiJobs$jobs$getJobsToJson(
|
||||||
|
Query$GetApiJobs$jobs$getJobs instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'createdAt': dateTimeToJson(instance.createdAt),
|
||||||
|
'description': instance.description,
|
||||||
|
'error': instance.error,
|
||||||
|
'finishedAt': _nullable$dateTimeToJson(instance.finishedAt),
|
||||||
|
'name': instance.name,
|
||||||
|
'progress': instance.progress,
|
||||||
|
'result': instance.result,
|
||||||
|
'status': instance.status,
|
||||||
|
'statusText': instance.statusText,
|
||||||
|
'uid': instance.uid,
|
||||||
|
'updatedAt': dateTimeToJson(instance.updatedAt),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$RemoveJob _$Variables$Mutation$RemoveJobFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$RemoveJob(
|
||||||
|
jobId: json['jobId'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$RemoveJobToJson(
|
||||||
|
Variables$Mutation$RemoveJob instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'jobId': instance.jobId,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RemoveJob _$Mutation$RemoveJobFromJson(Map<String, dynamic> json) =>
|
||||||
|
Mutation$RemoveJob(
|
||||||
|
removeJob: Mutation$RemoveJob$removeJob.fromJson(
|
||||||
|
json['removeJob'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RemoveJobToJson(Mutation$RemoveJob instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'removeJob': instance.removeJob.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RemoveJob$removeJob _$Mutation$RemoveJob$removeJobFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RemoveJob$removeJob(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RemoveJob$removeJobToJson(
|
||||||
|
Mutation$RemoveJob$removeJob instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RunSystemRebuild _$Mutation$RunSystemRebuildFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RunSystemRebuild(
|
||||||
|
runSystemRebuild: Mutation$RunSystemRebuild$runSystemRebuild.fromJson(
|
||||||
|
json['runSystemRebuild'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RunSystemRebuildToJson(
|
||||||
|
Mutation$RunSystemRebuild instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'runSystemRebuild': instance.runSystemRebuild.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RunSystemRebuild$runSystemRebuild
|
||||||
|
_$Mutation$RunSystemRebuild$runSystemRebuildFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RunSystemRebuild$runSystemRebuild(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RunSystemRebuild$runSystemRebuildToJson(
|
||||||
|
Mutation$RunSystemRebuild$runSystemRebuild instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RunSystemRollback _$Mutation$RunSystemRollbackFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RunSystemRollback(
|
||||||
|
runSystemRollback: Mutation$RunSystemRollback$runSystemRollback.fromJson(
|
||||||
|
json['runSystemRollback'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RunSystemRollbackToJson(
|
||||||
|
Mutation$RunSystemRollback instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'runSystemRollback': instance.runSystemRollback.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RunSystemRollback$runSystemRollback
|
||||||
|
_$Mutation$RunSystemRollback$runSystemRollbackFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RunSystemRollback$runSystemRollback(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RunSystemRollback$runSystemRollbackToJson(
|
||||||
|
Mutation$RunSystemRollback$runSystemRollback instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RunSystemUpgrade _$Mutation$RunSystemUpgradeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RunSystemUpgrade(
|
||||||
|
runSystemUpgrade: Mutation$RunSystemUpgrade$runSystemUpgrade.fromJson(
|
||||||
|
json['runSystemUpgrade'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RunSystemUpgradeToJson(
|
||||||
|
Mutation$RunSystemUpgrade instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'runSystemUpgrade': instance.runSystemUpgrade.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RunSystemUpgrade$runSystemUpgrade
|
||||||
|
_$Mutation$RunSystemUpgrade$runSystemUpgradeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RunSystemUpgrade$runSystemUpgrade(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RunSystemUpgrade$runSystemUpgradeToJson(
|
||||||
|
Mutation$RunSystemUpgrade$runSystemUpgrade instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$PullRepositoryChanges _$Mutation$PullRepositoryChangesFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$PullRepositoryChanges(
|
||||||
|
pullRepositoryChanges:
|
||||||
|
Mutation$PullRepositoryChanges$pullRepositoryChanges.fromJson(
|
||||||
|
json['pullRepositoryChanges'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$PullRepositoryChangesToJson(
|
||||||
|
Mutation$PullRepositoryChanges instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'pullRepositoryChanges': instance.pullRepositoryChanges.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$PullRepositoryChanges$pullRepositoryChanges
|
||||||
|
_$Mutation$PullRepositoryChanges$pullRepositoryChangesFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$PullRepositoryChanges$pullRepositoryChanges(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic>
|
||||||
|
_$Mutation$PullRepositoryChanges$pullRepositoryChangesToJson(
|
||||||
|
Mutation$PullRepositoryChanges$pullRepositoryChanges instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RebootSystem _$Mutation$RebootSystemFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RebootSystem(
|
||||||
|
rebootSystem: Mutation$RebootSystem$rebootSystem.fromJson(
|
||||||
|
json['rebootSystem'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RebootSystemToJson(
|
||||||
|
Mutation$RebootSystem instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'rebootSystem': instance.rebootSystem.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RebootSystem$rebootSystem _$Mutation$RebootSystem$rebootSystemFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RebootSystem$rebootSystem(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RebootSystem$rebootSystemToJson(
|
||||||
|
Mutation$RebootSystem$rebootSystem instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetApiTokens _$Query$GetApiTokensFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$GetApiTokens(
|
||||||
|
api: Query$GetApiTokens$api.fromJson(json['api'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetApiTokensToJson(Query$GetApiTokens instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'api': instance.api.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetApiTokens$api _$Query$GetApiTokens$apiFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetApiTokens$api(
|
||||||
|
devices: (json['devices'] as List<dynamic>)
|
||||||
|
.map((e) => Query$GetApiTokens$api$devices.fromJson(
|
||||||
|
e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetApiTokens$apiToJson(
|
||||||
|
Query$GetApiTokens$api instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'devices': instance.devices.map((e) => e.toJson()).toList(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetApiTokens$api$devices _$Query$GetApiTokens$api$devicesFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$GetApiTokens$api$devices(
|
||||||
|
creationDate: dateTimeFromJson(json['creationDate']),
|
||||||
|
isCaller: json['isCaller'] as bool,
|
||||||
|
name: json['name'] as String,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetApiTokens$api$devicesToJson(
|
||||||
|
Query$GetApiTokens$api$devices instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'creationDate': dateTimeToJson(instance.creationDate),
|
||||||
|
'isCaller': instance.isCaller,
|
||||||
|
'name': instance.name,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$RecoveryKey _$Query$RecoveryKeyFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$RecoveryKey(
|
||||||
|
api: Query$RecoveryKey$api.fromJson(json['api'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$RecoveryKeyToJson(Query$RecoveryKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'api': instance.api.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$RecoveryKey$api _$Query$RecoveryKey$apiFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$RecoveryKey$api(
|
||||||
|
recoveryKey: Query$RecoveryKey$api$recoveryKey.fromJson(
|
||||||
|
json['recoveryKey'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$RecoveryKey$apiToJson(
|
||||||
|
Query$RecoveryKey$api instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'recoveryKey': instance.recoveryKey.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$RecoveryKey$api$recoveryKey _$Query$RecoveryKey$api$recoveryKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$RecoveryKey$api$recoveryKey(
|
||||||
|
creationDate: _nullable$dateTimeFromJson(json['creationDate']),
|
||||||
|
exists: json['exists'] as bool,
|
||||||
|
expirationDate: _nullable$dateTimeFromJson(json['expirationDate']),
|
||||||
|
usesLeft: json['usesLeft'] as int?,
|
||||||
|
valid: json['valid'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$RecoveryKey$api$recoveryKeyToJson(
|
||||||
|
Query$RecoveryKey$api$recoveryKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'creationDate': _nullable$dateTimeToJson(instance.creationDate),
|
||||||
|
'exists': instance.exists,
|
||||||
|
'expirationDate': _nullable$dateTimeToJson(instance.expirationDate),
|
||||||
|
'usesLeft': instance.usesLeft,
|
||||||
|
'valid': instance.valid,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$GetNewRecoveryApiKey
|
||||||
|
_$Variables$Mutation$GetNewRecoveryApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$GetNewRecoveryApiKey(
|
||||||
|
limits: json['limits'] == null
|
||||||
|
? null
|
||||||
|
: Input$RecoveryKeyLimitsInput.fromJson(
|
||||||
|
json['limits'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$GetNewRecoveryApiKeyToJson(
|
||||||
|
Variables$Mutation$GetNewRecoveryApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'limits': instance.limits?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$GetNewRecoveryApiKey _$Mutation$GetNewRecoveryApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$GetNewRecoveryApiKey(
|
||||||
|
getNewRecoveryApiKey:
|
||||||
|
Mutation$GetNewRecoveryApiKey$getNewRecoveryApiKey.fromJson(
|
||||||
|
json['getNewRecoveryApiKey'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$GetNewRecoveryApiKeyToJson(
|
||||||
|
Mutation$GetNewRecoveryApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'getNewRecoveryApiKey': instance.getNewRecoveryApiKey.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$GetNewRecoveryApiKey$getNewRecoveryApiKey
|
||||||
|
_$Mutation$GetNewRecoveryApiKey$getNewRecoveryApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$GetNewRecoveryApiKey$getNewRecoveryApiKey(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
key: json['key'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$GetNewRecoveryApiKey$getNewRecoveryApiKeyToJson(
|
||||||
|
Mutation$GetNewRecoveryApiKey$getNewRecoveryApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'key': instance.key,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$UseRecoveryApiKey
|
||||||
|
_$Variables$Mutation$UseRecoveryApiKeyFromJson(Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$UseRecoveryApiKey(
|
||||||
|
input: Input$UseRecoveryKeyInput.fromJson(
|
||||||
|
json['input'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$UseRecoveryApiKeyToJson(
|
||||||
|
Variables$Mutation$UseRecoveryApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'input': instance.input.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$UseRecoveryApiKey _$Mutation$UseRecoveryApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$UseRecoveryApiKey(
|
||||||
|
useRecoveryApiKey: Mutation$UseRecoveryApiKey$useRecoveryApiKey.fromJson(
|
||||||
|
json['useRecoveryApiKey'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$UseRecoveryApiKeyToJson(
|
||||||
|
Mutation$UseRecoveryApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'useRecoveryApiKey': instance.useRecoveryApiKey.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$UseRecoveryApiKey$useRecoveryApiKey
|
||||||
|
_$Mutation$UseRecoveryApiKey$useRecoveryApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$UseRecoveryApiKey$useRecoveryApiKey(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
token: json['token'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$UseRecoveryApiKey$useRecoveryApiKeyToJson(
|
||||||
|
Mutation$UseRecoveryApiKey$useRecoveryApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'token': instance.token,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RefreshDeviceApiToken _$Mutation$RefreshDeviceApiTokenFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RefreshDeviceApiToken(
|
||||||
|
refreshDeviceApiToken:
|
||||||
|
Mutation$RefreshDeviceApiToken$refreshDeviceApiToken.fromJson(
|
||||||
|
json['refreshDeviceApiToken'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RefreshDeviceApiTokenToJson(
|
||||||
|
Mutation$RefreshDeviceApiToken instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'refreshDeviceApiToken': instance.refreshDeviceApiToken.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RefreshDeviceApiToken$refreshDeviceApiToken
|
||||||
|
_$Mutation$RefreshDeviceApiToken$refreshDeviceApiTokenFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RefreshDeviceApiToken$refreshDeviceApiToken(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
token: json['token'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic>
|
||||||
|
_$Mutation$RefreshDeviceApiToken$refreshDeviceApiTokenToJson(
|
||||||
|
Mutation$RefreshDeviceApiToken$refreshDeviceApiToken instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'token': instance.token,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$DeleteDeviceApiToken
|
||||||
|
_$Variables$Mutation$DeleteDeviceApiTokenFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$DeleteDeviceApiToken(
|
||||||
|
device: json['device'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$DeleteDeviceApiTokenToJson(
|
||||||
|
Variables$Mutation$DeleteDeviceApiToken instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'device': instance.device,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$DeleteDeviceApiToken _$Mutation$DeleteDeviceApiTokenFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$DeleteDeviceApiToken(
|
||||||
|
deleteDeviceApiToken:
|
||||||
|
Mutation$DeleteDeviceApiToken$deleteDeviceApiToken.fromJson(
|
||||||
|
json['deleteDeviceApiToken'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$DeleteDeviceApiTokenToJson(
|
||||||
|
Mutation$DeleteDeviceApiToken instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'deleteDeviceApiToken': instance.deleteDeviceApiToken.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$DeleteDeviceApiToken$deleteDeviceApiToken
|
||||||
|
_$Mutation$DeleteDeviceApiToken$deleteDeviceApiTokenFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$DeleteDeviceApiToken$deleteDeviceApiToken(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$DeleteDeviceApiToken$deleteDeviceApiTokenToJson(
|
||||||
|
Mutation$DeleteDeviceApiToken$deleteDeviceApiToken instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$GetNewDeviceApiKey _$Mutation$GetNewDeviceApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$GetNewDeviceApiKey(
|
||||||
|
getNewDeviceApiKey:
|
||||||
|
Mutation$GetNewDeviceApiKey$getNewDeviceApiKey.fromJson(
|
||||||
|
json['getNewDeviceApiKey'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$GetNewDeviceApiKeyToJson(
|
||||||
|
Mutation$GetNewDeviceApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'getNewDeviceApiKey': instance.getNewDeviceApiKey.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$GetNewDeviceApiKey$getNewDeviceApiKey
|
||||||
|
_$Mutation$GetNewDeviceApiKey$getNewDeviceApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$GetNewDeviceApiKey$getNewDeviceApiKey(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
key: json['key'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$GetNewDeviceApiKey$getNewDeviceApiKeyToJson(
|
||||||
|
Mutation$GetNewDeviceApiKey$getNewDeviceApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'key': instance.key,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$InvalidateNewDeviceApiKey _$Mutation$InvalidateNewDeviceApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$InvalidateNewDeviceApiKey(
|
||||||
|
invalidateNewDeviceApiKey:
|
||||||
|
Mutation$InvalidateNewDeviceApiKey$invalidateNewDeviceApiKey.fromJson(
|
||||||
|
json['invalidateNewDeviceApiKey'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$InvalidateNewDeviceApiKeyToJson(
|
||||||
|
Mutation$InvalidateNewDeviceApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'invalidateNewDeviceApiKey': instance.invalidateNewDeviceApiKey.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$InvalidateNewDeviceApiKey$invalidateNewDeviceApiKey
|
||||||
|
_$Mutation$InvalidateNewDeviceApiKey$invalidateNewDeviceApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$InvalidateNewDeviceApiKey$invalidateNewDeviceApiKey(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic>
|
||||||
|
_$Mutation$InvalidateNewDeviceApiKey$invalidateNewDeviceApiKeyToJson(
|
||||||
|
Mutation$InvalidateNewDeviceApiKey$invalidateNewDeviceApiKey
|
||||||
|
instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$AuthorizeWithNewDeviceApiKey
|
||||||
|
_$Variables$Mutation$AuthorizeWithNewDeviceApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$AuthorizeWithNewDeviceApiKey(
|
||||||
|
input: Input$UseNewDeviceKeyInput.fromJson(
|
||||||
|
json['input'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$AuthorizeWithNewDeviceApiKeyToJson(
|
||||||
|
Variables$Mutation$AuthorizeWithNewDeviceApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'input': instance.input.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$AuthorizeWithNewDeviceApiKey
|
||||||
|
_$Mutation$AuthorizeWithNewDeviceApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$AuthorizeWithNewDeviceApiKey(
|
||||||
|
authorizeWithNewDeviceApiKey:
|
||||||
|
Mutation$AuthorizeWithNewDeviceApiKey$authorizeWithNewDeviceApiKey
|
||||||
|
.fromJson(json['authorizeWithNewDeviceApiKey']
|
||||||
|
as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$AuthorizeWithNewDeviceApiKeyToJson(
|
||||||
|
Mutation$AuthorizeWithNewDeviceApiKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'authorizeWithNewDeviceApiKey':
|
||||||
|
instance.authorizeWithNewDeviceApiKey.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$AuthorizeWithNewDeviceApiKey$authorizeWithNewDeviceApiKey
|
||||||
|
_$Mutation$AuthorizeWithNewDeviceApiKey$authorizeWithNewDeviceApiKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$AuthorizeWithNewDeviceApiKey$authorizeWithNewDeviceApiKey(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
token: json['token'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic>
|
||||||
|
_$Mutation$AuthorizeWithNewDeviceApiKey$authorizeWithNewDeviceApiKeyToJson(
|
||||||
|
Mutation$AuthorizeWithNewDeviceApiKey$authorizeWithNewDeviceApiKey
|
||||||
|
instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'token': instance.token,
|
||||||
|
};
|
|
@ -0,0 +1,61 @@
|
||||||
|
fragment basicMutationReturnFields on MutationReturnInterface{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
|
||||||
|
query SystemSettings {
|
||||||
|
system {
|
||||||
|
settings {
|
||||||
|
autoUpgrade {
|
||||||
|
allowReboot
|
||||||
|
enable
|
||||||
|
}
|
||||||
|
ssh {
|
||||||
|
enable
|
||||||
|
passwordAuthentication
|
||||||
|
}
|
||||||
|
timezone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query SystemIsUsingBinds {
|
||||||
|
system {
|
||||||
|
info {
|
||||||
|
usingBinds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query DomainInfo {
|
||||||
|
system {
|
||||||
|
domainInfo {
|
||||||
|
domain
|
||||||
|
hostname
|
||||||
|
provider
|
||||||
|
requiredDnsRecords {
|
||||||
|
content
|
||||||
|
name
|
||||||
|
priority
|
||||||
|
recordType
|
||||||
|
ttl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation ChangeTimezone($timezone: String!) {
|
||||||
|
changeTimezone(timezone: $timezone) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
timezone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation ChangeAutoUpgradeSettings($settings: AutoUpgradeSettingsInput!) {
|
||||||
|
changeAutoUpgradeSettings(settings: $settings) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
allowReboot
|
||||||
|
enableAutoUpgrade
|
||||||
|
}
|
||||||
|
}
|
2960
lib/logic/api_maps/graphql_maps/schema/server_settings.graphql.dart
Normal file
2960
lib/logic/api_maps/graphql_maps/schema/server_settings.graphql.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,340 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'server_settings.graphql.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Fragment$basicMutationReturnFields _$Fragment$basicMutationReturnFieldsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Fragment$basicMutationReturnFields(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Fragment$basicMutationReturnFieldsToJson(
|
||||||
|
Fragment$basicMutationReturnFields instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$SystemSettings _$Query$SystemSettingsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$SystemSettings(
|
||||||
|
system: Query$SystemSettings$system.fromJson(
|
||||||
|
json['system'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$SystemSettingsToJson(
|
||||||
|
Query$SystemSettings instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'system': instance.system.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$SystemSettings$system _$Query$SystemSettings$systemFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$SystemSettings$system(
|
||||||
|
settings: Query$SystemSettings$system$settings.fromJson(
|
||||||
|
json['settings'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$SystemSettings$systemToJson(
|
||||||
|
Query$SystemSettings$system instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'settings': instance.settings.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$SystemSettings$system$settings
|
||||||
|
_$Query$SystemSettings$system$settingsFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$SystemSettings$system$settings(
|
||||||
|
autoUpgrade:
|
||||||
|
Query$SystemSettings$system$settings$autoUpgrade.fromJson(
|
||||||
|
json['autoUpgrade'] as Map<String, dynamic>),
|
||||||
|
ssh: Query$SystemSettings$system$settings$ssh.fromJson(
|
||||||
|
json['ssh'] as Map<String, dynamic>),
|
||||||
|
timezone: json['timezone'] as String,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$SystemSettings$system$settingsToJson(
|
||||||
|
Query$SystemSettings$system$settings instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'autoUpgrade': instance.autoUpgrade.toJson(),
|
||||||
|
'ssh': instance.ssh.toJson(),
|
||||||
|
'timezone': instance.timezone,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$SystemSettings$system$settings$autoUpgrade
|
||||||
|
_$Query$SystemSettings$system$settings$autoUpgradeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$SystemSettings$system$settings$autoUpgrade(
|
||||||
|
allowReboot: json['allowReboot'] as bool,
|
||||||
|
enable: json['enable'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$SystemSettings$system$settings$autoUpgradeToJson(
|
||||||
|
Query$SystemSettings$system$settings$autoUpgrade instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'allowReboot': instance.allowReboot,
|
||||||
|
'enable': instance.enable,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$SystemSettings$system$settings$ssh
|
||||||
|
_$Query$SystemSettings$system$settings$sshFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$SystemSettings$system$settings$ssh(
|
||||||
|
enable: json['enable'] as bool,
|
||||||
|
passwordAuthentication: json['passwordAuthentication'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$SystemSettings$system$settings$sshToJson(
|
||||||
|
Query$SystemSettings$system$settings$ssh instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'enable': instance.enable,
|
||||||
|
'passwordAuthentication': instance.passwordAuthentication,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$SystemIsUsingBinds _$Query$SystemIsUsingBindsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$SystemIsUsingBinds(
|
||||||
|
system: Query$SystemIsUsingBinds$system.fromJson(
|
||||||
|
json['system'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$SystemIsUsingBindsToJson(
|
||||||
|
Query$SystemIsUsingBinds instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'system': instance.system.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$SystemIsUsingBinds$system _$Query$SystemIsUsingBinds$systemFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$SystemIsUsingBinds$system(
|
||||||
|
info: Query$SystemIsUsingBinds$system$info.fromJson(
|
||||||
|
json['info'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$SystemIsUsingBinds$systemToJson(
|
||||||
|
Query$SystemIsUsingBinds$system instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'info': instance.info.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$SystemIsUsingBinds$system$info
|
||||||
|
_$Query$SystemIsUsingBinds$system$infoFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$SystemIsUsingBinds$system$info(
|
||||||
|
usingBinds: json['usingBinds'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$SystemIsUsingBinds$system$infoToJson(
|
||||||
|
Query$SystemIsUsingBinds$system$info instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'usingBinds': instance.usingBinds,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$DomainInfo _$Query$DomainInfoFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$DomainInfo(
|
||||||
|
system: Query$DomainInfo$system.fromJson(
|
||||||
|
json['system'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$DomainInfoToJson(Query$DomainInfo instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'system': instance.system.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$DomainInfo$system _$Query$DomainInfo$systemFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$DomainInfo$system(
|
||||||
|
domainInfo: Query$DomainInfo$system$domainInfo.fromJson(
|
||||||
|
json['domainInfo'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$DomainInfo$systemToJson(
|
||||||
|
Query$DomainInfo$system instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'domainInfo': instance.domainInfo.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$DomainInfo$system$domainInfo _$Query$DomainInfo$system$domainInfoFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$DomainInfo$system$domainInfo(
|
||||||
|
domain: json['domain'] as String,
|
||||||
|
hostname: json['hostname'] as String,
|
||||||
|
provider: $enumDecode(_$Enum$DnsProviderEnumMap, json['provider'],
|
||||||
|
unknownValue: Enum$DnsProvider.$unknown),
|
||||||
|
requiredDnsRecords: (json['requiredDnsRecords'] as List<dynamic>)
|
||||||
|
.map((e) =>
|
||||||
|
Query$DomainInfo$system$domainInfo$requiredDnsRecords.fromJson(
|
||||||
|
e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$DomainInfo$system$domainInfoToJson(
|
||||||
|
Query$DomainInfo$system$domainInfo instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'domain': instance.domain,
|
||||||
|
'hostname': instance.hostname,
|
||||||
|
'provider': _$Enum$DnsProviderEnumMap[instance.provider]!,
|
||||||
|
'requiredDnsRecords':
|
||||||
|
instance.requiredDnsRecords.map((e) => e.toJson()).toList(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
const _$Enum$DnsProviderEnumMap = {
|
||||||
|
Enum$DnsProvider.CLOUDFLARE: 'CLOUDFLARE',
|
||||||
|
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(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$ChangeTimezone(
|
||||||
|
timezone: json['timezone'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$ChangeTimezoneToJson(
|
||||||
|
Variables$Mutation$ChangeTimezone instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'timezone': instance.timezone,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$ChangeTimezone _$Mutation$ChangeTimezoneFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$ChangeTimezone(
|
||||||
|
changeTimezone: Mutation$ChangeTimezone$changeTimezone.fromJson(
|
||||||
|
json['changeTimezone'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$ChangeTimezoneToJson(
|
||||||
|
Mutation$ChangeTimezone instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'changeTimezone': instance.changeTimezone.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$ChangeTimezone$changeTimezone
|
||||||
|
_$Mutation$ChangeTimezone$changeTimezoneFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$ChangeTimezone$changeTimezone(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
timezone: json['timezone'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$ChangeTimezone$changeTimezoneToJson(
|
||||||
|
Mutation$ChangeTimezone$changeTimezone instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'timezone': instance.timezone,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$ChangeAutoUpgradeSettings
|
||||||
|
_$Variables$Mutation$ChangeAutoUpgradeSettingsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$ChangeAutoUpgradeSettings(
|
||||||
|
settings: Input$AutoUpgradeSettingsInput.fromJson(
|
||||||
|
json['settings'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$ChangeAutoUpgradeSettingsToJson(
|
||||||
|
Variables$Mutation$ChangeAutoUpgradeSettings instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'settings': instance.settings.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$ChangeAutoUpgradeSettings _$Mutation$ChangeAutoUpgradeSettingsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$ChangeAutoUpgradeSettings(
|
||||||
|
changeAutoUpgradeSettings:
|
||||||
|
Mutation$ChangeAutoUpgradeSettings$changeAutoUpgradeSettings.fromJson(
|
||||||
|
json['changeAutoUpgradeSettings'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$ChangeAutoUpgradeSettingsToJson(
|
||||||
|
Mutation$ChangeAutoUpgradeSettings instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'changeAutoUpgradeSettings': instance.changeAutoUpgradeSettings.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$ChangeAutoUpgradeSettings$changeAutoUpgradeSettings
|
||||||
|
_$Mutation$ChangeAutoUpgradeSettings$changeAutoUpgradeSettingsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$ChangeAutoUpgradeSettings$changeAutoUpgradeSettings(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
allowReboot: json['allowReboot'] as bool,
|
||||||
|
enableAutoUpgrade: json['enableAutoUpgrade'] as bool,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic>
|
||||||
|
_$Mutation$ChangeAutoUpgradeSettings$changeAutoUpgradeSettingsToJson(
|
||||||
|
Mutation$ChangeAutoUpgradeSettings$changeAutoUpgradeSettings
|
||||||
|
instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'allowReboot': instance.allowReboot,
|
||||||
|
'enableAutoUpgrade': instance.enableAutoUpgrade,
|
||||||
|
};
|
84
lib/logic/api_maps/graphql_maps/schema/services.graphql
Normal file
84
lib/logic/api_maps/graphql_maps/schema/services.graphql
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
fragment basicMutationReturnFields on MutationReturnInterface{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
|
||||||
|
query AllServices {
|
||||||
|
services {
|
||||||
|
allServices {
|
||||||
|
description
|
||||||
|
displayName
|
||||||
|
dnsRecords {
|
||||||
|
content
|
||||||
|
name
|
||||||
|
priority
|
||||||
|
recordType
|
||||||
|
ttl
|
||||||
|
}
|
||||||
|
id
|
||||||
|
isEnabled
|
||||||
|
isMovable
|
||||||
|
isRequired
|
||||||
|
status
|
||||||
|
storageUsage {
|
||||||
|
title
|
||||||
|
usedSpace
|
||||||
|
volume {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
svgIcon
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation EnableService($serviceId: String!) {
|
||||||
|
enableService(serviceId: $serviceId) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation DisableService($serviceId: String!) {
|
||||||
|
disableService(serviceId: $serviceId) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation StopService($serviceId: String!) {
|
||||||
|
stopService(serviceId: $serviceId) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation StartService($serviceId: String!) {
|
||||||
|
startService(serviceId: $serviceId) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation RestartService($serviceId: String!) {
|
||||||
|
restartService(serviceId: $serviceId) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation MoveService($input: MoveServiceInput!) {
|
||||||
|
moveService(input: $input) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
job {
|
||||||
|
createdAt
|
||||||
|
description
|
||||||
|
error
|
||||||
|
finishedAt
|
||||||
|
name
|
||||||
|
progress
|
||||||
|
result
|
||||||
|
status
|
||||||
|
statusText
|
||||||
|
uid
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4154
lib/logic/api_maps/graphql_maps/schema/services.graphql.dart
Normal file
4154
lib/logic/api_maps/graphql_maps/schema/services.graphql.dart
Normal file
File diff suppressed because it is too large
Load diff
482
lib/logic/api_maps/graphql_maps/schema/services.graphql.g.dart
Normal file
482
lib/logic/api_maps/graphql_maps/schema/services.graphql.g.dart
Normal file
|
@ -0,0 +1,482 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'services.graphql.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Fragment$basicMutationReturnFields _$Fragment$basicMutationReturnFieldsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Fragment$basicMutationReturnFields(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Fragment$basicMutationReturnFieldsToJson(
|
||||||
|
Fragment$basicMutationReturnFields instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$AllServices _$Query$AllServicesFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$AllServices(
|
||||||
|
services: Query$AllServices$services.fromJson(
|
||||||
|
json['services'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$AllServicesToJson(Query$AllServices instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'services': instance.services.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$AllServices$services _$Query$AllServices$servicesFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$AllServices$services(
|
||||||
|
allServices: (json['allServices'] as List<dynamic>)
|
||||||
|
.map((e) => Query$AllServices$services$allServices.fromJson(
|
||||||
|
e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$AllServices$servicesToJson(
|
||||||
|
Query$AllServices$services instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'allServices': instance.allServices.map((e) => e.toJson()).toList(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$AllServices$services$allServices
|
||||||
|
_$Query$AllServices$services$allServicesFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$AllServices$services$allServices(
|
||||||
|
description: json['description'] as String,
|
||||||
|
displayName: json['displayName'] as String,
|
||||||
|
dnsRecords: (json['dnsRecords'] as List<dynamic>?)
|
||||||
|
?.map((e) =>
|
||||||
|
Query$AllServices$services$allServices$dnsRecords.fromJson(
|
||||||
|
e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
id: json['id'] as String,
|
||||||
|
isEnabled: json['isEnabled'] as bool,
|
||||||
|
isMovable: json['isMovable'] as bool,
|
||||||
|
isRequired: json['isRequired'] as bool,
|
||||||
|
status: $enumDecode(_$Enum$ServiceStatusEnumEnumMap, json['status'],
|
||||||
|
unknownValue: Enum$ServiceStatusEnum.$unknown),
|
||||||
|
storageUsage:
|
||||||
|
Query$AllServices$services$allServices$storageUsage.fromJson(
|
||||||
|
json['storageUsage'] as Map<String, dynamic>),
|
||||||
|
svgIcon: json['svgIcon'] as String,
|
||||||
|
url: json['url'] as String?,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$AllServices$services$allServicesToJson(
|
||||||
|
Query$AllServices$services$allServices instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'description': instance.description,
|
||||||
|
'displayName': instance.displayName,
|
||||||
|
'dnsRecords': instance.dnsRecords?.map((e) => e.toJson()).toList(),
|
||||||
|
'id': instance.id,
|
||||||
|
'isEnabled': instance.isEnabled,
|
||||||
|
'isMovable': instance.isMovable,
|
||||||
|
'isRequired': instance.isRequired,
|
||||||
|
'status': _$Enum$ServiceStatusEnumEnumMap[instance.status]!,
|
||||||
|
'storageUsage': instance.storageUsage.toJson(),
|
||||||
|
'svgIcon': instance.svgIcon,
|
||||||
|
'url': instance.url,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
const _$Enum$ServiceStatusEnumEnumMap = {
|
||||||
|
Enum$ServiceStatusEnum.ACTIVATING: 'ACTIVATING',
|
||||||
|
Enum$ServiceStatusEnum.ACTIVE: 'ACTIVE',
|
||||||
|
Enum$ServiceStatusEnum.DEACTIVATING: 'DEACTIVATING',
|
||||||
|
Enum$ServiceStatusEnum.FAILED: 'FAILED',
|
||||||
|
Enum$ServiceStatusEnum.INACTIVE: 'INACTIVE',
|
||||||
|
Enum$ServiceStatusEnum.OFF: 'OFF',
|
||||||
|
Enum$ServiceStatusEnum.RELOADING: 'RELOADING',
|
||||||
|
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$storageUsageFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$AllServices$services$allServices$storageUsage(
|
||||||
|
title: json['title'] as String,
|
||||||
|
usedSpace: json['usedSpace'] as String,
|
||||||
|
volume: json['volume'] == null
|
||||||
|
? null
|
||||||
|
: Query$AllServices$services$allServices$storageUsage$volume
|
||||||
|
.fromJson(json['volume'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic>
|
||||||
|
_$Query$AllServices$services$allServices$storageUsageToJson(
|
||||||
|
Query$AllServices$services$allServices$storageUsage instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'title': instance.title,
|
||||||
|
'usedSpace': instance.usedSpace,
|
||||||
|
'volume': instance.volume?.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$AllServices$services$allServices$storageUsage$volume
|
||||||
|
_$Query$AllServices$services$allServices$storageUsage$volumeFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$AllServices$services$allServices$storageUsage$volume(
|
||||||
|
name: json['name'] as String,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String,
|
||||||
|
dynamic> _$Query$AllServices$services$allServices$storageUsage$volumeToJson(
|
||||||
|
Query$AllServices$services$allServices$storageUsage$volume instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'name': instance.name,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$EnableService _$Variables$Mutation$EnableServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$EnableService(
|
||||||
|
serviceId: json['serviceId'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$EnableServiceToJson(
|
||||||
|
Variables$Mutation$EnableService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'serviceId': instance.serviceId,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$EnableService _$Mutation$EnableServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$EnableService(
|
||||||
|
enableService: Mutation$EnableService$enableService.fromJson(
|
||||||
|
json['enableService'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$EnableServiceToJson(
|
||||||
|
Mutation$EnableService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'enableService': instance.enableService.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$EnableService$enableService
|
||||||
|
_$Mutation$EnableService$enableServiceFromJson(Map<String, dynamic> json) =>
|
||||||
|
Mutation$EnableService$enableService(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$EnableService$enableServiceToJson(
|
||||||
|
Mutation$EnableService$enableService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$DisableService _$Variables$Mutation$DisableServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$DisableService(
|
||||||
|
serviceId: json['serviceId'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$DisableServiceToJson(
|
||||||
|
Variables$Mutation$DisableService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'serviceId': instance.serviceId,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$DisableService _$Mutation$DisableServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$DisableService(
|
||||||
|
disableService: Mutation$DisableService$disableService.fromJson(
|
||||||
|
json['disableService'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$DisableServiceToJson(
|
||||||
|
Mutation$DisableService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'disableService': instance.disableService.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$DisableService$disableService
|
||||||
|
_$Mutation$DisableService$disableServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$DisableService$disableService(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$DisableService$disableServiceToJson(
|
||||||
|
Mutation$DisableService$disableService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$StopService _$Variables$Mutation$StopServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$StopService(
|
||||||
|
serviceId: json['serviceId'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$StopServiceToJson(
|
||||||
|
Variables$Mutation$StopService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'serviceId': instance.serviceId,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$StopService _$Mutation$StopServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$StopService(
|
||||||
|
stopService: Mutation$StopService$stopService.fromJson(
|
||||||
|
json['stopService'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$StopServiceToJson(
|
||||||
|
Mutation$StopService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'stopService': instance.stopService.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$StopService$stopService _$Mutation$StopService$stopServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$StopService$stopService(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$StopService$stopServiceToJson(
|
||||||
|
Mutation$StopService$stopService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$StartService _$Variables$Mutation$StartServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$StartService(
|
||||||
|
serviceId: json['serviceId'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$StartServiceToJson(
|
||||||
|
Variables$Mutation$StartService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'serviceId': instance.serviceId,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$StartService _$Mutation$StartServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$StartService(
|
||||||
|
startService: Mutation$StartService$startService.fromJson(
|
||||||
|
json['startService'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$StartServiceToJson(
|
||||||
|
Mutation$StartService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'startService': instance.startService.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$StartService$startService _$Mutation$StartService$startServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$StartService$startService(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$StartService$startServiceToJson(
|
||||||
|
Mutation$StartService$startService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$RestartService _$Variables$Mutation$RestartServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$RestartService(
|
||||||
|
serviceId: json['serviceId'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$RestartServiceToJson(
|
||||||
|
Variables$Mutation$RestartService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'serviceId': instance.serviceId,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RestartService _$Mutation$RestartServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RestartService(
|
||||||
|
restartService: Mutation$RestartService$restartService.fromJson(
|
||||||
|
json['restartService'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RestartServiceToJson(
|
||||||
|
Mutation$RestartService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'restartService': instance.restartService.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RestartService$restartService
|
||||||
|
_$Mutation$RestartService$restartServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RestartService$restartService(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RestartService$restartServiceToJson(
|
||||||
|
Mutation$RestartService$restartService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$MoveService _$Variables$Mutation$MoveServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$MoveService(
|
||||||
|
input: Input$MoveServiceInput.fromJson(
|
||||||
|
json['input'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$MoveServiceToJson(
|
||||||
|
Variables$Mutation$MoveService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'input': instance.input.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$MoveService _$Mutation$MoveServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$MoveService(
|
||||||
|
moveService: Mutation$MoveService$moveService.fromJson(
|
||||||
|
json['moveService'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$MoveServiceToJson(
|
||||||
|
Mutation$MoveService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'moveService': instance.moveService.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$MoveService$moveService _$Mutation$MoveService$moveServiceFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$MoveService$moveService(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
job: json['job'] == null
|
||||||
|
? null
|
||||||
|
: Mutation$MoveService$moveService$job.fromJson(
|
||||||
|
json['job'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$MoveService$moveServiceToJson(
|
||||||
|
Mutation$MoveService$moveService instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'job': instance.job?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$MoveService$moveService$job
|
||||||
|
_$Mutation$MoveService$moveService$jobFromJson(Map<String, dynamic> json) =>
|
||||||
|
Mutation$MoveService$moveService$job(
|
||||||
|
createdAt: dateTimeFromJson(json['createdAt']),
|
||||||
|
description: json['description'] as String,
|
||||||
|
error: json['error'] as String?,
|
||||||
|
finishedAt: _nullable$dateTimeFromJson(json['finishedAt']),
|
||||||
|
name: json['name'] as String,
|
||||||
|
progress: json['progress'] as int?,
|
||||||
|
result: json['result'] as String?,
|
||||||
|
status: json['status'] as String,
|
||||||
|
statusText: json['statusText'] as String?,
|
||||||
|
uid: json['uid'] as String,
|
||||||
|
updatedAt: dateTimeFromJson(json['updatedAt']),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$MoveService$moveService$jobToJson(
|
||||||
|
Mutation$MoveService$moveService$job instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'createdAt': dateTimeToJson(instance.createdAt),
|
||||||
|
'description': instance.description,
|
||||||
|
'error': instance.error,
|
||||||
|
'finishedAt': _nullable$dateTimeToJson(instance.finishedAt),
|
||||||
|
'name': instance.name,
|
||||||
|
'progress': instance.progress,
|
||||||
|
'result': instance.result,
|
||||||
|
'status': instance.status,
|
||||||
|
'statusText': instance.statusText,
|
||||||
|
'uid': instance.uid,
|
||||||
|
'updatedAt': dateTimeToJson(instance.updatedAt),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
72
lib/logic/api_maps/graphql_maps/schema/users.graphql
Normal file
72
lib/logic/api_maps/graphql_maps/schema/users.graphql
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
fragment basicMutationReturnFields on MutationReturnInterface{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment userFields on User{
|
||||||
|
username
|
||||||
|
userType
|
||||||
|
sshKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
query AllUsers {
|
||||||
|
users {
|
||||||
|
allUsers {
|
||||||
|
...userFields
|
||||||
|
}
|
||||||
|
rootUser: getUser(username: "root") {
|
||||||
|
...userFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query GetUser($username: String!) {
|
||||||
|
users {
|
||||||
|
getUser(username: $username) {
|
||||||
|
...userFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation CreateUser($user: UserMutationInput!) {
|
||||||
|
createUser(user: $user) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
user {
|
||||||
|
...userFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation DeleteUser($username: String!) {
|
||||||
|
deleteUser(username: $username) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation UpdateUser($user: UserMutationInput!) {
|
||||||
|
updateUser(user: $user) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
user {
|
||||||
|
...userFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation AddSshKey($sshInput: SshMutationInput!) {
|
||||||
|
addSshKey(sshInput: $sshInput) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
user {
|
||||||
|
...userFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation RemoveSshKey($sshInput: SshMutationInput!) {
|
||||||
|
removeSshKey(sshInput: $sshInput) {
|
||||||
|
...basicMutationReturnFields
|
||||||
|
user {
|
||||||
|
...userFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3319
lib/logic/api_maps/graphql_maps/schema/users.graphql.dart
Normal file
3319
lib/logic/api_maps/graphql_maps/schema/users.graphql.dart
Normal file
File diff suppressed because it is too large
Load diff
366
lib/logic/api_maps/graphql_maps/schema/users.graphql.g.dart
Normal file
366
lib/logic/api_maps/graphql_maps/schema/users.graphql.g.dart
Normal file
|
@ -0,0 +1,366 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'users.graphql.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Fragment$basicMutationReturnFields _$Fragment$basicMutationReturnFieldsFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Fragment$basicMutationReturnFields(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Fragment$basicMutationReturnFieldsToJson(
|
||||||
|
Fragment$basicMutationReturnFields instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Fragment$userFields _$Fragment$userFieldsFromJson(Map<String, dynamic> json) =>
|
||||||
|
Fragment$userFields(
|
||||||
|
username: json['username'] as String,
|
||||||
|
userType: $enumDecode(_$Enum$UserTypeEnumMap, json['userType'],
|
||||||
|
unknownValue: Enum$UserType.$unknown),
|
||||||
|
sshKeys:
|
||||||
|
(json['sshKeys'] as List<dynamic>).map((e) => e as String).toList(),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Fragment$userFieldsToJson(
|
||||||
|
Fragment$userFields instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'username': instance.username,
|
||||||
|
'userType': _$Enum$UserTypeEnumMap[instance.userType]!,
|
||||||
|
'sshKeys': instance.sshKeys,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
const _$Enum$UserTypeEnumMap = {
|
||||||
|
Enum$UserType.NORMAL: 'NORMAL',
|
||||||
|
Enum$UserType.PRIMARY: 'PRIMARY',
|
||||||
|
Enum$UserType.ROOT: 'ROOT',
|
||||||
|
Enum$UserType.$unknown: r'$unknown',
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$AllUsers _$Query$AllUsersFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$AllUsers(
|
||||||
|
users:
|
||||||
|
Query$AllUsers$users.fromJson(json['users'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$AllUsersToJson(Query$AllUsers instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'users': instance.users.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$AllUsers$users _$Query$AllUsers$usersFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Query$AllUsers$users(
|
||||||
|
allUsers: (json['allUsers'] as List<dynamic>)
|
||||||
|
.map((e) => Fragment$userFields.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
rootUser: json['rootUser'] == null
|
||||||
|
? null
|
||||||
|
: Fragment$userFields.fromJson(
|
||||||
|
json['rootUser'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$AllUsers$usersToJson(
|
||||||
|
Query$AllUsers$users instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'allUsers': instance.allUsers.map((e) => e.toJson()).toList(),
|
||||||
|
'rootUser': instance.rootUser?.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Query$GetUser _$Variables$Query$GetUserFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Query$GetUser(
|
||||||
|
username: json['username'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Query$GetUserToJson(
|
||||||
|
Variables$Query$GetUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'username': instance.username,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetUser _$Query$GetUserFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$GetUser(
|
||||||
|
users:
|
||||||
|
Query$GetUser$users.fromJson(json['users'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetUserToJson(Query$GetUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'users': instance.users.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Query$GetUser$users _$Query$GetUser$usersFromJson(Map<String, dynamic> json) =>
|
||||||
|
Query$GetUser$users(
|
||||||
|
getUser: json['getUser'] == null
|
||||||
|
? null
|
||||||
|
: Fragment$userFields.fromJson(
|
||||||
|
json['getUser'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Query$GetUser$usersToJson(
|
||||||
|
Query$GetUser$users instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'getUser': instance.getUser?.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$CreateUser _$Variables$Mutation$CreateUserFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$CreateUser(
|
||||||
|
user: Input$UserMutationInput.fromJson(
|
||||||
|
json['user'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$CreateUserToJson(
|
||||||
|
Variables$Mutation$CreateUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'user': instance.user.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$CreateUser _$Mutation$CreateUserFromJson(Map<String, dynamic> json) =>
|
||||||
|
Mutation$CreateUser(
|
||||||
|
createUser: Mutation$CreateUser$createUser.fromJson(
|
||||||
|
json['createUser'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$CreateUserToJson(
|
||||||
|
Mutation$CreateUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'createUser': instance.createUser.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$CreateUser$createUser _$Mutation$CreateUser$createUserFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$CreateUser$createUser(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
user: json['user'] == null
|
||||||
|
? null
|
||||||
|
: Fragment$userFields.fromJson(json['user'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$CreateUser$createUserToJson(
|
||||||
|
Mutation$CreateUser$createUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'user': instance.user?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$DeleteUser _$Variables$Mutation$DeleteUserFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$DeleteUser(
|
||||||
|
username: json['username'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$DeleteUserToJson(
|
||||||
|
Variables$Mutation$DeleteUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'username': instance.username,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$DeleteUser _$Mutation$DeleteUserFromJson(Map<String, dynamic> json) =>
|
||||||
|
Mutation$DeleteUser(
|
||||||
|
deleteUser: Mutation$DeleteUser$deleteUser.fromJson(
|
||||||
|
json['deleteUser'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$DeleteUserToJson(
|
||||||
|
Mutation$DeleteUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'deleteUser': instance.deleteUser.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$DeleteUser$deleteUser _$Mutation$DeleteUser$deleteUserFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$DeleteUser$deleteUser(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$DeleteUser$deleteUserToJson(
|
||||||
|
Mutation$DeleteUser$deleteUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$UpdateUser _$Variables$Mutation$UpdateUserFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$UpdateUser(
|
||||||
|
user: Input$UserMutationInput.fromJson(
|
||||||
|
json['user'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$UpdateUserToJson(
|
||||||
|
Variables$Mutation$UpdateUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'user': instance.user.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$UpdateUser _$Mutation$UpdateUserFromJson(Map<String, dynamic> json) =>
|
||||||
|
Mutation$UpdateUser(
|
||||||
|
updateUser: Mutation$UpdateUser$updateUser.fromJson(
|
||||||
|
json['updateUser'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$UpdateUserToJson(
|
||||||
|
Mutation$UpdateUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'updateUser': instance.updateUser.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$UpdateUser$updateUser _$Mutation$UpdateUser$updateUserFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$UpdateUser$updateUser(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
user: json['user'] == null
|
||||||
|
? null
|
||||||
|
: Fragment$userFields.fromJson(json['user'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$UpdateUser$updateUserToJson(
|
||||||
|
Mutation$UpdateUser$updateUser instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'user': instance.user?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$AddSshKey _$Variables$Mutation$AddSshKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$AddSshKey(
|
||||||
|
sshInput: Input$SshMutationInput.fromJson(
|
||||||
|
json['sshInput'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$AddSshKeyToJson(
|
||||||
|
Variables$Mutation$AddSshKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'sshInput': instance.sshInput.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$AddSshKey _$Mutation$AddSshKeyFromJson(Map<String, dynamic> json) =>
|
||||||
|
Mutation$AddSshKey(
|
||||||
|
addSshKey: Mutation$AddSshKey$addSshKey.fromJson(
|
||||||
|
json['addSshKey'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$AddSshKeyToJson(Mutation$AddSshKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'addSshKey': instance.addSshKey.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$AddSshKey$addSshKey _$Mutation$AddSshKey$addSshKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$AddSshKey$addSshKey(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
user: json['user'] == null
|
||||||
|
? null
|
||||||
|
: Fragment$userFields.fromJson(json['user'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$AddSshKey$addSshKeyToJson(
|
||||||
|
Mutation$AddSshKey$addSshKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'user': instance.user?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Variables$Mutation$RemoveSshKey _$Variables$Mutation$RemoveSshKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Variables$Mutation$RemoveSshKey(
|
||||||
|
sshInput: Input$SshMutationInput.fromJson(
|
||||||
|
json['sshInput'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Variables$Mutation$RemoveSshKeyToJson(
|
||||||
|
Variables$Mutation$RemoveSshKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'sshInput': instance.sshInput.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RemoveSshKey _$Mutation$RemoveSshKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RemoveSshKey(
|
||||||
|
removeSshKey: Mutation$RemoveSshKey$removeSshKey.fromJson(
|
||||||
|
json['removeSshKey'] as Map<String, dynamic>),
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RemoveSshKeyToJson(
|
||||||
|
Mutation$RemoveSshKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'removeSshKey': instance.removeSshKey.toJson(),
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutation$RemoveSshKey$removeSshKey _$Mutation$RemoveSshKey$removeSshKeyFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
Mutation$RemoveSshKey$removeSshKey(
|
||||||
|
code: json['code'] as int,
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
$__typename: json['__typename'] as String,
|
||||||
|
user: json['user'] == null
|
||||||
|
? null
|
||||||
|
: Fragment$userFields.fromJson(json['user'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$Mutation$RemoveSshKey$removeSshKeyToJson(
|
||||||
|
Mutation$RemoveSshKey$removeSshKey instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'code': instance.code,
|
||||||
|
'message': instance.message,
|
||||||
|
'success': instance.success,
|
||||||
|
'__typename': instance.$__typename,
|
||||||
|
'user': instance.user?.toJson(),
|
||||||
|
};
|
45
lib/logic/api_maps/graphql_maps/server_api/jobs_api.dart
Normal file
45
lib/logic/api_maps/graphql_maps/server_api/jobs_api.dart
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
part of 'server.dart';
|
||||||
|
|
||||||
|
mixin JobsApi on ApiMap {
|
||||||
|
Future<List<ServerJob>> getServerJobs() async {
|
||||||
|
QueryResult<Query$GetApiJobs> response;
|
||||||
|
List<ServerJob> jobsList = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$GetApiJobs();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
jobsList = jobsList = response.parsedData?.jobs.getJobs
|
||||||
|
.map<ServerJob>((final job) => ServerJob.fromGraphQL(job))
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return jobsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericMutationResult> removeApiJob(final String uid) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$RemoveJob(jobId: uid);
|
||||||
|
final mutation = Options$Mutation$RemoveJob(variables: variables);
|
||||||
|
final response = await client.mutate$RemoveJob(mutation);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: response.parsedData?.removeJob.success ?? false,
|
||||||
|
code: response.parsedData?.removeJob.code ?? 0,
|
||||||
|
message: response.parsedData?.removeJob.message,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
196
lib/logic/api_maps/graphql_maps/server_api/server.dart
Normal file
196
lib/logic/api_maps/graphql_maps/server_api/server.dart
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
import 'package:graphql/client.dart';
|
||||||
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/api_map.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/disk_volumes.graphql.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_api.graphql.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_settings.graphql.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/services.graphql.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.graphql.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/api_token.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/service.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/ssh_settings.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/system_settings.dart';
|
||||||
|
|
||||||
|
part 'jobs_api.dart';
|
||||||
|
part 'server_actions_api.dart';
|
||||||
|
part 'services_api.dart';
|
||||||
|
part 'users_api.dart';
|
||||||
|
part 'volume_api.dart';
|
||||||
|
|
||||||
|
class GenericMutationResult {
|
||||||
|
GenericMutationResult({
|
||||||
|
required this.success,
|
||||||
|
required this.code,
|
||||||
|
this.message,
|
||||||
|
});
|
||||||
|
final bool success;
|
||||||
|
final int code;
|
||||||
|
final String? message;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenericJobMutationReturn extends GenericMutationResult {
|
||||||
|
GenericJobMutationReturn({
|
||||||
|
required final super.success,
|
||||||
|
required final super.code,
|
||||||
|
final super.message,
|
||||||
|
this.job,
|
||||||
|
});
|
||||||
|
final ServerJob? job;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServerApi extends ApiMap
|
||||||
|
with VolumeApi, JobsApi, ServerActionsApi, ServicesApi, UsersApi {
|
||||||
|
ServerApi({
|
||||||
|
this.hasLogger = false,
|
||||||
|
this.isWithToken = true,
|
||||||
|
this.customToken = '',
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool hasLogger;
|
||||||
|
@override
|
||||||
|
bool isWithToken;
|
||||||
|
@override
|
||||||
|
String customToken;
|
||||||
|
@override
|
||||||
|
String? get rootAddress => getIt<ApiConfigModel>().serverDomain?.domainName;
|
||||||
|
|
||||||
|
Future<String?> getApiVersion() async {
|
||||||
|
QueryResult response;
|
||||||
|
String? apiVersion;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$GetApiVersion();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
apiVersion = response.data!['api']['version'];
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return apiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> isUsingBinds() async {
|
||||||
|
QueryResult response;
|
||||||
|
bool usesBinds = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$SystemIsUsingBinds();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
usesBinds = response.data!['system']['info']['usingBinds'];
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return usesBinds;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<ApiToken>> getApiTokens() async {
|
||||||
|
QueryResult response;
|
||||||
|
List<ApiToken> tokens = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$GetApiTokens();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
tokens = response.data!['api']['devices']
|
||||||
|
.map<ApiToken>((final e) => ApiToken.fromJson(e))
|
||||||
|
.toList();
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> switchService(final String uid, final bool needTurnOn) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
if (needTurnOn) {
|
||||||
|
final variables = Variables$Mutation$EnableService(serviceId: uid);
|
||||||
|
final mutation = Options$Mutation$EnableService(variables: variables);
|
||||||
|
await client.mutate$EnableService(mutation);
|
||||||
|
} else {
|
||||||
|
final variables = Variables$Mutation$DisableService(serviceId: uid);
|
||||||
|
final mutation = Options$Mutation$DisableService(variables: variables);
|
||||||
|
await client.mutate$DisableService(mutation);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setAutoUpgradeSettings(
|
||||||
|
final AutoUpgradeSettings settings,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final input = Input$AutoUpgradeSettingsInput(
|
||||||
|
allowReboot: settings.allowReboot,
|
||||||
|
enableAutoUpgrade: settings.enable,
|
||||||
|
);
|
||||||
|
final variables = Variables$Mutation$ChangeAutoUpgradeSettings(
|
||||||
|
settings: input,
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$ChangeAutoUpgradeSettings(
|
||||||
|
variables: variables,
|
||||||
|
);
|
||||||
|
await client.mutate$ChangeAutoUpgradeSettings(mutation);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setTimezone(final String timezone) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$ChangeTimezone(
|
||||||
|
timezone: timezone,
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$ChangeTimezone(
|
||||||
|
variables: variables,
|
||||||
|
);
|
||||||
|
await client.mutate$ChangeTimezone(mutation);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<SystemSettings> getSystemSettings() async {
|
||||||
|
QueryResult<Query$SystemSettings> response;
|
||||||
|
SystemSettings settings = SystemSettings(
|
||||||
|
autoUpgradeSettings: AutoUpgradeSettings(
|
||||||
|
allowReboot: false,
|
||||||
|
enable: false,
|
||||||
|
),
|
||||||
|
sshSettings: SshSettings(
|
||||||
|
enable: false,
|
||||||
|
passwordAuthentication: false,
|
||||||
|
),
|
||||||
|
timezone: 'Unknown',
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$SystemSettings();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
settings = SystemSettings.fromGraphQL(response.parsedData!.system);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
part of 'server.dart';
|
||||||
|
|
||||||
|
mixin ServerActionsApi on ApiMap {
|
||||||
|
Future<bool> _commonBoolRequest(final Function graphQLMethod) async {
|
||||||
|
QueryResult response;
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await graphQLMethod();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
result = false;
|
||||||
|
} else {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> reboot() async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
return await _commonBoolRequest(
|
||||||
|
() async => client.mutate$RebootSystem(),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> pullConfigurationUpdate() async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
return await _commonBoolRequest(
|
||||||
|
() async => client.mutate$PullRepositoryChanges(),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> upgrade() async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
return _commonBoolRequest(
|
||||||
|
() async => client.mutate$RunSystemUpgrade(),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> apply() async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
await client.mutate$RunSystemRebuild();
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
159
lib/logic/api_maps/graphql_maps/server_api/services_api.dart
Normal file
159
lib/logic/api_maps/graphql_maps/server_api/services_api.dart
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
part of 'server.dart';
|
||||||
|
|
||||||
|
mixin ServicesApi on ApiMap {
|
||||||
|
Future<List<Service>> getAllServices() async {
|
||||||
|
QueryResult<Query$AllServices> response;
|
||||||
|
List<Service> services = [];
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$AllServices();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
services = response.parsedData?.services.allServices
|
||||||
|
.map<Service>((final service) => Service.fromGraphQL(service))
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericMutationResult> enableService(final String serviceId) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$EnableService(serviceId: serviceId);
|
||||||
|
final mutation = Options$Mutation$EnableService(variables: variables);
|
||||||
|
final response = await client.mutate$EnableService(mutation);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: response.parsedData?.enableService.success ?? false,
|
||||||
|
code: response.parsedData?.enableService.code ?? 0,
|
||||||
|
message: response.parsedData?.enableService.message,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericMutationResult> disableService(final String serviceId) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$DisableService(serviceId: serviceId);
|
||||||
|
final mutation = Options$Mutation$DisableService(variables: variables);
|
||||||
|
final response = await client.mutate$DisableService(mutation);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: response.parsedData?.disableService.success ?? false,
|
||||||
|
code: response.parsedData?.disableService.code ?? 0,
|
||||||
|
message: response.parsedData?.disableService.message,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericMutationResult> stopService(final String serviceId) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$StopService(serviceId: serviceId);
|
||||||
|
final mutation = Options$Mutation$StopService(variables: variables);
|
||||||
|
final response = await client.mutate$StopService(mutation);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: response.parsedData?.stopService.success ?? false,
|
||||||
|
code: response.parsedData?.stopService.code ?? 0,
|
||||||
|
message: response.parsedData?.stopService.message,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericMutationResult> startService(final String serviceId) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$StartService(serviceId: serviceId);
|
||||||
|
final mutation = Options$Mutation$StartService(variables: variables);
|
||||||
|
final response = await client.mutate$StartService(mutation);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: response.parsedData?.startService.success ?? false,
|
||||||
|
code: response.parsedData?.startService.code ?? 0,
|
||||||
|
message: response.parsedData?.startService.message,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericMutationResult> restartService(final String serviceId) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$RestartService(serviceId: serviceId);
|
||||||
|
final mutation = Options$Mutation$RestartService(variables: variables);
|
||||||
|
final response = await client.mutate$RestartService(mutation);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: response.parsedData?.restartService.success ?? false,
|
||||||
|
code: response.parsedData?.restartService.code ?? 0,
|
||||||
|
message: response.parsedData?.restartService.message,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericJobMutationReturn> moveService(
|
||||||
|
final String serviceId,
|
||||||
|
final String destination,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$MoveService(
|
||||||
|
input: Input$MoveServiceInput(
|
||||||
|
serviceId: serviceId,
|
||||||
|
location: destination,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$MoveService(variables: variables);
|
||||||
|
final response = await client.mutate$MoveService(mutation);
|
||||||
|
final jobJson = response.parsedData?.moveService.job?.toJson();
|
||||||
|
return GenericJobMutationReturn(
|
||||||
|
success: response.parsedData?.moveService.success ?? false,
|
||||||
|
code: response.parsedData?.moveService.code ?? 0,
|
||||||
|
message: response.parsedData?.moveService.message,
|
||||||
|
job: jobJson != null ? ServerJob.fromJson(jobJson) : null,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericJobMutationReturn(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
job: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
203
lib/logic/api_maps/graphql_maps/server_api/users_api.dart
Normal file
203
lib/logic/api_maps/graphql_maps/server_api/users_api.dart
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
part of 'server.dart';
|
||||||
|
|
||||||
|
class UserMutationResult extends GenericMutationResult {
|
||||||
|
UserMutationResult({
|
||||||
|
required final super.success,
|
||||||
|
required final super.code,
|
||||||
|
final super.message,
|
||||||
|
this.user,
|
||||||
|
});
|
||||||
|
|
||||||
|
final User? user;
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin UsersApi on ApiMap {
|
||||||
|
Future<List<User>> getAllUsers() async {
|
||||||
|
QueryResult<Query$AllUsers> response;
|
||||||
|
List<User> users = [];
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$AllUsers();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
users = response.parsedData?.users.allUsers
|
||||||
|
.map<User>((final user) => User.fromGraphQL(user))
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
final rootUser = response.parsedData?.users.rootUser;
|
||||||
|
if (rootUser != null) {
|
||||||
|
users.add(User.fromGraphQL(rootUser));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<User?> getUser(final String login) async {
|
||||||
|
QueryResult<Query$GetUser> response;
|
||||||
|
User? user;
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Query$GetUser(username: login);
|
||||||
|
response = await client
|
||||||
|
.query$GetUser(Options$Query$GetUser(variables: variables));
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
final responseUser = response.parsedData?.users.getUser;
|
||||||
|
if (responseUser != null) {
|
||||||
|
user = User.fromGraphQL(responseUser);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<UserMutationResult> createUser(
|
||||||
|
final String username,
|
||||||
|
final String password,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$CreateUser(
|
||||||
|
user: Input$UserMutationInput(username: username, password: password),
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$CreateUser(variables: variables);
|
||||||
|
final response = await client.mutate$CreateUser(mutation);
|
||||||
|
return UserMutationResult(
|
||||||
|
success: response.parsedData?.createUser.success ?? false,
|
||||||
|
code: response.parsedData?.createUser.code ?? 500,
|
||||||
|
message: response.parsedData?.createUser.message,
|
||||||
|
user: response.parsedData?.createUser.user != null
|
||||||
|
? User.fromGraphQL(response.parsedData!.createUser.user!)
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return UserMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericMutationResult> deleteUser(
|
||||||
|
final String username,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$DeleteUser(username: username);
|
||||||
|
final mutation = Options$Mutation$DeleteUser(variables: variables);
|
||||||
|
final response = await client.mutate$DeleteUser(mutation);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: response.parsedData?.deleteUser.success ?? false,
|
||||||
|
code: response.parsedData?.deleteUser.code ?? 500,
|
||||||
|
message: response.parsedData?.deleteUser.message,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 500,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<UserMutationResult> updateUser(
|
||||||
|
final String username,
|
||||||
|
final String password,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$UpdateUser(
|
||||||
|
user: Input$UserMutationInput(username: username, password: password),
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$UpdateUser(variables: variables);
|
||||||
|
final response = await client.mutate$UpdateUser(mutation);
|
||||||
|
return UserMutationResult(
|
||||||
|
success: response.parsedData?.updateUser.success ?? false,
|
||||||
|
code: response.parsedData?.updateUser.code ?? 500,
|
||||||
|
message: response.parsedData?.updateUser.message,
|
||||||
|
user: response.parsedData?.updateUser.user != null
|
||||||
|
? User.fromGraphQL(response.parsedData!.updateUser.user!)
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return UserMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<UserMutationResult> addSshKey(
|
||||||
|
final String username,
|
||||||
|
final String sshKey,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$AddSshKey(
|
||||||
|
sshInput: Input$SshMutationInput(
|
||||||
|
username: username,
|
||||||
|
sshKey: sshKey,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$AddSshKey(variables: variables);
|
||||||
|
final response = await client.mutate$AddSshKey(mutation);
|
||||||
|
return UserMutationResult(
|
||||||
|
success: response.parsedData?.addSshKey.success ?? false,
|
||||||
|
code: response.parsedData?.addSshKey.code ?? 500,
|
||||||
|
message: response.parsedData?.addSshKey.message,
|
||||||
|
user: response.parsedData?.addSshKey.user != null
|
||||||
|
? User.fromGraphQL(response.parsedData!.addSshKey.user!)
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return UserMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<UserMutationResult> removeSshKey(
|
||||||
|
final String username,
|
||||||
|
final String sshKey,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$RemoveSshKey(
|
||||||
|
sshInput: Input$SshMutationInput(
|
||||||
|
username: username,
|
||||||
|
sshKey: sshKey,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$RemoveSshKey(variables: variables);
|
||||||
|
final response = await client.mutate$RemoveSshKey(mutation);
|
||||||
|
return UserMutationResult(
|
||||||
|
success: response.parsedData?.removeSshKey.success ?? false,
|
||||||
|
code: response.parsedData?.removeSshKey.code ?? 500,
|
||||||
|
message: response.parsedData?.removeSshKey.message,
|
||||||
|
user: response.parsedData?.removeSshKey.user != null
|
||||||
|
? User.fromGraphQL(response.parsedData!.removeSshKey.user!)
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return UserMutationResult(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
109
lib/logic/api_maps/graphql_maps/server_api/volume_api.dart
Normal file
109
lib/logic/api_maps/graphql_maps/server_api/volume_api.dart
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
part of 'server.dart';
|
||||||
|
|
||||||
|
class MigrateToBindsMutationReturn extends GenericMutationResult {
|
||||||
|
MigrateToBindsMutationReturn({
|
||||||
|
required final super.success,
|
||||||
|
required final super.code,
|
||||||
|
final super.message,
|
||||||
|
this.jobUid,
|
||||||
|
});
|
||||||
|
final String? jobUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin VolumeApi on ApiMap {
|
||||||
|
Future<List<ServerDiskVolume>> getServerDiskVolumes() async {
|
||||||
|
QueryResult response;
|
||||||
|
List<ServerDiskVolume> volumes = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$GetServerDiskVolumes();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
volumes = response.data!['storage']['volumes']
|
||||||
|
.map<ServerDiskVolume>((final e) => ServerDiskVolume.fromJson(e))
|
||||||
|
.toList();
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return volumes;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> mountVolume(final String volumeName) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$MountVolume(name: volumeName);
|
||||||
|
final mountVolumeMutation =
|
||||||
|
Options$Mutation$MountVolume(variables: variables);
|
||||||
|
await client.mutate$MountVolume(mountVolumeMutation);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> unmountVolume(final String volumeName) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$UnmountVolume(name: volumeName);
|
||||||
|
final unmountVolumeMutation =
|
||||||
|
Options$Mutation$UnmountVolume(variables: variables);
|
||||||
|
await client.mutate$UnmountVolume(unmountVolumeMutation);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> resizeVolume(final String volumeName) async {
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final variables = Variables$Mutation$ResizeVolume(name: volumeName);
|
||||||
|
final resizeVolumeMutation =
|
||||||
|
Options$Mutation$ResizeVolume(variables: variables);
|
||||||
|
await client.mutate$ResizeVolume(resizeVolumeMutation);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<MigrateToBindsMutationReturn> migrateToBinds(
|
||||||
|
final Map<String, String> serviceToDisk,
|
||||||
|
) async {
|
||||||
|
MigrateToBindsMutationReturn? mutation;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
final input = Input$MigrateToBindsInput(
|
||||||
|
bitwardenBlockDevice: serviceToDisk['bitwarden']!,
|
||||||
|
emailBlockDevice: serviceToDisk['mailserver']!,
|
||||||
|
giteaBlockDevice: serviceToDisk['gitea']!,
|
||||||
|
nextcloudBlockDevice: serviceToDisk['nextcloud']!,
|
||||||
|
pleromaBlockDevice: serviceToDisk['pleroma']!,
|
||||||
|
);
|
||||||
|
final variables = Variables$Mutation$MigrateToBinds(input: input);
|
||||||
|
final migrateMutation =
|
||||||
|
Options$Mutation$MigrateToBinds(variables: variables);
|
||||||
|
final QueryResult<Mutation$MigrateToBinds> result =
|
||||||
|
await client.mutate$MigrateToBinds(
|
||||||
|
migrateMutation,
|
||||||
|
);
|
||||||
|
mutation = mutation = MigrateToBindsMutationReturn(
|
||||||
|
success: result.parsedData!.migrateToBinds.success,
|
||||||
|
code: result.parsedData!.migrateToBinds.code,
|
||||||
|
message: result.parsedData!.migrateToBinds.message,
|
||||||
|
jobUid: result.parsedData!.migrateToBinds.job?.uid,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
mutation = MigrateToBindsMutationReturn(
|
||||||
|
success: false,
|
||||||
|
code: 0,
|
||||||
|
message: e.toString(),
|
||||||
|
jobUid: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mutation;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,277 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
|
||||||
import 'package:selfprivacy/logic/api_maps/api_map.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
|
||||||
import 'package:selfprivacy/utils/password_generator.dart';
|
|
||||||
|
|
||||||
class HetznerApi extends ApiMap {
|
|
||||||
HetznerApi({this.hasLogger = false, this.isWithToken = true});
|
|
||||||
@override
|
|
||||||
bool hasLogger;
|
|
||||||
@override
|
|
||||||
bool isWithToken;
|
|
||||||
|
|
||||||
@override
|
|
||||||
BaseOptions get options {
|
|
||||||
final BaseOptions options = BaseOptions(baseUrl: rootAddress);
|
|
||||||
if (isWithToken) {
|
|
||||||
final String? token = getIt<ApiConfigModel>().hetznerKey;
|
|
||||||
assert(token != null);
|
|
||||||
options.headers = {'Authorization': 'Bearer $token'};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validateStatus != null) {
|
|
||||||
options.validateStatus = validateStatus!;
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String rootAddress = 'https://api.hetzner.cloud/v1';
|
|
||||||
|
|
||||||
Future<bool> isValid(final String token) async {
|
|
||||||
validateStatus = (final int? status) =>
|
|
||||||
status == HttpStatus.ok || status == HttpStatus.unauthorized;
|
|
||||||
final Dio client = await getClient();
|
|
||||||
final Response response = await client.get(
|
|
||||||
'/servers',
|
|
||||||
options: Options(
|
|
||||||
headers: {'Authorization': 'Bearer $token'},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
close(client);
|
|
||||||
|
|
||||||
if (response.statusCode == HttpStatus.ok) {
|
|
||||||
return true;
|
|
||||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
throw Exception('code: ${response.statusCode}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ServerVolume> createVolume() async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
final Response dbCreateResponse = await client.post(
|
|
||||||
'/volumes',
|
|
||||||
data: {
|
|
||||||
'size': 10,
|
|
||||||
'name': StringGenerators.dbStorageName(),
|
|
||||||
'labels': {'labelkey': 'value'},
|
|
||||||
'location': 'fsn1',
|
|
||||||
'automount': false,
|
|
||||||
'format': 'ext4'
|
|
||||||
},
|
|
||||||
);
|
|
||||||
final dbId = dbCreateResponse.data['volume']['id'];
|
|
||||||
return ServerVolume(
|
|
||||||
id: dbId,
|
|
||||||
name: dbCreateResponse.data['volume']['name'],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ServerHostingDetails?> createServer({
|
|
||||||
required final String cloudFlareKey,
|
|
||||||
required final User rootUser,
|
|
||||||
required final String domainName,
|
|
||||||
required final ServerVolume dataBase,
|
|
||||||
}) async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
|
|
||||||
final String dbPassword = StringGenerators.dbPassword();
|
|
||||||
final int dbId = dataBase.id;
|
|
||||||
|
|
||||||
final String apiToken = StringGenerators.apiToken();
|
|
||||||
|
|
||||||
final String hostname = getHostnameFromDomain(domainName);
|
|
||||||
|
|
||||||
final String base64Password =
|
|
||||||
base64.encode(utf8.encode(rootUser.password ?? 'PASS'));
|
|
||||||
|
|
||||||
print('hostname: $hostname');
|
|
||||||
|
|
||||||
/// add ssh key when you need it: e.g. "ssh_keys":["kherel"]
|
|
||||||
/// check the branch name, it could be "development" or "master".
|
|
||||||
///
|
|
||||||
final String userdataString =
|
|
||||||
"#cloud-config\nruncmd:\n- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-21.05 DOMAIN='$domainName' LUSER='${rootUser.login}' ENCODED_PASSWORD='$base64Password' CF_TOKEN=$cloudFlareKey DB_PASSWORD=$dbPassword API_TOKEN=$apiToken HOSTNAME=$hostname bash 2>&1 | tee /tmp/infect.log";
|
|
||||||
print(userdataString);
|
|
||||||
|
|
||||||
final Map<String, Object> data = {
|
|
||||||
'name': hostname,
|
|
||||||
'server_type': 'cx11',
|
|
||||||
'start_after_create': false,
|
|
||||||
'image': 'ubuntu-20.04',
|
|
||||||
'volumes': [dbId],
|
|
||||||
'networks': [],
|
|
||||||
'user_data': userdataString,
|
|
||||||
'labels': {},
|
|
||||||
'automount': true,
|
|
||||||
'location': 'fsn1'
|
|
||||||
};
|
|
||||||
print('Decoded data: $data');
|
|
||||||
|
|
||||||
ServerHostingDetails? serverDetails;
|
|
||||||
|
|
||||||
try {
|
|
||||||
final Response serverCreateResponse = await client.post(
|
|
||||||
'/servers',
|
|
||||||
data: data,
|
|
||||||
);
|
|
||||||
print(serverCreateResponse.data);
|
|
||||||
serverDetails = ServerHostingDetails(
|
|
||||||
id: serverCreateResponse.data['server']['id'],
|
|
||||||
ip4: serverCreateResponse.data['server']['public_net']['ipv4']['ip'],
|
|
||||||
createTime: DateTime.now(),
|
|
||||||
volume: dataBase,
|
|
||||||
apiToken: apiToken,
|
|
||||||
provider: ServerProvider.hetzner,
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e);
|
|
||||||
rethrow;
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return serverDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
static String getHostnameFromDomain(final String domain) {
|
|
||||||
// Replace all non-alphanumeric characters with an underscore
|
|
||||||
String hostname =
|
|
||||||
domain.split('.')[0].replaceAll(RegExp(r'[^a-zA-Z0-9]'), '-');
|
|
||||||
if (hostname.endsWith('-')) {
|
|
||||||
hostname = hostname.substring(0, hostname.length - 1);
|
|
||||||
}
|
|
||||||
if (hostname.startsWith('-')) {
|
|
||||||
hostname = hostname.substring(1);
|
|
||||||
}
|
|
||||||
if (hostname.isEmpty) {
|
|
||||||
hostname = 'selfprivacy-server';
|
|
||||||
}
|
|
||||||
|
|
||||||
return hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> deleteSelfprivacyServerAndAllVolumes({
|
|
||||||
required final String domainName,
|
|
||||||
}) async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
|
|
||||||
final String hostname = getHostnameFromDomain(domainName);
|
|
||||||
|
|
||||||
final Response serversReponse = await client.get('/servers');
|
|
||||||
final List servers = serversReponse.data['servers'];
|
|
||||||
final Map server = servers.firstWhere((final el) => el['name'] == hostname);
|
|
||||||
final List volumes = server['volumes'];
|
|
||||||
final List<Future> laterFutures = <Future>[];
|
|
||||||
|
|
||||||
for (final volumeId in volumes) {
|
|
||||||
await client.post('/volumes/$volumeId/actions/detach');
|
|
||||||
}
|
|
||||||
await Future.delayed(const Duration(seconds: 10));
|
|
||||||
|
|
||||||
for (final volumeId in volumes) {
|
|
||||||
laterFutures.add(client.delete('/volumes/$volumeId'));
|
|
||||||
}
|
|
||||||
laterFutures.add(client.delete('/servers/${server['id']}'));
|
|
||||||
|
|
||||||
await Future.wait(laterFutures);
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ServerHostingDetails> reset() async {
|
|
||||||
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
await client.post('/servers/${server.id}/actions/reset');
|
|
||||||
close(client);
|
|
||||||
|
|
||||||
return server.copyWith(startTime: DateTime.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ServerHostingDetails> powerOn() async {
|
|
||||||
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
await client.post('/servers/${server.id}/actions/poweron');
|
|
||||||
close(client);
|
|
||||||
|
|
||||||
return server.copyWith(startTime: DateTime.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, dynamic>> getMetrics(
|
|
||||||
final DateTime start,
|
|
||||||
final DateTime end,
|
|
||||||
final String type,
|
|
||||||
) async {
|
|
||||||
final ServerHostingDetails? hetznerServer =
|
|
||||||
getIt<ApiConfigModel>().serverDetails;
|
|
||||||
final Dio client = await getClient();
|
|
||||||
|
|
||||||
final Map<String, dynamic> queryParameters = {
|
|
||||||
'start': start.toUtc().toIso8601String(),
|
|
||||||
'end': end.toUtc().toIso8601String(),
|
|
||||||
'type': type
|
|
||||||
};
|
|
||||||
final Response res = await client.get(
|
|
||||||
'/servers/${hetznerServer!.id}/metrics',
|
|
||||||
queryParameters: queryParameters,
|
|
||||||
);
|
|
||||||
close(client);
|
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<HetznerServerInfo> getInfo() async {
|
|
||||||
final ServerHostingDetails? hetznerServer =
|
|
||||||
getIt<ApiConfigModel>().serverDetails;
|
|
||||||
final Dio client = await getClient();
|
|
||||||
final Response response = await client.get('/servers/${hetznerServer!.id}');
|
|
||||||
close(client);
|
|
||||||
|
|
||||||
return HetznerServerInfo.fromJson(response.data!['server']);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<HetznerServerInfo>> getServers() async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
final Response response = await client.get('/servers');
|
|
||||||
close(client);
|
|
||||||
|
|
||||||
return (response.data!['servers'] as List)
|
|
||||||
// ignore: unnecessary_lambdas
|
|
||||||
.map((final e) => HetznerServerInfo.fromJson(e))
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> createReverseDns({
|
|
||||||
required final String ip4,
|
|
||||||
required final String domainName,
|
|
||||||
}) async {
|
|
||||||
final ServerHostingDetails? hetznerServer =
|
|
||||||
getIt<ApiConfigModel>().serverDetails;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
await client.post(
|
|
||||||
'/servers/${hetznerServer!.id}/actions/change_dns_ptr',
|
|
||||||
data: {
|
|
||||||
'ip': ip4,
|
|
||||||
'dns_ptr': domainName,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
48
lib/logic/api_maps/rest_maps/api_factory_creator.dart
Normal file
48
lib/logic/api_maps/rest_maps/api_factory_creator.dart
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||||
|
|
||||||
|
class UnknownApiProviderException implements Exception {
|
||||||
|
UnknownApiProviderException(this.message);
|
||||||
|
final String message;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiFactoryCreator {
|
||||||
|
static ServerProviderApiFactory createServerProviderApiFactory(
|
||||||
|
final ServerProvider provider,
|
||||||
|
) {
|
||||||
|
switch (provider) {
|
||||||
|
case ServerProvider.hetzner:
|
||||||
|
return HetznerApiFactory();
|
||||||
|
case ServerProvider.unknown:
|
||||||
|
throw UnknownApiProviderException('Unknown server provider');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DnsProviderApiFactory createDnsProviderApiFactory(
|
||||||
|
final DnsProvider provider,
|
||||||
|
) {
|
||||||
|
switch (provider) {
|
||||||
|
case DnsProvider.cloudflare:
|
||||||
|
return CloudflareApiFactory();
|
||||||
|
case DnsProvider.unknown:
|
||||||
|
throw UnknownApiProviderException('Unknown DNS provider');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VolumeApiFactoryCreator {
|
||||||
|
static VolumeProviderApiFactory createVolumeProviderApiFactory(
|
||||||
|
final ServerProvider provider,
|
||||||
|
) {
|
||||||
|
switch (provider) {
|
||||||
|
case ServerProvider.hetzner:
|
||||||
|
return HetznerApiFactory();
|
||||||
|
case ServerProvider.unknown:
|
||||||
|
throw UnknownApiProviderException('Unknown volume provider');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ 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/api_maps/api_map.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||||
|
|
||||||
class BackblazeApiAuth {
|
class BackblazeApiAuth {
|
|
@ -2,16 +2,11 @@ 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/api_maps/api_map.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
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';
|
||||||
|
|
||||||
class DomainNotFoundException implements Exception {
|
class CloudflareApi extends DnsProviderApi {
|
||||||
DomainNotFoundException(this.message);
|
|
||||||
final String message;
|
|
||||||
}
|
|
||||||
|
|
||||||
class CloudflareApi extends ApiMap {
|
|
||||||
CloudflareApi({
|
CloudflareApi({
|
||||||
this.hasLogger = false,
|
this.hasLogger = false,
|
||||||
this.isWithToken = true,
|
this.isWithToken = true,
|
||||||
|
@ -24,6 +19,10 @@ class CloudflareApi extends ApiMap {
|
||||||
|
|
||||||
final String? customToken;
|
final String? customToken;
|
||||||
|
|
||||||
|
@override
|
||||||
|
RegExp getApiTokenValidation() =>
|
||||||
|
RegExp(r'\s+|[!$%^&*()@+|~=`{}\[\]:<>?,.\/]');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BaseOptions get options {
|
BaseOptions get options {
|
||||||
final BaseOptions options = BaseOptions(baseUrl: rootAddress);
|
final BaseOptions options = BaseOptions(baseUrl: rootAddress);
|
||||||
|
@ -46,110 +45,133 @@ class CloudflareApi extends ApiMap {
|
||||||
@override
|
@override
|
||||||
String rootAddress = 'https://api.cloudflare.com/client/v4';
|
String rootAddress = 'https://api.cloudflare.com/client/v4';
|
||||||
|
|
||||||
Future<bool> isValid(final String token) async {
|
@override
|
||||||
validateStatus = (final status) =>
|
Future<bool> isApiTokenValid(final String token) async {
|
||||||
status == HttpStatus.ok || status == HttpStatus.unauthorized;
|
bool isValid = false;
|
||||||
|
Response? response;
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
final Response response = await client.get(
|
try {
|
||||||
'/user/tokens/verify',
|
response = await client.get(
|
||||||
options: Options(headers: {'Authorization': 'Bearer $token'}),
|
'/user/tokens/verify',
|
||||||
);
|
options: Options(headers: {'Authorization': 'Bearer $token'}),
|
||||||
|
);
|
||||||
close(client);
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
if (response.statusCode == HttpStatus.ok) {
|
isValid = false;
|
||||||
return true;
|
} finally {
|
||||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
close(client);
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
throw Exception('code: ${response.statusCode}');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response != null) {
|
||||||
|
if (response.statusCode == HttpStatus.ok) {
|
||||||
|
isValid = true;
|
||||||
|
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||||
|
isValid = false;
|
||||||
|
} else {
|
||||||
|
throw Exception('code: ${response.statusCode}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getZoneId(final String domain) async {
|
@override
|
||||||
validateStatus = (final status) =>
|
Future<String?> getZoneId(final String domain) async {
|
||||||
status == HttpStatus.ok || status == HttpStatus.forbidden;
|
String? zoneId;
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
final Response response = await client.get(
|
try {
|
||||||
'/zones',
|
final Response response = await client.get(
|
||||||
queryParameters: {'name': domain},
|
'/zones',
|
||||||
);
|
queryParameters: {'name': domain},
|
||||||
|
);
|
||||||
close(client);
|
zoneId = response.data['result'][0]['id'];
|
||||||
|
} catch (e) {
|
||||||
if (response.data['result'].isEmpty) {
|
print(e);
|
||||||
throw DomainNotFoundException('No domains found');
|
} finally {
|
||||||
} else {
|
close(client);
|
||||||
return response.data['result'][0]['id'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return zoneId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Future<void> removeSimilarRecords({
|
Future<void> removeSimilarRecords({
|
||||||
required final ServerDomain cloudFlareDomain,
|
required final ServerDomain domain,
|
||||||
final String? ip4,
|
final String? ip4,
|
||||||
}) async {
|
}) async {
|
||||||
final String domainName = cloudFlareDomain.domainName;
|
final String domainName = domain.domainName;
|
||||||
final String domainZoneId = cloudFlareDomain.zoneId;
|
final String domainZoneId = domain.zoneId;
|
||||||
|
|
||||||
final String url = '/zones/$domainZoneId/dns_records';
|
final String url = '/zones/$domainZoneId/dns_records';
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
final Response response = await client.get(url);
|
try {
|
||||||
|
final Response response = await client.get(url);
|
||||||
|
|
||||||
final List records = response.data['result'] ?? [];
|
final List records = response.data['result'] ?? [];
|
||||||
final List<Future> allDeleteFutures = <Future>[];
|
final List<Future> allDeleteFutures = <Future>[];
|
||||||
|
|
||||||
for (final record in records) {
|
for (final record in records) {
|
||||||
if (record['zone_name'] == domainName) {
|
if (record['zone_name'] == domainName) {
|
||||||
allDeleteFutures.add(
|
allDeleteFutures.add(
|
||||||
client.delete('$url/${record["id"]}'),
|
client.delete('$url/${record["id"]}'),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
await Future.wait(allDeleteFutures);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Future.wait(allDeleteFutures);
|
|
||||||
close(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Future<List<DnsRecord>> getDnsRecords({
|
Future<List<DnsRecord>> getDnsRecords({
|
||||||
required final ServerDomain cloudFlareDomain,
|
required final ServerDomain domain,
|
||||||
}) async {
|
}) async {
|
||||||
final String domainName = cloudFlareDomain.domainName;
|
Response response;
|
||||||
final String domainZoneId = cloudFlareDomain.zoneId;
|
final String domainName = domain.domainName;
|
||||||
|
final String domainZoneId = domain.zoneId;
|
||||||
|
final List<DnsRecord> allRecords = <DnsRecord>[];
|
||||||
|
|
||||||
final String url = '/zones/$domainZoneId/dns_records';
|
final String url = '/zones/$domainZoneId/dns_records';
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
final Response response = await client.get(url);
|
try {
|
||||||
|
response = await client.get(url);
|
||||||
|
final List records = response.data['result'] ?? [];
|
||||||
|
|
||||||
final List records = response.data['result'] ?? [];
|
for (final record in records) {
|
||||||
final List<DnsRecord> allRecords = <DnsRecord>[];
|
if (record['zone_name'] == domainName) {
|
||||||
|
allRecords.add(
|
||||||
for (final record in records) {
|
DnsRecord(
|
||||||
if (record['zone_name'] == domainName) {
|
name: record['name'],
|
||||||
allRecords.add(
|
type: record['type'],
|
||||||
DnsRecord(
|
content: record['content'],
|
||||||
name: record['name'],
|
ttl: record['ttl'],
|
||||||
type: record['type'],
|
proxied: record['proxied'],
|
||||||
content: record['content'],
|
),
|
||||||
ttl: record['ttl'],
|
);
|
||||||
proxied: record['proxied'],
|
}
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(client);
|
|
||||||
return allRecords;
|
return allRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Future<void> createMultipleDnsRecords({
|
Future<void> createMultipleDnsRecords({
|
||||||
required final ServerDomain cloudFlareDomain,
|
required final ServerDomain domain,
|
||||||
final String? ip4,
|
final String? ip4,
|
||||||
}) async {
|
}) async {
|
||||||
final String domainName = cloudFlareDomain.domainName;
|
final String domainName = domain.domainName;
|
||||||
final String domainZoneId = cloudFlareDomain.zoneId;
|
final String domainZoneId = domain.zoneId;
|
||||||
final List<DnsRecord> listDnsRecords = projectDnsRecords(domainName, ip4);
|
final List<DnsRecord> listDnsRecords = projectDnsRecords(domainName, ip4);
|
||||||
final List<Future> allCreateFutures = <Future>[];
|
final List<Future> allCreateFutures = <Future>[];
|
||||||
|
|
||||||
|
@ -219,11 +241,12 @@ class CloudflareApi extends ApiMap {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Future<void> setDkim(
|
Future<void> setDkim(
|
||||||
final String dkimRecordString,
|
final String dkimRecordString,
|
||||||
final ServerDomain cloudFlareDomain,
|
final ServerDomain domain,
|
||||||
) async {
|
) async {
|
||||||
final String domainZoneId = cloudFlareDomain.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(
|
final DnsRecord dkimRecord = DnsRecord(
|
||||||
|
@ -234,26 +257,38 @@ class CloudflareApi extends ApiMap {
|
||||||
);
|
);
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
await client.post(
|
try {
|
||||||
url,
|
await client.post(
|
||||||
data: dkimRecord.toJson(),
|
url,
|
||||||
);
|
data: dkimRecord.toJson(),
|
||||||
|
);
|
||||||
client.close();
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Future<List<String>> domainList() async {
|
Future<List<String>> domainList() async {
|
||||||
final String url = '$rootAddress/zones';
|
final String url = '$rootAddress/zones';
|
||||||
|
List<String> domains = [];
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
final Response response = await client.get(
|
||||||
|
url,
|
||||||
|
queryParameters: {'per_page': 50},
|
||||||
|
);
|
||||||
|
domains = response.data['result']
|
||||||
|
.map<String>((final el) => el['name'] as String)
|
||||||
|
.toList();
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
final Response response = await client.get(
|
return domains;
|
||||||
url,
|
|
||||||
queryParameters: {'per_page': 50},
|
|
||||||
);
|
|
||||||
|
|
||||||
close(client);
|
|
||||||
return response.data['result']
|
|
||||||
.map<String>((final el) => el['name'] as String)
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||||
|
|
||||||
|
class CloudflareApiFactory extends DnsProviderApiFactory {
|
||||||
|
@override
|
||||||
|
DnsProviderApi getDnsProvider({
|
||||||
|
final DnsProviderApiSettings settings = const DnsProviderApiSettings(),
|
||||||
|
}) =>
|
||||||
|
CloudflareApi(
|
||||||
|
hasLogger: settings.hasLogger,
|
||||||
|
isWithToken: settings.isWithToken,
|
||||||
|
customToken: settings.customToken,
|
||||||
|
);
|
||||||
|
}
|
31
lib/logic/api_maps/rest_maps/dns_providers/dns_provider.dart
Normal file
31
lib/logic/api_maps/rest_maps/dns_providers/dns_provider.dart
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||||
|
|
||||||
|
class DomainNotFoundException implements Exception {
|
||||||
|
DomainNotFoundException(this.message);
|
||||||
|
final String message;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class DnsProviderApi extends ApiMap {
|
||||||
|
Future<List<DnsRecord>> getDnsRecords({
|
||||||
|
required final ServerDomain domain,
|
||||||
|
});
|
||||||
|
Future<void> removeSimilarRecords({
|
||||||
|
required final ServerDomain domain,
|
||||||
|
final String? ip4,
|
||||||
|
});
|
||||||
|
Future<void> createMultipleDnsRecords({
|
||||||
|
required final ServerDomain domain,
|
||||||
|
final String? ip4,
|
||||||
|
});
|
||||||
|
Future<void> setDkim(
|
||||||
|
final String dkimRecordString,
|
||||||
|
final ServerDomain domain,
|
||||||
|
);
|
||||||
|
Future<String?> getZoneId(final String domain);
|
||||||
|
Future<List<String>> domainList();
|
||||||
|
|
||||||
|
Future<bool> isApiTokenValid(final String token);
|
||||||
|
RegExp getApiTokenValidation();
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
|
||||||
|
|
||||||
|
class DnsProviderApiSettings extends ProviderApiSettings {
|
||||||
|
const DnsProviderApiSettings({
|
||||||
|
final super.hasLogger = false,
|
||||||
|
final super.isWithToken = true,
|
||||||
|
final this.customToken,
|
||||||
|
});
|
||||||
|
final String? customToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class DnsProviderApiFactory {
|
||||||
|
DnsProviderApi getDnsProvider({
|
||||||
|
final DnsProviderApiSettings settings = const DnsProviderApiSettings(),
|
||||||
|
});
|
||||||
|
}
|
5
lib/logic/api_maps/rest_maps/provider_api_settings.dart
Normal file
5
lib/logic/api_maps/rest_maps/provider_api_settings.dart
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class ProviderApiSettings {
|
||||||
|
const ProviderApiSettings({this.hasLogger = false, this.isWithToken = true});
|
||||||
|
final bool hasLogger;
|
||||||
|
final bool isWithToken;
|
||||||
|
}
|
|
@ -4,19 +4,17 @@ 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/api_maps/rest_maps/api_map.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.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/api_token.dart';
|
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/auto_upgrade_settings.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/recovery_token_status.dart';
|
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
|
||||||
import 'package:selfprivacy/logic/models/timezone_settings.dart';
|
import 'package:selfprivacy/logic/models/timezone_settings.dart';
|
||||||
|
|
||||||
import 'package:selfprivacy/logic/api_maps/api_map.dart';
|
|
||||||
|
|
||||||
class ApiResponse<D> {
|
class ApiResponse<D> {
|
||||||
ApiResponse({
|
ApiResponse({
|
||||||
required this.statusCode,
|
required this.statusCode,
|
||||||
|
@ -46,16 +44,20 @@ class ServerApi extends ApiMap {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BaseOptions get options {
|
BaseOptions get options {
|
||||||
BaseOptions options = BaseOptions();
|
BaseOptions options = BaseOptions(
|
||||||
|
connectTimeout: 10000,
|
||||||
|
receiveTimeout: 10000,
|
||||||
|
);
|
||||||
|
|
||||||
if (isWithToken) {
|
if (isWithToken) {
|
||||||
final ServerDomain? cloudFlareDomain =
|
final ServerDomain? serverDomain = getIt<ApiConfigModel>().serverDomain;
|
||||||
getIt<ApiConfigModel>().serverDomain;
|
final String domainName = serverDomain!.domainName;
|
||||||
final String domainName = cloudFlareDomain!.domainName;
|
|
||||||
final String? apiToken = getIt<ApiConfigModel>().serverDetails?.apiToken;
|
final String? apiToken = getIt<ApiConfigModel>().serverDetails?.apiToken;
|
||||||
|
|
||||||
options = BaseOptions(
|
options = BaseOptions(
|
||||||
baseUrl: 'https://api.$domainName',
|
baseUrl: 'https://api.$domainName',
|
||||||
|
connectTimeout: 10000,
|
||||||
|
receiveTimeout: 10000,
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Bearer $apiToken',
|
'Authorization': 'Bearer $apiToken',
|
||||||
},
|
},
|
||||||
|
@ -65,6 +67,8 @@ class ServerApi extends ApiMap {
|
||||||
if (overrideDomain != null) {
|
if (overrideDomain != null) {
|
||||||
options = BaseOptions(
|
options = BaseOptions(
|
||||||
baseUrl: 'https://api.$overrideDomain',
|
baseUrl: 'https://api.$overrideDomain',
|
||||||
|
connectTimeout: 10000,
|
||||||
|
receiveTimeout: 10000,
|
||||||
headers: customToken != null
|
headers: customToken != null
|
||||||
? {'Authorization': 'Bearer $customToken'}
|
? {'Authorization': 'Bearer $customToken'}
|
||||||
: null,
|
: null,
|
||||||
|
@ -99,8 +103,8 @@ class ServerApi extends ApiMap {
|
||||||
try {
|
try {
|
||||||
response = await client.get('/services/status');
|
response = await client.get('/services/status');
|
||||||
res = response.statusCode == HttpStatus.ok;
|
res = response.statusCode == HttpStatus.ok;
|
||||||
} on DioError catch (e) {
|
} catch (e) {
|
||||||
print(e.message);
|
print(e);
|
||||||
} finally {
|
} finally {
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
@ -126,6 +130,7 @@ class ServerApi extends ApiMap {
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
||||||
data: User(
|
data: User(
|
||||||
login: user.login,
|
login: user.login,
|
||||||
|
type: UserType.normal,
|
||||||
password: user.password,
|
password: user.password,
|
||||||
isFoundOnServer: false,
|
isFoundOnServer: false,
|
||||||
),
|
),
|
||||||
|
@ -152,6 +157,7 @@ class ServerApi extends ApiMap {
|
||||||
statusCode: code,
|
statusCode: code,
|
||||||
data: User(
|
data: User(
|
||||||
login: user.login,
|
login: user.login,
|
||||||
|
type: UserType.normal,
|
||||||
password: user.password,
|
password: user.password,
|
||||||
isFoundOnServer: isFoundOnServer,
|
isFoundOnServer: isFoundOnServer,
|
||||||
),
|
),
|
||||||
|
@ -403,11 +409,11 @@ class ServerApi extends ApiMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ServiceTypes.passwordManager: response.data['bitwarden'] == 0,
|
ServiceTypes.bitwarden: response.data['bitwarden'] == 0,
|
||||||
ServiceTypes.git: response.data['gitea'] == 0,
|
ServiceTypes.gitea: response.data['gitea'] == 0,
|
||||||
ServiceTypes.cloud: response.data['nextcloud'] == 0,
|
ServiceTypes.nextcloud: response.data['nextcloud'] == 0,
|
||||||
ServiceTypes.vpn: response.data['ocserv'] == 0,
|
ServiceTypes.ocserv: response.data['ocserv'] == 0,
|
||||||
ServiceTypes.socialNetwork: response.data['pleroma'] == 0,
|
ServiceTypes.pleroma: response.data['pleroma'] == 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,51 +564,21 @@ class ServerApi extends ApiMap {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AutoUpgradeSettings> getAutoUpgradeSettings() async {
|
|
||||||
Response response;
|
|
||||||
AutoUpgradeSettings settings = const AutoUpgradeSettings(
|
|
||||||
enable: false,
|
|
||||||
allowReboot: false,
|
|
||||||
);
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/system/configuration/autoUpgrade');
|
|
||||||
if (response.data != null) {
|
|
||||||
settings = AutoUpgradeSettings.fromJson(response.data);
|
|
||||||
}
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> updateAutoUpgradeSettings(
|
|
||||||
final AutoUpgradeSettings settings,
|
|
||||||
) async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
await client.put(
|
|
||||||
'/system/configuration/autoUpgrade',
|
|
||||||
data: settings.toJson(),
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<TimeZoneSettings> getServerTimezone() async {
|
Future<TimeZoneSettings> getServerTimezone() async {
|
||||||
// I am not sure how to initialize TimeZoneSettings with default value...
|
TimeZoneSettings settings = TimeZoneSettings();
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
final Response response =
|
try {
|
||||||
await client.get('/system/configuration/timezone');
|
final Response response = await client.get(
|
||||||
close(client);
|
'/system/configuration/timezone',
|
||||||
|
);
|
||||||
|
settings = TimeZoneSettings.fromString(response.data);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
return TimeZoneSettings.fromString(response.data);
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateServerTimezone(final TimeZoneSettings settings) async {
|
Future<void> updateServerTimezone(final TimeZoneSettings settings) async {
|
||||||
|
@ -621,36 +597,23 @@ class ServerApi extends ApiMap {
|
||||||
|
|
||||||
Future<String?> getDkim() async {
|
Future<String?> getDkim() async {
|
||||||
Response response;
|
Response response;
|
||||||
|
String? dkim;
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
response = await client.get('/services/mailserver/dkim');
|
response = await client.get('/services/mailserver/dkim');
|
||||||
|
final Codec<String, String> base64toString = utf8.fuse(base64);
|
||||||
|
dkim = base64toString
|
||||||
|
.decode(response.data)
|
||||||
|
.split('(')[1]
|
||||||
|
.split(')')[0]
|
||||||
|
.replaceAll('"', '');
|
||||||
} on DioError catch (e) {
|
} on DioError catch (e) {
|
||||||
print(e.message);
|
print(e.message);
|
||||||
return null;
|
|
||||||
} finally {
|
} finally {
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.statusCode == null) {
|
return dkim;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.statusCode == HttpStatus.notFound || response.data == null) {
|
|
||||||
throw Exception('No DKIM key found');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.statusCode != HttpStatus.ok) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
final Codec<String, String> base64toString = utf8.fuse(base64);
|
|
||||||
|
|
||||||
return base64toString
|
|
||||||
.decode(response.data)
|
|
||||||
.split('(')[1]
|
|
||||||
.split(')')[0]
|
|
||||||
.replaceAll('"', '');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ApiResponse<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
|
Future<ApiResponse<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
|
||||||
|
@ -914,15 +877,15 @@ extension UrlServerExt on ServiceTypes {
|
||||||
// return ''; // external service
|
// return ''; // external service
|
||||||
// case ServiceTypes.video:
|
// case ServiceTypes.video:
|
||||||
// return ''; // jitsi meet not working
|
// return ''; // jitsi meet not working
|
||||||
case ServiceTypes.passwordManager:
|
case ServiceTypes.bitwarden:
|
||||||
return 'bitwarden';
|
return 'bitwarden';
|
||||||
case ServiceTypes.cloud:
|
case ServiceTypes.nextcloud:
|
||||||
return 'nextcloud';
|
return 'nextcloud';
|
||||||
case ServiceTypes.socialNetwork:
|
case ServiceTypes.pleroma:
|
||||||
return 'pleroma';
|
return 'pleroma';
|
||||||
case ServiceTypes.git:
|
case ServiceTypes.gitea:
|
||||||
return 'gitea';
|
return 'gitea';
|
||||||
case ServiceTypes.vpn:
|
case ServiceTypes.ocserv:
|
||||||
return 'ocserv';
|
return 'ocserv';
|
||||||
default:
|
default:
|
||||||
throw Exception('wrong state');
|
throw Exception('wrong state');
|
|
@ -0,0 +1,558 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/volume_provider.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/server_basic_info.dart';
|
||||||
|
import 'package:selfprivacy/utils/password_generator.dart';
|
||||||
|
|
||||||
|
class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
|
HetznerApi({final this.hasLogger = false, final this.isWithToken = true});
|
||||||
|
@override
|
||||||
|
bool hasLogger;
|
||||||
|
@override
|
||||||
|
bool isWithToken;
|
||||||
|
|
||||||
|
@override
|
||||||
|
BaseOptions get options {
|
||||||
|
final BaseOptions options = BaseOptions(baseUrl: rootAddress);
|
||||||
|
if (isWithToken) {
|
||||||
|
final String? token = getIt<ApiConfigModel>().hetznerKey;
|
||||||
|
assert(token != null);
|
||||||
|
options.headers = {'Authorization': 'Bearer $token'};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validateStatus != null) {
|
||||||
|
options.validateStatus = validateStatus!;
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String rootAddress = 'https://api.hetzner.cloud/v1';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> isApiTokenValid(final String token) async {
|
||||||
|
bool isValid = false;
|
||||||
|
Response? response;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
response = await client.get(
|
||||||
|
'/servers',
|
||||||
|
options: Options(
|
||||||
|
headers: {'Authorization': 'Bearer $token'},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
isValid = false;
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response != null) {
|
||||||
|
if (response.statusCode == HttpStatus.ok) {
|
||||||
|
isValid = true;
|
||||||
|
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||||
|
isValid = false;
|
||||||
|
} else {
|
||||||
|
throw Exception('code: ${response.statusCode}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
RegExp getApiTokenValidation() =>
|
||||||
|
RegExp(r'\s+|[-!$%^&*()@+|~=`{}\[\]:<>?,.\/]');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<double?> getPricePerGb() async {
|
||||||
|
double? price;
|
||||||
|
|
||||||
|
final Response dbGetResponse;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
dbGetResponse = await client.get('/pricing');
|
||||||
|
|
||||||
|
final volume = dbGetResponse.data['pricing']['volume'];
|
||||||
|
final volumePrice = volume['price_per_gb_month']['gross'];
|
||||||
|
price = double.parse(volumePrice);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ServerVolume?> createVolume() async {
|
||||||
|
ServerVolume? volume;
|
||||||
|
|
||||||
|
final Response dbCreateResponse;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
dbCreateResponse = await client.post(
|
||||||
|
'/volumes',
|
||||||
|
data: {
|
||||||
|
'size': 10,
|
||||||
|
'name': StringGenerators.dbStorageName(),
|
||||||
|
'labels': {'labelkey': 'value'},
|
||||||
|
'location': 'fsn1',
|
||||||
|
'automount': false,
|
||||||
|
'format': 'ext4'
|
||||||
|
},
|
||||||
|
);
|
||||||
|
final dbId = dbCreateResponse.data['volume']['id'];
|
||||||
|
final dbSize = dbCreateResponse.data['volume']['size'];
|
||||||
|
final dbServer = dbCreateResponse.data['volume']['server'];
|
||||||
|
final dbName = dbCreateResponse.data['volume']['name'];
|
||||||
|
final dbDevice = dbCreateResponse.data['volume']['linux_device'];
|
||||||
|
volume = ServerVolume(
|
||||||
|
id: dbId,
|
||||||
|
name: dbName,
|
||||||
|
sizeByte: dbSize,
|
||||||
|
serverId: dbServer,
|
||||||
|
linuxDevice: dbDevice,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<ServerVolume>> getVolumes({final String? status}) async {
|
||||||
|
final List<ServerVolume> volumes = [];
|
||||||
|
|
||||||
|
final Response dbGetResponse;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
dbGetResponse = await client.get(
|
||||||
|
'/volumes',
|
||||||
|
queryParameters: {
|
||||||
|
'status': status,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
final List<dynamic> rawVolumes = dbGetResponse.data['volumes'];
|
||||||
|
for (final rawVolume in rawVolumes) {
|
||||||
|
final int dbId = rawVolume['id'];
|
||||||
|
final int dbSize = rawVolume['size'] * 1024 * 1024 * 1024;
|
||||||
|
final dbServer = rawVolume['server'];
|
||||||
|
final String dbName = rawVolume['name'];
|
||||||
|
final dbDevice = rawVolume['linux_device'];
|
||||||
|
final volume = ServerVolume(
|
||||||
|
id: dbId,
|
||||||
|
name: dbName,
|
||||||
|
sizeByte: dbSize,
|
||||||
|
serverId: dbServer,
|
||||||
|
linuxDevice: dbDevice,
|
||||||
|
);
|
||||||
|
volumes.add(volume);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return volumes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ServerVolume?> getVolume(final int id) async {
|
||||||
|
ServerVolume? volume;
|
||||||
|
|
||||||
|
final Response dbGetResponse;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
dbGetResponse = await client.get('/volumes/$id');
|
||||||
|
final int dbId = dbGetResponse.data['volume']['id'];
|
||||||
|
final int dbSize = dbGetResponse.data['volume']['size'];
|
||||||
|
final int dbServer = dbGetResponse.data['volume']['server'];
|
||||||
|
final String dbName = dbGetResponse.data['volume']['name'];
|
||||||
|
final dbDevice = dbGetResponse.data['volume']['linux_device'];
|
||||||
|
volume = ServerVolume(
|
||||||
|
id: dbId,
|
||||||
|
name: dbName,
|
||||||
|
sizeByte: dbSize,
|
||||||
|
serverId: dbServer,
|
||||||
|
linuxDevice: dbDevice,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> deleteVolume(final int id) async {
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
await client.delete('/volumes/$id');
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> attachVolume(final int volumeId, final int serverId) async {
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
final Response dbPostResponse;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
dbPostResponse = await client.post(
|
||||||
|
'/volumes/$volumeId/actions/attach',
|
||||||
|
data: {
|
||||||
|
'automount': true,
|
||||||
|
'server': serverId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
success = dbPostResponse.data['action']['status'].toString() != 'error';
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> detachVolume(final int volumeId) async {
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
final Response dbPostResponse;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
dbPostResponse = await client.post('/volumes/$volumeId/actions/detach');
|
||||||
|
success = dbPostResponse.data['action']['status'].toString() != 'error';
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> resizeVolume(final int volumeId, final int sizeGb) async {
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
final Response dbPostResponse;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
dbPostResponse = await client.post(
|
||||||
|
'/volumes/$volumeId/actions/resize',
|
||||||
|
data: {
|
||||||
|
'size': sizeGb,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
success = dbPostResponse.data['action']['status'].toString() != 'error';
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ServerHostingDetails?> createServer({
|
||||||
|
required final String dnsApiToken,
|
||||||
|
required final User rootUser,
|
||||||
|
required final String domainName,
|
||||||
|
}) async {
|
||||||
|
ServerHostingDetails? details;
|
||||||
|
|
||||||
|
final ServerVolume? newVolume = await createVolume();
|
||||||
|
if (newVolume == null) {
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
details = await createServerWithVolume(
|
||||||
|
dnsApiToken: dnsApiToken,
|
||||||
|
rootUser: rootUser,
|
||||||
|
domainName: domainName,
|
||||||
|
dataBase: newVolume,
|
||||||
|
);
|
||||||
|
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ServerHostingDetails?> createServerWithVolume({
|
||||||
|
required final String dnsApiToken,
|
||||||
|
required final User rootUser,
|
||||||
|
required final String domainName,
|
||||||
|
required final ServerVolume dataBase,
|
||||||
|
}) async {
|
||||||
|
final Dio client = await getClient();
|
||||||
|
|
||||||
|
final String dbPassword = StringGenerators.dbPassword();
|
||||||
|
final int dbId = dataBase.id;
|
||||||
|
|
||||||
|
final String apiToken = StringGenerators.apiToken();
|
||||||
|
|
||||||
|
final String hostname = getHostnameFromDomain(domainName);
|
||||||
|
|
||||||
|
final String base64Password =
|
||||||
|
base64.encode(utf8.encode(rootUser.password ?? 'PASS'));
|
||||||
|
|
||||||
|
print('hostname: $hostname');
|
||||||
|
|
||||||
|
/// add ssh key when you need it: e.g. "ssh_keys":["kherel"]
|
||||||
|
/// check the branch name, it could be "development" or "master".
|
||||||
|
///
|
||||||
|
final String userdataString =
|
||||||
|
"#cloud-config\nruncmd:\n- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-21.05 DOMAIN='$domainName' LUSER='${rootUser.login}' ENCODED_PASSWORD='$base64Password' CF_TOKEN=$dnsApiToken DB_PASSWORD=$dbPassword API_TOKEN=$apiToken HOSTNAME=$hostname bash 2>&1 | tee /tmp/infect.log";
|
||||||
|
print(userdataString);
|
||||||
|
|
||||||
|
final Map<String, Object> data = {
|
||||||
|
'name': hostname,
|
||||||
|
'server_type': 'cx11',
|
||||||
|
'start_after_create': false,
|
||||||
|
'image': 'ubuntu-20.04',
|
||||||
|
'volumes': [dbId],
|
||||||
|
'networks': [],
|
||||||
|
'user_data': userdataString,
|
||||||
|
'labels': {},
|
||||||
|
'automount': true,
|
||||||
|
'location': 'fsn1'
|
||||||
|
};
|
||||||
|
print('Decoded data: $data');
|
||||||
|
|
||||||
|
ServerHostingDetails? serverDetails;
|
||||||
|
DioError? hetznerError;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Response serverCreateResponse = await client.post(
|
||||||
|
'/servers',
|
||||||
|
data: data,
|
||||||
|
);
|
||||||
|
print(serverCreateResponse.data);
|
||||||
|
serverDetails = ServerHostingDetails(
|
||||||
|
id: serverCreateResponse.data['server']['id'],
|
||||||
|
ip4: serverCreateResponse.data['server']['public_net']['ipv4']['ip'],
|
||||||
|
createTime: DateTime.now(),
|
||||||
|
volume: dataBase,
|
||||||
|
apiToken: apiToken,
|
||||||
|
provider: ServerProvider.hetzner,
|
||||||
|
);
|
||||||
|
success = true;
|
||||||
|
} on DioError catch (e) {
|
||||||
|
print(e);
|
||||||
|
hetznerError = e;
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
|
await deleteVolume(dbId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hetznerError != null) {
|
||||||
|
throw hetznerError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getHostnameFromDomain(final String domain) {
|
||||||
|
// Replace all non-alphanumeric characters with an underscore
|
||||||
|
String hostname =
|
||||||
|
domain.split('.')[0].replaceAll(RegExp(r'[^a-zA-Z0-9]'), '-');
|
||||||
|
if (hostname.endsWith('-')) {
|
||||||
|
hostname = hostname.substring(0, hostname.length - 1);
|
||||||
|
}
|
||||||
|
if (hostname.startsWith('-')) {
|
||||||
|
hostname = hostname.substring(1);
|
||||||
|
}
|
||||||
|
if (hostname.isEmpty) {
|
||||||
|
hostname = 'selfprivacy-server';
|
||||||
|
}
|
||||||
|
|
||||||
|
return hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> deleteServer({
|
||||||
|
required final String domainName,
|
||||||
|
}) async {
|
||||||
|
final Dio client = await getClient();
|
||||||
|
|
||||||
|
final String hostname = getHostnameFromDomain(domainName);
|
||||||
|
|
||||||
|
final Response serversReponse = await client.get('/servers');
|
||||||
|
final List servers = serversReponse.data['servers'];
|
||||||
|
final Map server = servers.firstWhere((final el) => el['name'] == hostname);
|
||||||
|
final List volumes = server['volumes'];
|
||||||
|
final List<Future> laterFutures = <Future>[];
|
||||||
|
|
||||||
|
for (final volumeId in volumes) {
|
||||||
|
await client.post('/volumes/$volumeId/actions/detach');
|
||||||
|
}
|
||||||
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
|
|
||||||
|
for (final volumeId in volumes) {
|
||||||
|
laterFutures.add(client.delete('/volumes/$volumeId'));
|
||||||
|
}
|
||||||
|
laterFutures.add(client.delete('/servers/${server['id']}'));
|
||||||
|
|
||||||
|
await Future.wait(laterFutures);
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ServerHostingDetails> restart() async {
|
||||||
|
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
||||||
|
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
await client.post('/servers/${server.id}/actions/reset');
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return server.copyWith(startTime: DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ServerHostingDetails> powerOn() async {
|
||||||
|
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
||||||
|
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
await client.post('/servers/${server.id}/actions/poweron');
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return server.copyWith(startTime: DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> getMetrics(
|
||||||
|
final DateTime start,
|
||||||
|
final DateTime end,
|
||||||
|
final String type,
|
||||||
|
) async {
|
||||||
|
final ServerHostingDetails? hetznerServer =
|
||||||
|
getIt<ApiConfigModel>().serverDetails;
|
||||||
|
|
||||||
|
Map<String, dynamic> metrics = {};
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
final Map<String, dynamic> queryParameters = {
|
||||||
|
'start': start.toUtc().toIso8601String(),
|
||||||
|
'end': end.toUtc().toIso8601String(),
|
||||||
|
'type': type
|
||||||
|
};
|
||||||
|
final Response res = await client.get(
|
||||||
|
'/servers/${hetznerServer!.id}/metrics',
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
);
|
||||||
|
metrics = res.data;
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return metrics;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<HetznerServerInfo> getInfo() async {
|
||||||
|
final ServerHostingDetails? hetznerServer =
|
||||||
|
getIt<ApiConfigModel>().serverDetails;
|
||||||
|
final Dio client = await getClient();
|
||||||
|
final Response response = await client.get('/servers/${hetznerServer!.id}');
|
||||||
|
close(client);
|
||||||
|
|
||||||
|
return HetznerServerInfo.fromJson(response.data!['server']);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<ServerBasicInfo>> getServers() async {
|
||||||
|
List<ServerBasicInfo> servers = [];
|
||||||
|
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
final Response response = await client.get('/servers');
|
||||||
|
servers = response.data!['servers']
|
||||||
|
.map<HetznerServerInfo>(
|
||||||
|
(final e) => HetznerServerInfo.fromJson(e),
|
||||||
|
)
|
||||||
|
.toList()
|
||||||
|
.where(
|
||||||
|
(final server) => server.publicNet.ipv4 != null,
|
||||||
|
)
|
||||||
|
.map<ServerBasicInfo>(
|
||||||
|
(final server) => ServerBasicInfo(
|
||||||
|
id: server.id,
|
||||||
|
name: server.name,
|
||||||
|
ip: server.publicNet.ipv4.ip,
|
||||||
|
reverseDns: server.publicNet.ipv4.reverseDns,
|
||||||
|
created: server.created,
|
||||||
|
volumeId: server.volumes.isNotEmpty ? server.volumes[0] : 0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
print(servers);
|
||||||
|
return servers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> createReverseDns({
|
||||||
|
required final ServerHostingDetails serverDetails,
|
||||||
|
required final ServerDomain domain,
|
||||||
|
}) async {
|
||||||
|
final Dio client = await getClient();
|
||||||
|
try {
|
||||||
|
await client.post(
|
||||||
|
'/servers/${serverDetails.id}/actions/change_dns_ptr',
|
||||||
|
data: {
|
||||||
|
'ip': serverDetails.ip4,
|
||||||
|
'dns_ptr': domain.domainName,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/volume_provider.dart';
|
||||||
|
|
||||||
|
class HetznerApiFactory extends ServerProviderApiFactory
|
||||||
|
with VolumeProviderApiFactory {
|
||||||
|
@override
|
||||||
|
ServerProviderApi getServerProvider({
|
||||||
|
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||||
|
}) =>
|
||||||
|
HetznerApi(
|
||||||
|
hasLogger: settings.hasLogger,
|
||||||
|
isWithToken: settings.isWithToken,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
VolumeProviderApi getVolumeProvider({
|
||||||
|
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||||
|
}) =>
|
||||||
|
HetznerApi(
|
||||||
|
hasLogger: settings.hasLogger,
|
||||||
|
isWithToken: settings.isWithToken,
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/server_basic_info.dart';
|
||||||
|
|
||||||
|
abstract class ServerProviderApi extends ApiMap {
|
||||||
|
Future<List<ServerBasicInfo>> getServers();
|
||||||
|
|
||||||
|
Future<ServerHostingDetails> restart();
|
||||||
|
Future<ServerHostingDetails> powerOn();
|
||||||
|
|
||||||
|
Future<void> deleteServer({required final String domainName});
|
||||||
|
Future<ServerHostingDetails?> createServer({
|
||||||
|
required final String dnsApiToken,
|
||||||
|
required final User rootUser,
|
||||||
|
required final String domainName,
|
||||||
|
});
|
||||||
|
Future<void> createReverseDns({
|
||||||
|
required final ServerHostingDetails serverDetails,
|
||||||
|
required final ServerDomain domain,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<bool> isApiTokenValid(final String token);
|
||||||
|
RegExp getApiTokenValidation();
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/volume_provider.dart';
|
||||||
|
|
||||||
|
abstract class ServerProviderApiFactory {
|
||||||
|
ServerProviderApi getServerProvider({
|
||||||
|
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin VolumeProviderApiFactory {
|
||||||
|
VolumeProviderApi getVolumeProvider({
|
||||||
|
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
|
|
||||||
|
mixin VolumeProviderApi on ApiMap {
|
||||||
|
Future<ServerVolume?> createVolume();
|
||||||
|
Future<List<ServerVolume>> getVolumes({final String? status});
|
||||||
|
Future<ServerVolume?> getVolume(final int id);
|
||||||
|
Future<bool> attachVolume(final int volumeId, final int serverId);
|
||||||
|
Future<bool> detachVolume(final int volumeId);
|
||||||
|
Future<bool> resizeVolume(final int volumeId, final int sizeGb);
|
||||||
|
Future<void> deleteVolume(final int id);
|
||||||
|
Future<double?> getPricePerGb();
|
||||||
|
}
|
|
@ -20,97 +20,104 @@ enum InitializingSteps {
|
||||||
checkSystemDnsAndDkimSet,
|
checkSystemDnsAndDkimSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Period { hour, day, month }
|
enum Period {
|
||||||
|
hour,
|
||||||
|
day,
|
||||||
|
month;
|
||||||
|
|
||||||
|
int get stepPeriodInSeconds {
|
||||||
|
switch (this) {
|
||||||
|
case Period.hour:
|
||||||
|
return 18;
|
||||||
|
case Period.day:
|
||||||
|
return 432;
|
||||||
|
case Period.month:
|
||||||
|
return 6480;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum ServiceTypes {
|
enum ServiceTypes {
|
||||||
mail,
|
mailserver,
|
||||||
messenger,
|
bitwarden,
|
||||||
passwordManager,
|
jitsi,
|
||||||
video,
|
nextcloud,
|
||||||
cloud,
|
pleroma,
|
||||||
socialNetwork,
|
gitea,
|
||||||
git,
|
ocserv,
|
||||||
vpn,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ServiceTypesExt on ServiceTypes {
|
extension ServiceTypesExt on ServiceTypes {
|
||||||
String get title {
|
String get title {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case ServiceTypes.mail:
|
case ServiceTypes.mailserver:
|
||||||
return 'services.mail.title'.tr();
|
return 'services.mail.title'.tr();
|
||||||
case ServiceTypes.messenger:
|
case ServiceTypes.bitwarden:
|
||||||
return 'services.messenger.title'.tr();
|
|
||||||
case ServiceTypes.passwordManager:
|
|
||||||
return 'services.password_manager.title'.tr();
|
return 'services.password_manager.title'.tr();
|
||||||
case ServiceTypes.video:
|
case ServiceTypes.jitsi:
|
||||||
return 'services.video.title'.tr();
|
return 'services.video.title'.tr();
|
||||||
case ServiceTypes.cloud:
|
case ServiceTypes.nextcloud:
|
||||||
return 'services.cloud.title'.tr();
|
return 'services.cloud.title'.tr();
|
||||||
case ServiceTypes.socialNetwork:
|
case ServiceTypes.pleroma:
|
||||||
return 'services.social_network.title'.tr();
|
return 'services.social_network.title'.tr();
|
||||||
case ServiceTypes.git:
|
case ServiceTypes.gitea:
|
||||||
return 'services.git.title'.tr();
|
return 'services.git.title'.tr();
|
||||||
case ServiceTypes.vpn:
|
case ServiceTypes.ocserv:
|
||||||
return 'services.vpn.title'.tr();
|
return 'services.vpn.title'.tr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String get subtitle {
|
String get subtitle {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case ServiceTypes.mail:
|
case ServiceTypes.mailserver:
|
||||||
return 'services.mail.subtitle'.tr();
|
return 'services.mail.subtitle'.tr();
|
||||||
case ServiceTypes.messenger:
|
case ServiceTypes.bitwarden:
|
||||||
return 'services.messenger.subtitle'.tr();
|
|
||||||
case ServiceTypes.passwordManager:
|
|
||||||
return 'services.password_manager.subtitle'.tr();
|
return 'services.password_manager.subtitle'.tr();
|
||||||
case ServiceTypes.video:
|
case ServiceTypes.jitsi:
|
||||||
return 'services.video.subtitle'.tr();
|
return 'services.video.subtitle'.tr();
|
||||||
case ServiceTypes.cloud:
|
case ServiceTypes.nextcloud:
|
||||||
return 'services.cloud.subtitle'.tr();
|
return 'services.cloud.subtitle'.tr();
|
||||||
case ServiceTypes.socialNetwork:
|
case ServiceTypes.pleroma:
|
||||||
return 'services.social_network.subtitle'.tr();
|
return 'services.social_network.subtitle'.tr();
|
||||||
case ServiceTypes.git:
|
case ServiceTypes.gitea:
|
||||||
return 'services.git.subtitle'.tr();
|
return 'services.git.subtitle'.tr();
|
||||||
case ServiceTypes.vpn:
|
case ServiceTypes.ocserv:
|
||||||
return 'services.vpn.subtitle'.tr();
|
return 'services.vpn.subtitle'.tr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String get loginInfo {
|
String get loginInfo {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case ServiceTypes.mail:
|
case ServiceTypes.mailserver:
|
||||||
return 'services.mail.login_info'.tr();
|
return 'services.mail.login_info'.tr();
|
||||||
case ServiceTypes.messenger:
|
case ServiceTypes.bitwarden:
|
||||||
return 'services.messenger.login_info'.tr();
|
|
||||||
case ServiceTypes.passwordManager:
|
|
||||||
return 'services.password_manager.login_info'.tr();
|
return 'services.password_manager.login_info'.tr();
|
||||||
case ServiceTypes.video:
|
case ServiceTypes.jitsi:
|
||||||
return 'services.video.login_info'.tr();
|
return 'services.video.login_info'.tr();
|
||||||
case ServiceTypes.cloud:
|
case ServiceTypes.nextcloud:
|
||||||
return 'services.cloud.login_info'.tr();
|
return 'services.cloud.login_info'.tr();
|
||||||
case ServiceTypes.socialNetwork:
|
case ServiceTypes.pleroma:
|
||||||
return 'services.social_network.login_info'.tr();
|
return 'services.social_network.login_info'.tr();
|
||||||
case ServiceTypes.git:
|
case ServiceTypes.gitea:
|
||||||
return 'services.git.login_info'.tr();
|
return 'services.git.login_info'.tr();
|
||||||
case ServiceTypes.vpn:
|
case ServiceTypes.ocserv:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String get subdomain {
|
String get subdomain {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case ServiceTypes.passwordManager:
|
case ServiceTypes.bitwarden:
|
||||||
return 'password';
|
return 'password';
|
||||||
case ServiceTypes.video:
|
case ServiceTypes.jitsi:
|
||||||
return 'meet';
|
return 'meet';
|
||||||
case ServiceTypes.cloud:
|
case ServiceTypes.nextcloud:
|
||||||
return 'cloud';
|
return 'cloud';
|
||||||
case ServiceTypes.socialNetwork:
|
case ServiceTypes.pleroma:
|
||||||
return 'social';
|
return 'social';
|
||||||
case ServiceTypes.git:
|
case ServiceTypes.gitea:
|
||||||
return 'git';
|
return 'git';
|
||||||
case ServiceTypes.vpn:
|
case ServiceTypes.ocserv:
|
||||||
case ServiceTypes.messenger:
|
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -118,21 +125,19 @@ extension ServiceTypesExt on ServiceTypes {
|
||||||
|
|
||||||
IconData get icon {
|
IconData get icon {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case ServiceTypes.mail:
|
case ServiceTypes.mailserver:
|
||||||
return BrandIcons.envelope;
|
return BrandIcons.envelope;
|
||||||
case ServiceTypes.messenger:
|
case ServiceTypes.bitwarden:
|
||||||
return BrandIcons.messanger;
|
|
||||||
case ServiceTypes.passwordManager:
|
|
||||||
return BrandIcons.key;
|
return BrandIcons.key;
|
||||||
case ServiceTypes.video:
|
case ServiceTypes.jitsi:
|
||||||
return BrandIcons.webcam;
|
return BrandIcons.webcam;
|
||||||
case ServiceTypes.cloud:
|
case ServiceTypes.nextcloud:
|
||||||
return BrandIcons.upload;
|
return BrandIcons.upload;
|
||||||
case ServiceTypes.socialNetwork:
|
case ServiceTypes.pleroma:
|
||||||
return BrandIcons.social;
|
return BrandIcons.social;
|
||||||
case ServiceTypes.git:
|
case ServiceTypes.gitea:
|
||||||
return BrandIcons.git;
|
return BrandIcons.git;
|
||||||
case ServiceTypes.vpn:
|
case ServiceTypes.ocserv:
|
||||||
return Icons.vpn_lock_outlined;
|
return Icons.vpn_lock_outlined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
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/backblaze.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/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/hive/backblaze_bucket.dart';
|
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/backup.dart';
|
import 'package:selfprivacy/logic/models/json/backup.dart';
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/job.dart';
|
import 'package:selfprivacy/logic/models/job.dart';
|
||||||
|
|
||||||
export 'package:provider/provider.dart';
|
export 'package:provider/provider.dart';
|
||||||
|
|
||||||
part 'jobs_state.dart';
|
part 'client_jobs_state.dart';
|
||||||
|
|
||||||
class JobsCubit extends Cubit<JobsState> {
|
class JobsCubit extends Cubit<JobsState> {
|
||||||
JobsCubit({
|
JobsCubit({
|
||||||
|
@ -21,10 +23,11 @@ class JobsCubit extends Cubit<JobsState> {
|
||||||
final UsersCubit usersCubit;
|
final UsersCubit usersCubit;
|
||||||
final ServicesCubit servicesCubit;
|
final ServicesCubit servicesCubit;
|
||||||
|
|
||||||
void addJob(final Job job) {
|
void addJob(final ClientJob job) {
|
||||||
final List<Job> newJobsList = <Job>[];
|
final List<ClientJob> newJobsList = [];
|
||||||
if (state is JobsStateWithJobs) {
|
if (state is JobsStateWithJobs) {
|
||||||
newJobsList.addAll((state as JobsStateWithJobs).jobList);
|
final JobsStateWithJobs jobsState = state as JobsStateWithJobs;
|
||||||
|
newJobsList.addAll(jobsState.clientJobList);
|
||||||
}
|
}
|
||||||
newJobsList.add(job);
|
newJobsList.add(job);
|
||||||
getIt<NavigationService>().showSnackBar('jobs.jobAdded'.tr());
|
getIt<NavigationService>().showSnackBar('jobs.jobAdded'.tr());
|
||||||
|
@ -37,14 +40,14 @@ class JobsCubit extends Cubit<JobsState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void createOrRemoveServiceToggleJob(final ToggleJob job) {
|
void createOrRemoveServiceToggleJob(final ToggleJob job) {
|
||||||
final List<Job> newJobsList = <Job>[];
|
final List<ClientJob> newJobsList = <ClientJob>[];
|
||||||
if (state is JobsStateWithJobs) {
|
if (state is JobsStateWithJobs) {
|
||||||
newJobsList.addAll((state as JobsStateWithJobs).jobList);
|
newJobsList.addAll((state as JobsStateWithJobs).clientJobList);
|
||||||
}
|
}
|
||||||
final bool needToRemoveJob = newJobsList
|
final bool needToRemoveJob = newJobsList
|
||||||
.any((final el) => el is ServiceToggleJob && el.type == job.type);
|
.any((final el) => el is ServiceToggleJob && el.type == job.type);
|
||||||
if (needToRemoveJob) {
|
if (needToRemoveJob) {
|
||||||
final Job removingJob = newJobsList.firstWhere(
|
final ClientJob removingJob = newJobsList.firstWhere(
|
||||||
(final el) => el is ServiceToggleJob && el.type == job.type,
|
(final el) => el is ServiceToggleJob && el.type == job.type,
|
||||||
);
|
);
|
||||||
removeJob(removingJob.id);
|
removeJob(removingJob.id);
|
||||||
|
@ -56,9 +59,9 @@ class JobsCubit extends Cubit<JobsState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void createShhJobIfNotExist(final CreateSSHKeyJob job) {
|
void createShhJobIfNotExist(final CreateSSHKeyJob job) {
|
||||||
final List<Job> newJobsList = <Job>[];
|
final List<ClientJob> newJobsList = <ClientJob>[];
|
||||||
if (state is JobsStateWithJobs) {
|
if (state is JobsStateWithJobs) {
|
||||||
newJobsList.addAll((state as JobsStateWithJobs).jobList);
|
newJobsList.addAll((state as JobsStateWithJobs).clientJobList);
|
||||||
}
|
}
|
||||||
final bool isExistInJobList =
|
final bool isExistInJobList =
|
||||||
newJobsList.any((final el) => el is CreateSSHKeyJob);
|
newJobsList.any((final el) => el is CreateSSHKeyJob);
|
||||||
|
@ -98,10 +101,11 @@ class JobsCubit extends Cubit<JobsState> {
|
||||||
|
|
||||||
Future<void> applyAll() async {
|
Future<void> applyAll() async {
|
||||||
if (state is JobsStateWithJobs) {
|
if (state is JobsStateWithJobs) {
|
||||||
final List<Job> jobs = (state as JobsStateWithJobs).jobList;
|
final List<ClientJob> jobs = (state as JobsStateWithJobs).clientJobList;
|
||||||
emit(JobsStateLoading());
|
emit(JobsStateLoading());
|
||||||
bool hasServiceJobs = false;
|
bool hasServiceJobs = false;
|
||||||
for (final Job job in jobs) {
|
for (final ClientJob job in jobs) {
|
||||||
|
// TODO: Rewrite to polymorphism
|
||||||
if (job is CreateUserJob) {
|
if (job is CreateUserJob) {
|
||||||
await usersCubit.createUser(job.user);
|
await usersCubit.createUser(job.user);
|
||||||
}
|
}
|
||||||
|
@ -110,7 +114,7 @@ class JobsCubit extends Cubit<JobsState> {
|
||||||
}
|
}
|
||||||
if (job is ServiceToggleJob) {
|
if (job is ServiceToggleJob) {
|
||||||
hasServiceJobs = true;
|
hasServiceJobs = true;
|
||||||
await api.switchService(job.type, job.needToTurnOn);
|
await api.switchService(job.type.name, job.needToTurnOn);
|
||||||
}
|
}
|
||||||
if (job is CreateSSHKeyJob) {
|
if (job is CreateSSHKeyJob) {
|
||||||
await usersCubit.addSshKey(job.user, job.publicKey);
|
await usersCubit.addSshKey(job.user, job.publicKey);
|
||||||
|
@ -118,10 +122,17 @@ class JobsCubit extends Cubit<JobsState> {
|
||||||
if (job is DeleteSSHKeyJob) {
|
if (job is DeleteSSHKeyJob) {
|
||||||
await usersCubit.deleteSshKey(job.user, job.publicKey);
|
await usersCubit.deleteSshKey(job.user, job.publicKey);
|
||||||
}
|
}
|
||||||
|
if (job is ResetUserPasswordJob) {
|
||||||
|
await usersCubit.changeUserPassword(job.user, job.user.password!);
|
||||||
|
}
|
||||||
|
if (job is RebuildServerJob) {
|
||||||
|
await upgradeServer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await api.pullConfigurationUpdate();
|
await api.pullConfigurationUpdate();
|
||||||
await api.apply();
|
await api.apply();
|
||||||
|
|
||||||
if (hasServiceJobs) {
|
if (hasServiceJobs) {
|
||||||
await servicesCubit.load();
|
await servicesCubit.load();
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
part of 'jobs_cubit.dart';
|
part of 'client_jobs_cubit.dart';
|
||||||
|
|
||||||
abstract class JobsState extends Equatable {
|
abstract class JobsState extends Equatable {
|
||||||
@override
|
@override
|
||||||
|
@ -10,13 +10,11 @@ class JobsStateLoading extends JobsState {}
|
||||||
class JobsStateEmpty extends JobsState {}
|
class JobsStateEmpty extends JobsState {}
|
||||||
|
|
||||||
class JobsStateWithJobs extends JobsState {
|
class JobsStateWithJobs extends JobsState {
|
||||||
JobsStateWithJobs(this.jobList);
|
JobsStateWithJobs(this.clientJobList);
|
||||||
final List<Job> jobList;
|
final List<ClientJob> clientJobList;
|
||||||
|
|
||||||
JobsState removeById(final String id) {
|
JobsState removeById(final String id) {
|
||||||
final List<Job> newJobsList =
|
final List<ClientJob> newJobsList =
|
||||||
jobList.where((final element) => element.id != id).toList();
|
clientJobList.where((final element) => element.id != id).toList();
|
||||||
|
|
||||||
if (newJobsList.isEmpty) {
|
if (newJobsList.isEmpty) {
|
||||||
return JobsStateEmpty();
|
return JobsStateEmpty();
|
||||||
}
|
}
|
||||||
|
@ -24,5 +22,5 @@ class JobsStateWithJobs extends JobsState {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => jobList;
|
List<Object?> get props => clientJobList;
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
import 'package:selfprivacy/logic/common_enum/common_enum.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/json/api_token.dart';
|
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
||||||
|
@ -16,17 +16,16 @@ class ApiDevicesCubit
|
||||||
@override
|
@override
|
||||||
void load() async {
|
void load() async {
|
||||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
final List<ApiToken>? devices = await _getApiTokens();
|
_refetch();
|
||||||
if (devices != null) {
|
|
||||||
emit(ApiDevicesState(devices, LoadingStatus.success));
|
|
||||||
} else {
|
|
||||||
emit(const ApiDevicesState([], LoadingStatus.error));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> refresh() async {
|
Future<void> refresh() async {
|
||||||
emit(const ApiDevicesState([], LoadingStatus.refreshing));
|
emit(const ApiDevicesState([], LoadingStatus.refreshing));
|
||||||
|
_refetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _refetch() async {
|
||||||
final List<ApiToken>? devices = await _getApiTokens();
|
final List<ApiToken>? devices = await _getApiTokens();
|
||||||
if (devices != null) {
|
if (devices != null) {
|
||||||
emit(ApiDevicesState(devices, LoadingStatus.success));
|
emit(ApiDevicesState(devices, LoadingStatus.success));
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.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/hive/server_domain.dart';
|
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/cloudflare.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
|
||||||
|
|
||||||
part 'dns_records_state.dart';
|
part 'dns_records_state.dart';
|
||||||
|
|
||||||
|
@ -16,8 +18,12 @@ class DnsRecordsCubit
|
||||||
const DnsRecordsState(dnsState: DnsRecordsStatus.refreshing),
|
const DnsRecordsState(dnsState: DnsRecordsStatus.refreshing),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DnsProviderApiFactory? dnsProviderApiFactory =
|
||||||
|
ApiFactoryCreator.createDnsProviderApiFactory(
|
||||||
|
DnsProvider.cloudflare, // TODO: HARDCODE FOR NOW!!!
|
||||||
|
); // TODO: Remove when provider selection is implemented.
|
||||||
|
|
||||||
final ServerApi api = ServerApi();
|
final ServerApi api = ServerApi();
|
||||||
final CloudflareApi cloudflare = CloudflareApi();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
|
@ -31,14 +37,15 @@ class DnsRecordsCubit
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
print('Loading DNS status');
|
|
||||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
final ServerDomain? domain = serverInstallationCubit.state.serverDomain;
|
final ServerDomain? domain = serverInstallationCubit.state.serverDomain;
|
||||||
final String? ipAddress =
|
final String? ipAddress =
|
||||||
serverInstallationCubit.state.serverDetails?.ip4;
|
serverInstallationCubit.state.serverDetails?.ip4;
|
||||||
if (domain != null && ipAddress != null) {
|
if (domain != null && ipAddress != null) {
|
||||||
final List<DnsRecord> records =
|
final List<DnsRecord> records = await dnsProviderApiFactory!
|
||||||
await cloudflare.getDnsRecords(cloudFlareDomain: domain);
|
.getDnsProvider()
|
||||||
|
.getDnsRecords(domain: domain);
|
||||||
final String? dkimPublicKey = await api.getDkim();
|
final String? dkimPublicKey = await api.getDkim();
|
||||||
final List<DesiredDnsRecord> desiredRecords =
|
final List<DesiredDnsRecord> desiredRecords =
|
||||||
_getDesiredDnsRecords(domain.domainName, ipAddress, dkimPublicKey);
|
_getDesiredDnsRecords(domain.domainName, ipAddress, dkimPublicKey);
|
||||||
|
@ -116,12 +123,14 @@ class DnsRecordsCubit
|
||||||
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 String? dkimPublicKey = await api.getDkim();
|
||||||
await cloudflare.removeSimilarRecords(cloudFlareDomain: domain!);
|
final DnsProviderApi dnsProviderApi =
|
||||||
await cloudflare.createMultipleDnsRecords(
|
dnsProviderApiFactory!.getDnsProvider();
|
||||||
cloudFlareDomain: domain,
|
await dnsProviderApi.removeSimilarRecords(domain: domain!);
|
||||||
|
await dnsProviderApi.createMultipleDnsRecords(
|
||||||
|
domain: domain,
|
||||||
ip4: ipAddress,
|
ip4: ipAddress,
|
||||||
);
|
);
|
||||||
await cloudflare.setDkim(dkimPublicKey ?? '', domain);
|
await dnsProviderApi.setDkim(dkimPublicKey ?? '', domain);
|
||||||
await load();
|
await load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +139,7 @@ class DnsRecordsCubit
|
||||||
final String? ipAddress,
|
final String? ipAddress,
|
||||||
final String? dkimPublicKey,
|
final String? dkimPublicKey,
|
||||||
) {
|
) {
|
||||||
if (domainName == null || ipAddress == null || dkimPublicKey == null) {
|
if (domainName == null || ipAddress == null) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
|
@ -195,13 +204,14 @@ class DnsRecordsCubit
|
||||||
type: 'TXT',
|
type: 'TXT',
|
||||||
category: DnsRecordsCategory.email,
|
category: DnsRecordsCategory.email,
|
||||||
),
|
),
|
||||||
DesiredDnsRecord(
|
if (dkimPublicKey != null)
|
||||||
name: 'selector._domainkey.$domainName',
|
DesiredDnsRecord(
|
||||||
content: dkimPublicKey,
|
name: 'selector._domainkey.$domainName',
|
||||||
description: 'providers.domain.record_description.dkim',
|
content: dkimPublicKey,
|
||||||
type: 'TXT',
|
description: 'providers.domain.record_description.dkim',
|
||||||
category: DnsRecordsCategory.email,
|
type: 'TXT',
|
||||||
),
|
category: DnsRecordsCategory.email,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/backblaze.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
@ -55,10 +55,11 @@ class BackblazeFormCubit extends FormCubit {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isKeyValid) {
|
if (!isKeyValid) {
|
||||||
keyId.setError('bad key');
|
keyId.setError('initializing.backblaze_bad_key_error'.tr());
|
||||||
applicationKey.setError('bad key');
|
applicationKey.setError('initializing.backblaze_bad_key_error'.tr());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,12 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
||||||
|
|
||||||
class CloudFlareFormCubit extends FormCubit {
|
class DnsProviderFormCubit extends FormCubit {
|
||||||
CloudFlareFormCubit(this.initializingCubit) {
|
DnsProviderFormCubit(this.initializingCubit) {
|
||||||
final RegExp regExp = RegExp(r'\s+|[!$%^&*()@+|~=`{}\[\]:<>?,.\/]');
|
final RegExp regExp = initializingCubit.getDnsProviderApiTokenValidation();
|
||||||
apiKey = FieldCubit(
|
apiKey = FieldCubit(
|
||||||
initalValue: '',
|
initalValue: '',
|
||||||
validations: [
|
validations: [
|
||||||
|
@ -30,24 +29,25 @@ class CloudFlareFormCubit extends FormCubit {
|
||||||
}
|
}
|
||||||
|
|
||||||
final ServerInstallationCubit initializingCubit;
|
final ServerInstallationCubit initializingCubit;
|
||||||
|
|
||||||
late final FieldCubit<String> apiKey;
|
late final FieldCubit<String> apiKey;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> asyncValidation() async {
|
FutureOr<bool> asyncValidation() async {
|
||||||
late bool isKeyValid;
|
late bool isKeyValid;
|
||||||
final CloudflareApi apiClient = CloudflareApi(isWithToken: false);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
isKeyValid = await apiClient.isValid(apiKey.state.value);
|
isKeyValid = await initializingCubit
|
||||||
|
.isDnsProviderApiTokenValid(apiKey.state.value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
addError(e);
|
addError(e);
|
||||||
|
isKeyValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isKeyValid) {
|
if (!isKeyValid) {
|
||||||
apiKey.setError('bad key');
|
apiKey.setError('initializing.cloudflare_bad_key_error'.tr());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||||
|
|
||||||
|
@ -10,9 +9,10 @@ class DomainSetupCubit extends Cubit<DomainSetupState> {
|
||||||
|
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
emit(Loading(LoadingTypes.loadingDomain));
|
emit(Loading(LoadingTypes.loadingDomain));
|
||||||
final CloudflareApi api = CloudflareApi();
|
final List<String> list = await serverInstallationCubit
|
||||||
|
.repository.dnsProviderApiFactory!
|
||||||
final List<String> list = await api.domainList();
|
.getDnsProvider()
|
||||||
|
.domainList();
|
||||||
if (list.isEmpty) {
|
if (list.isEmpty) {
|
||||||
emit(Empty());
|
emit(Empty());
|
||||||
} else if (list.length == 1) {
|
} else if (list.length == 1) {
|
||||||
|
@ -28,20 +28,24 @@ class DomainSetupCubit extends Cubit<DomainSetupState> {
|
||||||
Future<void> saveDomain() async {
|
Future<void> saveDomain() async {
|
||||||
assert(state is Loaded, 'wrong state');
|
assert(state is Loaded, 'wrong state');
|
||||||
final String domainName = (state as Loaded).domain;
|
final String domainName = (state as Loaded).domain;
|
||||||
final CloudflareApi api = CloudflareApi();
|
|
||||||
|
|
||||||
emit(Loading(LoadingTypes.saving));
|
emit(Loading(LoadingTypes.saving));
|
||||||
|
|
||||||
final String zoneId = await api.getZoneId(domainName);
|
final String? zoneId = await serverInstallationCubit
|
||||||
|
.repository.dnsProviderApiFactory!
|
||||||
|
.getDnsProvider()
|
||||||
|
.getZoneId(domainName);
|
||||||
|
|
||||||
final ServerDomain domain = ServerDomain(
|
if (zoneId != null) {
|
||||||
domainName: domainName,
|
final ServerDomain domain = ServerDomain(
|
||||||
zoneId: zoneId,
|
domainName: domainName,
|
||||||
provider: DnsProvider.cloudflare,
|
zoneId: zoneId,
|
||||||
);
|
provider: DnsProvider.cloudflare,
|
||||||
|
);
|
||||||
|
|
||||||
serverInstallationCubit.setDomain(domain);
|
serverInstallationCubit.setDomain(domain);
|
||||||
emit(DomainSet());
|
emit(DomainSet());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/hetzner.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
||||||
|
|
||||||
class HetznerFormCubit extends FormCubit {
|
class ProviderFormCubit extends FormCubit {
|
||||||
HetznerFormCubit(this.serverInstallationCubit) {
|
ProviderFormCubit(this.serverInstallationCubit) {
|
||||||
final RegExp regExp = RegExp(r'\s+|[-!$%^&*()@+|~=`{}\[\]:<>?,.\/]');
|
final RegExp regExp =
|
||||||
|
serverInstallationCubit.getServerProviderApiTokenValidation();
|
||||||
apiKey = FieldCubit(
|
apiKey = FieldCubit(
|
||||||
initalValue: '',
|
initalValue: '',
|
||||||
validations: [
|
validations: [
|
||||||
|
@ -30,24 +30,25 @@ class HetznerFormCubit extends FormCubit {
|
||||||
}
|
}
|
||||||
|
|
||||||
final ServerInstallationCubit serverInstallationCubit;
|
final ServerInstallationCubit serverInstallationCubit;
|
||||||
|
|
||||||
late final FieldCubit<String> apiKey;
|
late final FieldCubit<String> apiKey;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> asyncValidation() async {
|
FutureOr<bool> asyncValidation() async {
|
||||||
late bool isKeyValid;
|
late bool isKeyValid;
|
||||||
final HetznerApi apiClient = HetznerApi(isWithToken: false);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
isKeyValid = await apiClient.isValid(apiKey.state.value);
|
isKeyValid = await serverInstallationCubit
|
||||||
|
.isServerProviderApiTokenValid(apiKey.state.value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
addError(e);
|
addError(e);
|
||||||
|
isKeyValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isKeyValid) {
|
if (!isKeyValid) {
|
||||||
apiKey.setError('bad key');
|
apiKey.setError('initializing.hetzner_bad_key_error'.tr());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
|
|
||||||
class RootUserFormCubit extends FormCubit {
|
class RootUserFormCubit extends FormCubit {
|
||||||
|
@ -22,6 +22,7 @@ class RootUserFormCubit extends FormCubit {
|
||||||
FutureOr<void> onSubmit() async {
|
FutureOr<void> onSubmit() async {
|
||||||
final User user = User(
|
final User user = User(
|
||||||
login: userName.state.value,
|
login: userName.state.value,
|
||||||
|
type: UserType.primary,
|
||||||
password: password.state.value,
|
password: password.state.value,
|
||||||
);
|
);
|
||||||
serverInstallationCubit.setRootUser(user);
|
serverInstallationCubit.setRootUser(user);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||||
|
|
||||||
|
@ -18,8 +18,9 @@ class RecoveryDomainFormCubit extends FormCubit {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<void> onSubmit() async {
|
FutureOr<void> onSubmit() async {
|
||||||
initializingCubit
|
initializingCubit.submitDomainForAccessRecovery(
|
||||||
.submitDomainForAccessRecovery(serverDomainField.state.value);
|
serverDomainField.state.value.toLowerCase(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/job.dart';
|
import 'package:selfprivacy/logic/models/job.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
|
|
||||||
|
@ -41,7 +41,8 @@ class SshFormCubit extends FormCubit {
|
||||||
@override
|
@override
|
||||||
FutureOr<void> onSubmit() {
|
FutureOr<void> onSubmit() {
|
||||||
print(key.state.isValid);
|
print(key.state.isValid);
|
||||||
jobsCubit.addJob(CreateSSHKeyJob(user: user, publicKey: key.state.value));
|
jobsCubit
|
||||||
|
.addJob(CreateSSHKeyJob(user: user, publicKey: key.state.value.trim()));
|
||||||
}
|
}
|
||||||
|
|
||||||
late FieldCubit<String> key;
|
late FieldCubit<String> key;
|
||||||
|
|
|
@ -1,37 +1,60 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/job.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/job.dart';
|
||||||
import 'package:selfprivacy/utils/password_generator.dart';
|
import 'package:selfprivacy/utils/password_generator.dart';
|
||||||
|
|
||||||
class UserFormCubit extends FormCubit {
|
class UserFormCubit extends FormCubit {
|
||||||
UserFormCubit({
|
UserFormCubit({
|
||||||
required this.jobsCubit,
|
required this.jobsCubit,
|
||||||
required final FieldCubitFactory fieldFactory,
|
required final FieldCubitFactory fieldFactory,
|
||||||
final User? user,
|
final this.initialUser,
|
||||||
}) {
|
}) {
|
||||||
final bool isEdit = user != null;
|
if (initialUser == null) {
|
||||||
|
login = fieldFactory.createUserLoginField();
|
||||||
|
login.setValue('');
|
||||||
|
password = fieldFactory.createUserPasswordField();
|
||||||
|
password.setValue(
|
||||||
|
StringGenerators.userPassword(),
|
||||||
|
);
|
||||||
|
|
||||||
login = fieldFactory.createUserLoginField();
|
super.addFields([login, password]);
|
||||||
login.setValue(isEdit ? user.login : '');
|
} else {
|
||||||
password = fieldFactory.createUserPasswordField();
|
login = fieldFactory.createRequiredStringField();
|
||||||
password.setValue(
|
login.setValue(initialUser!.login);
|
||||||
isEdit ? (user.password ?? '') : StringGenerators.userPassword(),
|
password = fieldFactory.createUserPasswordField();
|
||||||
);
|
password.setValue(
|
||||||
|
initialUser?.password ?? '',
|
||||||
|
);
|
||||||
|
|
||||||
super.addFields([login, password]);
|
super.addFields([login, password]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<void> onSubmit() {
|
FutureOr<void> onSubmit() {
|
||||||
final User user = User(
|
print('onSubmit');
|
||||||
login: login.state.value,
|
print('initialUser: $initialUser');
|
||||||
password: password.state.value,
|
print('login: ${login.state.value}');
|
||||||
);
|
print('password: ${password.state.value}');
|
||||||
jobsCubit.addJob(CreateUserJob(user: user));
|
if (initialUser == null) {
|
||||||
|
final User user = User(
|
||||||
|
login: login.state.value,
|
||||||
|
type: UserType.normal,
|
||||||
|
password: password.state.value,
|
||||||
|
);
|
||||||
|
jobsCubit.addJob(CreateUserJob(user: user));
|
||||||
|
} else {
|
||||||
|
final User user = User(
|
||||||
|
login: initialUser?.login ?? login.state.value,
|
||||||
|
type: initialUser?.type ?? UserType.normal,
|
||||||
|
password: password.state.value,
|
||||||
|
);
|
||||||
|
jobsCubit.addJob(ResetUserPasswordJob(user: user));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
late FieldCubit<String> login;
|
late FieldCubit<String> login;
|
||||||
|
@ -42,4 +65,5 @@ class UserFormCubit extends FormCubit {
|
||||||
}
|
}
|
||||||
|
|
||||||
final JobsCubit jobsCubit;
|
final JobsCubit jobsCubit;
|
||||||
|
final User? initialUser;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,20 @@ class HetznerMetricsCubit extends Cubit<HetznerMetricsState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(final Period period) async {
|
void load(final Period period) async {
|
||||||
final HetznerMetricsLoaded newState = await repository.getMetrics(period);
|
try {
|
||||||
timer = Timer(
|
final HetznerMetricsLoaded newState = await repository.getMetrics(period);
|
||||||
Duration(seconds: newState.stepInSeconds.toInt()),
|
timer = Timer(
|
||||||
() => load(newState.period),
|
Duration(seconds: newState.stepInSeconds.toInt()),
|
||||||
);
|
() => load(newState.period),
|
||||||
|
);
|
||||||
emit(newState);
|
emit(newState);
|
||||||
|
} on StateError {
|
||||||
|
print('Tried to emit Hetzner metrics when cubit is closed');
|
||||||
|
} on MetricsLoadException {
|
||||||
|
timer = Timer(
|
||||||
|
Duration(seconds: state.period.stepPeriodInSeconds),
|
||||||
|
() => load(state.period),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import 'package:selfprivacy/logic/api_maps/hetzner.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
import 'package:selfprivacy/logic/models/hetzner_metrics.dart';
|
import 'package:selfprivacy/logic/models/hetzner_metrics.dart';
|
||||||
|
|
||||||
import 'package:selfprivacy/logic/cubit/hetzner_metrics/hetzner_metrics_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/hetzner_metrics/hetzner_metrics_cubit.dart';
|
||||||
|
|
||||||
|
class MetricsLoadException implements Exception {
|
||||||
|
MetricsLoadException(this.message);
|
||||||
|
final String message;
|
||||||
|
}
|
||||||
|
|
||||||
class HetznerMetricsRepository {
|
class HetznerMetricsRepository {
|
||||||
Future<HetznerMetricsLoaded> getMetrics(final Period period) async {
|
Future<HetznerMetricsLoaded> getMetrics(final Period period) async {
|
||||||
final DateTime end = DateTime.now();
|
final DateTime end = DateTime.now();
|
||||||
|
@ -21,7 +26,7 @@ class HetznerMetricsRepository {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final HetznerApi api = HetznerApi(hasLogger: true);
|
final HetznerApi api = HetznerApi(hasLogger: false);
|
||||||
|
|
||||||
final List<Map<String, dynamic>> results = await Future.wait([
|
final List<Map<String, dynamic>> results = await Future.wait([
|
||||||
api.getMetrics(start, end, 'cpu'),
|
api.getMetrics(start, end, 'cpu'),
|
||||||
|
@ -31,6 +36,10 @@ class HetznerMetricsRepository {
|
||||||
final cpuMetricsData = results[0]['metrics'];
|
final cpuMetricsData = results[0]['metrics'];
|
||||||
final networkMetricsData = results[1]['metrics'];
|
final networkMetricsData = results[1]['metrics'];
|
||||||
|
|
||||||
|
if (cpuMetricsData == null || networkMetricsData == null) {
|
||||||
|
throw MetricsLoadException('Metrics data is null');
|
||||||
|
}
|
||||||
|
|
||||||
return HetznerMetricsLoaded(
|
return HetznerMetricsLoaded(
|
||||||
period: period,
|
period: period,
|
||||||
start: start,
|
start: start,
|
||||||
|
|
141
lib/logic/cubit/provider_volumes/provider_volume_cubit.dart
Normal file
141
lib/logic/cubit/provider_volumes/provider_volume_cubit.dart
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
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/rest_maps/api_factory_creator.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/disk_status.dart';
|
||||||
|
|
||||||
|
part 'provider_volume_state.dart';
|
||||||
|
|
||||||
|
class ApiProviderVolumeCubit
|
||||||
|
extends ServerInstallationDependendCubit<ApiProviderVolumeState> {
|
||||||
|
ApiProviderVolumeCubit(final ServerInstallationCubit serverInstallationCubit)
|
||||||
|
: super(serverInstallationCubit, const ApiProviderVolumeState.initial());
|
||||||
|
|
||||||
|
VolumeProviderApiFactory? providerApi;
|
||||||
|
|
||||||
|
final ServerApi serverApi = ServerApi();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> load() async {
|
||||||
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
|
final serverDetails = getIt<ApiConfigModel>().serverDetails;
|
||||||
|
providerApi = serverDetails == null
|
||||||
|
? null
|
||||||
|
: VolumeApiFactoryCreator.createVolumeProviderApiFactory(
|
||||||
|
getIt<ApiConfigModel>().serverDetails!.provider,
|
||||||
|
);
|
||||||
|
_refetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<double?> getPricePerGb() async =>
|
||||||
|
providerApi!.getVolumeProvider().getPricePerGb();
|
||||||
|
|
||||||
|
Future<void> refresh() async {
|
||||||
|
emit(const ApiProviderVolumeState([], LoadingStatus.refreshing, false));
|
||||||
|
_refetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _refetch() async {
|
||||||
|
if (providerApi == null) {
|
||||||
|
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<ServerVolume> volumes =
|
||||||
|
await providerApi!.getVolumeProvider().getVolumes();
|
||||||
|
|
||||||
|
if (volumes.isEmpty) {
|
||||||
|
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(ApiProviderVolumeState(volumes, LoadingStatus.success, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> attachVolume(final DiskVolume volume) async {
|
||||||
|
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
||||||
|
await providerApi!
|
||||||
|
.getVolumeProvider()
|
||||||
|
.attachVolume(volume.providerVolume!.id, server.id);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> detachVolume(final DiskVolume volume) async {
|
||||||
|
await providerApi!
|
||||||
|
.getVolumeProvider()
|
||||||
|
.detachVolume(volume.providerVolume!.id);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> resizeVolume(
|
||||||
|
final DiskVolume volume,
|
||||||
|
final int newSizeGb,
|
||||||
|
final Function() callback,
|
||||||
|
) async {
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Starting resize',
|
||||||
|
);
|
||||||
|
emit(state.copyWith(isResizing: true));
|
||||||
|
final bool resized = await providerApi!.getVolumeProvider().resizeVolume(
|
||||||
|
volume.providerVolume!.id,
|
||||||
|
newSizeGb,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!resized) {
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'providers.storage.extending_volume_error'.tr(),
|
||||||
|
);
|
||||||
|
emit(state.copyWith(isResizing: false));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Hetzner resized, waiting 10 seconds',
|
||||||
|
);
|
||||||
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
|
|
||||||
|
await ServerApi().resizeVolume(volume.name);
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Server api resized, waiting 20 seconds',
|
||||||
|
);
|
||||||
|
|
||||||
|
await Future.delayed(const Duration(seconds: 20));
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Restarting server',
|
||||||
|
);
|
||||||
|
|
||||||
|
await refresh();
|
||||||
|
emit(state.copyWith(isResizing: false));
|
||||||
|
await callback();
|
||||||
|
await serverApi.reboot();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> createVolume() async {
|
||||||
|
final ServerVolume? volume =
|
||||||
|
await providerApi!.getVolumeProvider().createVolume();
|
||||||
|
|
||||||
|
final diskVolume = DiskVolume(providerVolume: volume);
|
||||||
|
await attachVolume(diskVolume);
|
||||||
|
|
||||||
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
|
|
||||||
|
await ServerApi().mountVolume(volume!.name);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteVolume(final DiskVolume volume) async {
|
||||||
|
await providerApi!
|
||||||
|
.getVolumeProvider()
|
||||||
|
.deleteVolume(volume.providerVolume!.id);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void clear() {
|
||||||
|
emit(const ApiProviderVolumeState.initial());
|
||||||
|
}
|
||||||
|
}
|
27
lib/logic/cubit/provider_volumes/provider_volume_state.dart
Normal file
27
lib/logic/cubit/provider_volumes/provider_volume_state.dart
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
part of 'provider_volume_cubit.dart';
|
||||||
|
|
||||||
|
class ApiProviderVolumeState extends ServerInstallationDependendState {
|
||||||
|
const ApiProviderVolumeState(this._volumes, this.status, this.isResizing);
|
||||||
|
|
||||||
|
const ApiProviderVolumeState.initial()
|
||||||
|
: this(const [], LoadingStatus.uninitialized, false);
|
||||||
|
final List<ServerVolume> _volumes;
|
||||||
|
final LoadingStatus status;
|
||||||
|
final bool isResizing;
|
||||||
|
|
||||||
|
List<ServerVolume> get volumes => _volumes;
|
||||||
|
|
||||||
|
ApiProviderVolumeState copyWith({
|
||||||
|
final List<ServerVolume>? volumes,
|
||||||
|
final LoadingStatus? status,
|
||||||
|
final bool? isResizing,
|
||||||
|
}) =>
|
||||||
|
ApiProviderVolumeState(
|
||||||
|
volumes ?? _volumes,
|
||||||
|
status ?? this.status,
|
||||||
|
isResizing ?? this.isResizing,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [_volumes, status, isResizing];
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
import 'package:selfprivacy/logic/common_enum/common_enum.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/json/recovery_token_status.dart';
|
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
|
||||||
|
|
|
@ -1,33 +1,48 @@
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:equatable/equatable.dart';
|
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_repository.dart';
|
import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_repository.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/auto_upgrade_settings.dart';
|
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
||||||
import 'package:selfprivacy/logic/models/timezone_settings.dart';
|
import 'package:selfprivacy/logic/models/timezone_settings.dart';
|
||||||
|
|
||||||
part 'server_detailed_info_state.dart';
|
part 'server_detailed_info_state.dart';
|
||||||
|
|
||||||
class ServerDetailsCubit extends Cubit<ServerDetailsState> {
|
class ServerDetailsCubit
|
||||||
ServerDetailsCubit() : super(ServerDetailsInitial());
|
extends ServerInstallationDependendCubit<ServerDetailsState> {
|
||||||
|
ServerDetailsCubit(final ServerInstallationCubit serverInstallationCubit)
|
||||||
|
: super(serverInstallationCubit, ServerDetailsInitial());
|
||||||
|
|
||||||
ServerDetailsRepository repository = ServerDetailsRepository();
|
ServerDetailsRepository repository = ServerDetailsRepository();
|
||||||
|
|
||||||
void check() async {
|
void check() async {
|
||||||
final bool isReadyToCheck = getIt<ApiConfigModel>().serverDetails != null;
|
final bool isReadyToCheck = getIt<ApiConfigModel>().serverDetails != null;
|
||||||
if (isReadyToCheck) {
|
try {
|
||||||
emit(ServerDetailsLoading());
|
if (isReadyToCheck) {
|
||||||
final ServerDetailsRepositoryDto data = await repository.load();
|
emit(ServerDetailsLoading());
|
||||||
emit(
|
final ServerDetailsRepositoryDto data = await repository.load();
|
||||||
Loaded(
|
emit(
|
||||||
serverInfo: data.hetznerServerInfo,
|
Loaded(
|
||||||
autoUpgradeSettings: data.autoUpgradeSettings,
|
serverInfo: data.hetznerServerInfo,
|
||||||
serverTimezone: data.serverTimezone,
|
autoUpgradeSettings: data.autoUpgradeSettings,
|
||||||
checkTime: DateTime.now(),
|
serverTimezone: data.serverTimezone,
|
||||||
),
|
checkTime: DateTime.now(),
|
||||||
);
|
),
|
||||||
} else {
|
);
|
||||||
emit(ServerDetailsNotReady());
|
} else {
|
||||||
|
emit(ServerDetailsNotReady());
|
||||||
|
}
|
||||||
|
} on StateError {
|
||||||
|
print('Tried to emit server info state when cubit is closed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void clear() {
|
||||||
|
emit(ServerDetailsNotReady());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void load() async {
|
||||||
|
check();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,37 @@
|
||||||
import 'package:selfprivacy/logic/api_maps/hetzner.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/auto_upgrade_settings.dart';
|
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
||||||
import 'package:selfprivacy/logic/models/timezone_settings.dart';
|
import 'package:selfprivacy/logic/models/timezone_settings.dart';
|
||||||
|
|
||||||
class ServerDetailsRepository {
|
class ServerDetailsRepository {
|
||||||
HetznerApi hetznerAPi = HetznerApi();
|
HetznerApi hetzner = HetznerApi();
|
||||||
ServerApi selfprivacyServer = ServerApi();
|
ServerApi server = ServerApi();
|
||||||
|
|
||||||
Future<ServerDetailsRepositoryDto> load() async {
|
Future<ServerDetailsRepositoryDto> load() async {
|
||||||
print('load');
|
final settings = await server.getSystemSettings();
|
||||||
return ServerDetailsRepositoryDto(
|
return ServerDetailsRepositoryDto(
|
||||||
autoUpgradeSettings: await selfprivacyServer.getAutoUpgradeSettings(),
|
autoUpgradeSettings: settings.autoUpgradeSettings,
|
||||||
hetznerServerInfo: await hetznerAPi.getInfo(),
|
hetznerServerInfo: await hetzner.getInfo(),
|
||||||
serverTimezone: await selfprivacyServer.getServerTimezone(),
|
serverTimezone: TimeZoneSettings.fromString(
|
||||||
|
settings.timezone,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> setAutoUpgradeSettings(
|
||||||
|
final AutoUpgradeSettings settings,
|
||||||
|
) async {
|
||||||
|
await server.setAutoUpgradeSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setTimezone(
|
||||||
|
final String timezone,
|
||||||
|
) async {
|
||||||
|
if (timezone.isNotEmpty) {
|
||||||
|
await server.setTimezone(timezone);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ServerDetailsRepositoryDto {
|
class ServerDetailsRepositoryDto {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
part of 'server_detailed_info_cubit.dart';
|
part of 'server_detailed_info_cubit.dart';
|
||||||
|
|
||||||
abstract class ServerDetailsState extends Equatable {
|
abstract class ServerDetailsState extends ServerInstallationDependendState {
|
||||||
const ServerDetailsState();
|
const ServerDetailsState();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -4,6 +4,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
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';
|
||||||
|
@ -49,13 +51,40 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegExp getServerProviderApiTokenValidation() =>
|
||||||
|
repository.serverProviderApiFactory!
|
||||||
|
.getServerProvider()
|
||||||
|
.getApiTokenValidation();
|
||||||
|
|
||||||
|
RegExp getDnsProviderApiTokenValidation() => repository.dnsProviderApiFactory!
|
||||||
|
.getDnsProvider()
|
||||||
|
.getApiTokenValidation();
|
||||||
|
|
||||||
|
Future<bool> isServerProviderApiTokenValid(
|
||||||
|
final String providerToken,
|
||||||
|
) async =>
|
||||||
|
repository.serverProviderApiFactory!
|
||||||
|
.getServerProvider(
|
||||||
|
settings: const ProviderApiSettings(isWithToken: false),
|
||||||
|
)
|
||||||
|
.isApiTokenValid(providerToken);
|
||||||
|
|
||||||
|
Future<bool> isDnsProviderApiTokenValid(
|
||||||
|
final String providerToken,
|
||||||
|
) async =>
|
||||||
|
repository.dnsProviderApiFactory!
|
||||||
|
.getDnsProvider(
|
||||||
|
settings: const DnsProviderApiSettings(isWithToken: false),
|
||||||
|
)
|
||||||
|
.isApiTokenValid(providerToken);
|
||||||
|
|
||||||
void setHetznerKey(final String hetznerKey) async {
|
void setHetznerKey(final String hetznerKey) async {
|
||||||
await repository.saveHetznerKey(hetznerKey);
|
await repository.saveHetznerKey(hetznerKey);
|
||||||
|
|
||||||
if (state is ServerInstallationRecovery) {
|
if (state is ServerInstallationRecovery) {
|
||||||
emit(
|
emit(
|
||||||
(state as ServerInstallationRecovery).copyWith(
|
(state as ServerInstallationRecovery).copyWith(
|
||||||
hetznerKey: hetznerKey,
|
providerApiToken: hetznerKey,
|
||||||
currentStep: RecoveryStep.serverSelection,
|
currentStep: RecoveryStep.serverSelection,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -63,7 +92,9 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
(state as ServerInstallationNotFinished).copyWith(hetznerKey: hetznerKey),
|
(state as ServerInstallationNotFinished).copyWith(
|
||||||
|
providerApiToken: hetznerKey,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +148,7 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
|
|
||||||
Future<void> onSuccess(final ServerHostingDetails serverDetails) async {
|
Future<void> onSuccess(final ServerHostingDetails serverDetails) async {
|
||||||
await repository.createDnsRecords(
|
await repository.createDnsRecords(
|
||||||
serverDetails.ip4,
|
serverDetails,
|
||||||
state.serverDomain!,
|
state.serverDomain!,
|
||||||
onCancel: onCancel,
|
onCancel: onCancel,
|
||||||
);
|
);
|
||||||
|
@ -167,6 +198,7 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
final ServerHostingDetails server = await repository.startServer(
|
final ServerHostingDetails server = await repository.startServer(
|
||||||
dataState.serverDetails!,
|
dataState.serverDetails!,
|
||||||
);
|
);
|
||||||
|
|
||||||
await repository.saveServerDetails(server);
|
await repository.saveServerDetails(server);
|
||||||
await repository.saveIsServerStarted(true);
|
await repository.saveIsServerStarted(true);
|
||||||
|
|
||||||
|
@ -292,10 +324,22 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
final bool isServerWorking = await repository.isHttpServerWorking();
|
final bool isServerWorking = await repository.isHttpServerWorking();
|
||||||
|
|
||||||
if (isServerWorking) {
|
if (isServerWorking) {
|
||||||
await repository.createDkimRecord(dataState.serverDomain!);
|
bool dkimCreated = true;
|
||||||
await repository.saveHasFinalChecked(true);
|
try {
|
||||||
|
await repository.createDkimRecord(dataState.serverDomain!);
|
||||||
emit(dataState.finish());
|
} catch (e) {
|
||||||
|
dkimCreated = false;
|
||||||
|
}
|
||||||
|
if (dkimCreated) {
|
||||||
|
await repository.saveHasFinalChecked(true);
|
||||||
|
emit(dataState.finish());
|
||||||
|
} else {
|
||||||
|
runDelayed(
|
||||||
|
finishCheckIfServerIsOkay,
|
||||||
|
const Duration(seconds: 60),
|
||||||
|
dataState,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
runDelayed(
|
runDelayed(
|
||||||
finishCheckIfServerIsOkay,
|
finishCheckIfServerIsOkay,
|
||||||
|
@ -417,11 +461,11 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RecoveryStep.serverSelection:
|
case RecoveryStep.cloudflareToken:
|
||||||
repository.deleteHetznerKey();
|
repository.deleteServerDetails();
|
||||||
emit(
|
emit(
|
||||||
dataState.copyWith(
|
dataState.copyWith(
|
||||||
currentStep: RecoveryStep.hetznerToken,
|
currentStep: RecoveryStep.serverSelection,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -464,7 +508,7 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
final ServerInstallationRecovery dataState =
|
final ServerInstallationRecovery dataState =
|
||||||
state as ServerInstallationRecovery;
|
state as ServerInstallationRecovery;
|
||||||
final List<ServerBasicInfo> servers =
|
final List<ServerBasicInfo> servers =
|
||||||
await repository.getServersOnHetznerAccount();
|
await repository.getServersOnProviderAccount();
|
||||||
final Iterable<ServerBasicInfoWithValidators> validated = servers.map(
|
final Iterable<ServerBasicInfoWithValidators> validated = servers.map(
|
||||||
(final ServerBasicInfo server) =>
|
(final ServerBasicInfo server) =>
|
||||||
ServerBasicInfoWithValidators.fromServerBasicInfo(
|
ServerBasicInfoWithValidators.fromServerBasicInfo(
|
||||||
|
@ -491,6 +535,9 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
id: server.volumeId,
|
id: server.volumeId,
|
||||||
name: 'recovered_volume',
|
name: 'recovered_volume',
|
||||||
|
sizeByte: 0,
|
||||||
|
serverId: server.id,
|
||||||
|
linuxDevice: '',
|
||||||
),
|
),
|
||||||
apiToken: dataState.serverDetails!.apiToken,
|
apiToken: dataState.serverDetails!.apiToken,
|
||||||
provider: ServerProvider.hetzner,
|
provider: ServerProvider.hetzner,
|
||||||
|
@ -561,24 +608,6 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
@override
|
@override
|
||||||
void onChange(final Change<ServerInstallationState> change) {
|
void onChange(final Change<ServerInstallationState> change) {
|
||||||
super.onChange(change);
|
super.onChange(change);
|
||||||
print('================================');
|
|
||||||
print('ServerInstallationState changed!');
|
|
||||||
print('Current type: ${change.nextState.runtimeType}');
|
|
||||||
print('Hetzner key: ${change.nextState.hetznerKey}');
|
|
||||||
print('Cloudflare key: ${change.nextState.cloudFlareKey}');
|
|
||||||
print('Domain: ${change.nextState.serverDomain}');
|
|
||||||
print('BackblazeCredential: ${change.nextState.backblazeCredential}');
|
|
||||||
if (change.nextState is ServerInstallationRecovery) {
|
|
||||||
print(
|
|
||||||
'Recovery Step: ${(change.nextState as ServerInstallationRecovery).currentStep}',
|
|
||||||
);
|
|
||||||
print(
|
|
||||||
'Recovery Capabilities: ${(change.nextState as ServerInstallationRecovery).recoveryCapabilities}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (change.nextState is TimerState) {
|
|
||||||
print('Timer: ${(change.nextState as TimerState).duration}');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearAppConfig() {
|
void clearAppConfig() {
|
||||||
|
@ -597,7 +626,7 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
await repository.deleteServerRelatedRecords();
|
await repository.deleteServerRelatedRecords();
|
||||||
emit(
|
emit(
|
||||||
ServerInstallationNotFinished(
|
ServerInstallationNotFinished(
|
||||||
hetznerKey: state.hetznerKey,
|
providerApiToken: state.providerApiToken,
|
||||||
serverDomain: state.serverDomain,
|
serverDomain: state.serverDomain,
|
||||||
cloudFlareKey: state.cloudFlareKey,
|
cloudFlareKey: state.cloudFlareKey,
|
||||||
backblazeCredential: state.backblazeCredential,
|
backblazeCredential: state.backblazeCredential,
|
||||||
|
|
|
@ -9,23 +9,24 @@ import 'package:hive/hive.dart';
|
||||||
import 'package:pub_semver/pub_semver.dart';
|
import 'package:pub_semver/pub_semver.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/config/hive_config.dart';
|
import 'package:selfprivacy/config/hive_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/hetzner.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
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/hetzner_server_info.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/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/logic/cubit/server_installation/server_installation_cubit.dart';
|
|
||||||
|
|
||||||
class IpNotFoundException implements Exception {
|
class IpNotFoundException implements Exception {
|
||||||
IpNotFoundException(this.message);
|
IpNotFoundException(this.message);
|
||||||
final String message;
|
final String message;
|
||||||
|
@ -39,9 +40,17 @@ class ServerAuthorizationException implements Exception {
|
||||||
class ServerInstallationRepository {
|
class ServerInstallationRepository {
|
||||||
Box box = Hive.box(BNames.serverInstallationBox);
|
Box box = Hive.box(BNames.serverInstallationBox);
|
||||||
Box<User> usersBox = Hive.box(BNames.usersBox);
|
Box<User> usersBox = Hive.box(BNames.usersBox);
|
||||||
|
ServerProviderApiFactory? serverProviderApiFactory =
|
||||||
|
ApiFactoryCreator.createServerProviderApiFactory(
|
||||||
|
ServerProvider.hetzner, // TODO: HARDCODE FOR NOW!!!
|
||||||
|
); // TODO: Remove when provider selection is implemented.
|
||||||
|
DnsProviderApiFactory? dnsProviderApiFactory =
|
||||||
|
ApiFactoryCreator.createDnsProviderApiFactory(
|
||||||
|
DnsProvider.cloudflare, // TODO: HARDCODE FOR NOW!!!
|
||||||
|
);
|
||||||
|
|
||||||
Future<ServerInstallationState> load() async {
|
Future<ServerInstallationState> load() async {
|
||||||
final String? hetznerToken = getIt<ApiConfigModel>().hetznerKey;
|
final String? providerApiToken = getIt<ApiConfigModel>().hetznerKey;
|
||||||
final String? cloudflareToken = getIt<ApiConfigModel>().cloudFlareKey;
|
final String? cloudflareToken = getIt<ApiConfigModel>().cloudFlareKey;
|
||||||
final ServerDomain? serverDomain = getIt<ApiConfigModel>().serverDomain;
|
final ServerDomain? serverDomain = getIt<ApiConfigModel>().serverDomain;
|
||||||
final BackblazeCredential? backblazeCredential =
|
final BackblazeCredential? backblazeCredential =
|
||||||
|
@ -49,9 +58,23 @@ class ServerInstallationRepository {
|
||||||
final ServerHostingDetails? serverDetails =
|
final ServerHostingDetails? serverDetails =
|
||||||
getIt<ApiConfigModel>().serverDetails;
|
getIt<ApiConfigModel>().serverDetails;
|
||||||
|
|
||||||
|
if (serverDetails != null &&
|
||||||
|
serverDetails.provider != ServerProvider.unknown) {
|
||||||
|
serverProviderApiFactory =
|
||||||
|
ApiFactoryCreator.createServerProviderApiFactory(
|
||||||
|
serverDetails.provider,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverDomain != null && serverDomain.provider != DnsProvider.unknown) {
|
||||||
|
dnsProviderApiFactory = ApiFactoryCreator.createDnsProviderApiFactory(
|
||||||
|
serverDomain.provider,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (box.get(BNames.hasFinalChecked, defaultValue: false)) {
|
if (box.get(BNames.hasFinalChecked, defaultValue: false)) {
|
||||||
return ServerInstallationFinished(
|
return ServerInstallationFinished(
|
||||||
hetznerKey: hetznerToken!,
|
providerApiToken: providerApiToken!,
|
||||||
cloudFlareKey: cloudflareToken!,
|
cloudFlareKey: cloudflareToken!,
|
||||||
serverDomain: serverDomain!,
|
serverDomain: serverDomain!,
|
||||||
backblazeCredential: backblazeCredential!,
|
backblazeCredential: backblazeCredential!,
|
||||||
|
@ -68,14 +91,14 @@ class ServerInstallationRepository {
|
||||||
if (box.get(BNames.isRecoveringServer, defaultValue: false) &&
|
if (box.get(BNames.isRecoveringServer, defaultValue: false) &&
|
||||||
serverDomain != null) {
|
serverDomain != null) {
|
||||||
return ServerInstallationRecovery(
|
return ServerInstallationRecovery(
|
||||||
hetznerKey: hetznerToken,
|
providerApiToken: providerApiToken,
|
||||||
cloudFlareKey: cloudflareToken,
|
cloudFlareKey: cloudflareToken,
|
||||||
serverDomain: serverDomain,
|
serverDomain: serverDomain,
|
||||||
backblazeCredential: backblazeCredential,
|
backblazeCredential: backblazeCredential,
|
||||||
serverDetails: serverDetails,
|
serverDetails: serverDetails,
|
||||||
rootUser: box.get(BNames.rootUser),
|
rootUser: box.get(BNames.rootUser),
|
||||||
currentStep: _getCurrentRecoveryStep(
|
currentStep: _getCurrentRecoveryStep(
|
||||||
hetznerToken,
|
providerApiToken,
|
||||||
cloudflareToken,
|
cloudflareToken,
|
||||||
serverDomain,
|
serverDomain,
|
||||||
serverDetails,
|
serverDetails,
|
||||||
|
@ -85,7 +108,7 @@ class ServerInstallationRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
return ServerInstallationNotFinished(
|
return ServerInstallationNotFinished(
|
||||||
hetznerKey: hetznerToken,
|
providerApiToken: providerApiToken,
|
||||||
cloudFlareKey: cloudflareToken,
|
cloudFlareKey: cloudflareToken,
|
||||||
serverDomain: serverDomain,
|
serverDomain: serverDomain,
|
||||||
backblazeCredential: backblazeCredential,
|
backblazeCredential: backblazeCredential,
|
||||||
|
@ -130,24 +153,24 @@ class ServerInstallationRepository {
|
||||||
Future<ServerHostingDetails> startServer(
|
Future<ServerHostingDetails> startServer(
|
||||||
final ServerHostingDetails hetznerServer,
|
final ServerHostingDetails hetznerServer,
|
||||||
) async {
|
) async {
|
||||||
final HetznerApi hetznerApi = HetznerApi();
|
ServerHostingDetails serverDetails;
|
||||||
final ServerHostingDetails serverDetails = await hetznerApi.powerOn();
|
|
||||||
|
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||||
|
serverDetails = await api.powerOn();
|
||||||
|
|
||||||
return serverDetails;
|
return serverDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getDomainId(final String token, final String domain) async {
|
Future<String?> getDomainId(final String token, final String domain) async {
|
||||||
final CloudflareApi cloudflareApi = CloudflareApi(
|
final DnsProviderApi dnsProviderApi = dnsProviderApiFactory!.getDnsProvider(
|
||||||
isWithToken: false,
|
settings: DnsProviderApiSettings(
|
||||||
customToken: token,
|
isWithToken: false,
|
||||||
|
customToken: token,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
final String? domainId = await dnsProviderApi.getZoneId(domain);
|
||||||
final String domainId = await cloudflareApi.getZoneId(domain);
|
return domainId;
|
||||||
return domainId;
|
|
||||||
} on DomainNotFoundException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, bool>> isDnsAddressesMatch(
|
Future<Map<String, bool>> isDnsAddressesMatch(
|
||||||
|
@ -208,18 +231,14 @@ class ServerInstallationRepository {
|
||||||
required final Future<void> Function(ServerHostingDetails serverDetails)
|
required final Future<void> Function(ServerHostingDetails serverDetails)
|
||||||
onSuccess,
|
onSuccess,
|
||||||
}) async {
|
}) async {
|
||||||
final HetznerApi hetznerApi = HetznerApi();
|
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||||
late ServerVolume dataBase;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dataBase = await hetznerApi.createVolume();
|
final ServerHostingDetails? serverDetails = await api.createServer(
|
||||||
|
dnsApiToken: cloudFlareKey,
|
||||||
final ServerHostingDetails? serverDetails = await hetznerApi.createServer(
|
|
||||||
cloudFlareKey: cloudFlareKey,
|
|
||||||
rootUser: rootUser,
|
rootUser: rootUser,
|
||||||
domainName: domainName,
|
domainName: domainName,
|
||||||
dataBase: dataBase,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (serverDetails == null) {
|
if (serverDetails == null) {
|
||||||
print('Server is not initialized!');
|
print('Server is not initialized!');
|
||||||
return;
|
return;
|
||||||
|
@ -238,17 +257,58 @@ class ServerInstallationRepository {
|
||||||
text: 'basis.delete'.tr(),
|
text: 'basis.delete'.tr(),
|
||||||
isRed: true,
|
isRed: true,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await hetznerApi.deleteSelfprivacyServerAndAllVolumes(
|
await api.deleteServer(
|
||||||
domainName: domainName,
|
domainName: domainName,
|
||||||
);
|
);
|
||||||
|
|
||||||
final ServerHostingDetails? serverDetails =
|
ServerHostingDetails? serverDetails;
|
||||||
await hetznerApi.createServer(
|
try {
|
||||||
cloudFlareKey: cloudFlareKey,
|
serverDetails = await api.createServer(
|
||||||
rootUser: rootUser,
|
dnsApiToken: cloudFlareKey,
|
||||||
domainName: domainName,
|
rootUser: rootUser,
|
||||||
dataBase: dataBase,
|
domainName: domainName,
|
||||||
);
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverDetails == null) {
|
||||||
|
print('Server is not initialized!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await saveServerDetails(serverDetails);
|
||||||
|
onSuccess(serverDetails);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ActionButton(
|
||||||
|
text: 'basis.cancel'.tr(),
|
||||||
|
onPressed: onCancel,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (e.response!.data['error']['code'] == 'resource_unavailable') {
|
||||||
|
final NavigationService nav = getIt.get<NavigationService>();
|
||||||
|
nav.showPopUpDialog(
|
||||||
|
BrandAlert(
|
||||||
|
title: 'modals.1_1'.tr(),
|
||||||
|
contentText: 'modals.2_2'.tr(),
|
||||||
|
actions: [
|
||||||
|
ActionButton(
|
||||||
|
text: 'modals.7'.tr(),
|
||||||
|
isRed: true,
|
||||||
|
onPressed: () async {
|
||||||
|
ServerHostingDetails? serverDetails;
|
||||||
|
try {
|
||||||
|
serverDetails = await api.createServer(
|
||||||
|
dnsApiToken: cloudFlareKey,
|
||||||
|
rootUser: rootUser,
|
||||||
|
domainName: domainName,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
if (serverDetails == null) {
|
if (serverDetails == null) {
|
||||||
print('Server is not initialized!');
|
print('Server is not initialized!');
|
||||||
return;
|
return;
|
||||||
|
@ -268,25 +328,27 @@ class ServerInstallationRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createDnsRecords(
|
Future<bool> createDnsRecords(
|
||||||
final String ip4,
|
final ServerHostingDetails serverDetails,
|
||||||
final ServerDomain cloudFlareDomain, {
|
final ServerDomain domain, {
|
||||||
required final void Function() onCancel,
|
required final void Function() onCancel,
|
||||||
}) async {
|
}) async {
|
||||||
final CloudflareApi cloudflareApi = CloudflareApi();
|
final DnsProviderApi dnsProviderApi =
|
||||||
|
dnsProviderApiFactory!.getDnsProvider();
|
||||||
|
final ServerProviderApi serverApi =
|
||||||
|
serverProviderApiFactory!.getServerProvider();
|
||||||
|
|
||||||
await cloudflareApi.removeSimilarRecords(
|
await dnsProviderApi.removeSimilarRecords(
|
||||||
ip4: ip4,
|
ip4: serverDetails.ip4,
|
||||||
cloudFlareDomain: cloudFlareDomain,
|
domain: domain,
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await cloudflareApi.createMultipleDnsRecords(
|
await dnsProviderApi.createMultipleDnsRecords(
|
||||||
ip4: ip4,
|
ip4: serverDetails.ip4,
|
||||||
cloudFlareDomain: cloudFlareDomain,
|
domain: domain,
|
||||||
);
|
);
|
||||||
} on DioError catch (e) {
|
} on DioError catch (e) {
|
||||||
final HetznerApi hetznerApi = HetznerApi();
|
|
||||||
final NavigationService nav = getIt.get<NavigationService>();
|
final NavigationService nav = getIt.get<NavigationService>();
|
||||||
nav.showPopUpDialog(
|
nav.showPopUpDialog(
|
||||||
BrandAlert(
|
BrandAlert(
|
||||||
|
@ -299,8 +361,8 @@ class ServerInstallationRepository {
|
||||||
text: 'basis.delete'.tr(),
|
text: 'basis.delete'.tr(),
|
||||||
isRed: true,
|
isRed: true,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await hetznerApi.deleteSelfprivacyServerAndAllVolumes(
|
await serverApi.deleteServer(
|
||||||
domainName: cloudFlareDomain.domainName,
|
domainName: domain.domainName,
|
||||||
);
|
);
|
||||||
|
|
||||||
onCancel();
|
onCancel();
|
||||||
|
@ -313,42 +375,46 @@ class ServerInstallationRepository {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await HetznerApi().createReverseDns(
|
await serverApi.createReverseDns(
|
||||||
ip4: ip4,
|
serverDetails: serverDetails,
|
||||||
domainName: cloudFlareDomain.domainName,
|
domain: domain,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createDkimRecord(final ServerDomain cloudFlareDomain) async {
|
Future<void> createDkimRecord(final ServerDomain cloudFlareDomain) async {
|
||||||
final CloudflareApi cloudflareApi = CloudflareApi();
|
final DnsProviderApi dnsProviderApi =
|
||||||
|
dnsProviderApiFactory!.getDnsProvider();
|
||||||
final ServerApi api = ServerApi();
|
final ServerApi api = ServerApi();
|
||||||
|
|
||||||
final String? dkimRecordString = await api.getDkim();
|
String dkimRecordString = '';
|
||||||
|
try {
|
||||||
|
dkimRecordString = (await api.getDkim())!;
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
|
||||||
await cloudflareApi.setDkim(dkimRecordString ?? '', cloudFlareDomain);
|
await dnsProviderApi.setDkim(dkimRecordString, cloudFlareDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isHttpServerWorking() async {
|
Future<bool> isHttpServerWorking() async {
|
||||||
final ServerApi api = ServerApi();
|
final ServerApi api = ServerApi();
|
||||||
final bool isHttpServerWorking = await api.isHttpServerWorking();
|
return api.isHttpServerWorking();
|
||||||
try {
|
|
||||||
await api.getDkim();
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isHttpServerWorking;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ServerHostingDetails> restart() async {
|
Future<ServerHostingDetails> restart() async {
|
||||||
final HetznerApi hetznerApi = HetznerApi();
|
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||||
return hetznerApi.reset();
|
return api.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ServerHostingDetails> powerOn() async {
|
Future<ServerHostingDetails> powerOn() async {
|
||||||
final HetznerApi hetznerApi = HetznerApi();
|
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||||
return hetznerApi.powerOn();
|
return api.powerOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ServerRecoveryCapabilities> getRecoveryCapabilities(
|
Future<ServerRecoveryCapabilities> getRecoveryCapabilities(
|
||||||
|
@ -439,6 +505,9 @@ class ServerInstallationRepository {
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
id: 0,
|
id: 0,
|
||||||
name: '',
|
name: '',
|
||||||
|
sizeByte: 0,
|
||||||
|
serverId: 0,
|
||||||
|
linuxDevice: '',
|
||||||
),
|
),
|
||||||
provider: ServerProvider.unknown,
|
provider: ServerProvider.unknown,
|
||||||
id: 0,
|
id: 0,
|
||||||
|
@ -473,6 +542,9 @@ class ServerInstallationRepository {
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
id: 0,
|
id: 0,
|
||||||
name: '',
|
name: '',
|
||||||
|
sizeByte: 0,
|
||||||
|
serverId: 0,
|
||||||
|
linuxDevice: '',
|
||||||
),
|
),
|
||||||
provider: ServerProvider.unknown,
|
provider: ServerProvider.unknown,
|
||||||
id: 0,
|
id: 0,
|
||||||
|
@ -507,6 +579,9 @@ class ServerInstallationRepository {
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
id: 0,
|
id: 0,
|
||||||
name: '',
|
name: '',
|
||||||
|
serverId: 0,
|
||||||
|
sizeByte: 0,
|
||||||
|
linuxDevice: '',
|
||||||
),
|
),
|
||||||
provider: ServerProvider.unknown,
|
provider: ServerProvider.unknown,
|
||||||
id: 0,
|
id: 0,
|
||||||
|
@ -532,6 +607,9 @@ class ServerInstallationRepository {
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
id: 0,
|
id: 0,
|
||||||
name: '',
|
name: '',
|
||||||
|
sizeByte: 0,
|
||||||
|
serverId: 0,
|
||||||
|
linuxDevice: '',
|
||||||
),
|
),
|
||||||
provider: ServerProvider.unknown,
|
provider: ServerProvider.unknown,
|
||||||
id: 0,
|
id: 0,
|
||||||
|
@ -550,6 +628,7 @@ class ServerInstallationRepository {
|
||||||
final ServerApi serverApi = ServerApi();
|
final ServerApi serverApi = ServerApi();
|
||||||
const User fallbackUser = User(
|
const User fallbackUser = User(
|
||||||
isFoundOnServer: false,
|
isFoundOnServer: false,
|
||||||
|
type: UserType.primary,
|
||||||
note: "Couldn't find main user on server, API is outdated",
|
note: "Couldn't find main user on server, API is outdated",
|
||||||
login: 'UNKNOWN',
|
login: 'UNKNOWN',
|
||||||
sshKeys: [],
|
sshKeys: [],
|
||||||
|
@ -569,27 +648,16 @@ class ServerInstallationRepository {
|
||||||
return User(
|
return User(
|
||||||
isFoundOnServer: true,
|
isFoundOnServer: true,
|
||||||
login: users.data[0],
|
login: users.data[0],
|
||||||
|
type: UserType.primary,
|
||||||
);
|
);
|
||||||
} on FormatException {
|
} on FormatException {
|
||||||
return fallbackUser;
|
return fallbackUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ServerBasicInfo>> getServersOnHetznerAccount() async {
|
Future<List<ServerBasicInfo>> getServersOnProviderAccount() async {
|
||||||
final HetznerApi hetznerApi = HetznerApi();
|
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||||
final List<HetznerServerInfo> servers = await hetznerApi.getServers();
|
return api.getServers();
|
||||||
return servers
|
|
||||||
.map(
|
|
||||||
(final HetznerServerInfo server) => ServerBasicInfo(
|
|
||||||
id: server.id,
|
|
||||||
name: server.name,
|
|
||||||
ip: server.publicNet.ipv4.ip,
|
|
||||||
reverseDns: server.publicNet.ipv4.reverseDns,
|
|
||||||
created: server.created,
|
|
||||||
volumeId: server.volumes.isNotEmpty ? server.volumes[0] : 0,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveServerDetails(
|
Future<void> saveServerDetails(
|
||||||
|
@ -598,6 +666,11 @@ class ServerInstallationRepository {
|
||||||
await getIt<ApiConfigModel>().storeServerDetails(serverDetails);
|
await getIt<ApiConfigModel>().storeServerDetails(serverDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteServerDetails() async {
|
||||||
|
await box.delete(BNames.serverDetails);
|
||||||
|
getIt<ApiConfigModel>().init();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> saveHetznerKey(final String key) async {
|
Future<void> saveHetznerKey(final String key) async {
|
||||||
print('saved');
|
print('saved');
|
||||||
await getIt<ApiConfigModel>().storeHetznerKey(key);
|
await getIt<ApiConfigModel>().storeHetznerKey(key);
|
||||||
|
@ -614,10 +687,20 @@ class ServerInstallationRepository {
|
||||||
await getIt<ApiConfigModel>().storeBackblazeCredential(backblazeCredential);
|
await getIt<ApiConfigModel>().storeBackblazeCredential(backblazeCredential);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteBackblazeKey() async {
|
||||||
|
await box.delete(BNames.backblazeCredential);
|
||||||
|
getIt<ApiConfigModel>().init();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> saveCloudFlareKey(final String key) async {
|
Future<void> saveCloudFlareKey(final String key) async {
|
||||||
await getIt<ApiConfigModel>().storeCloudFlareKey(key);
|
await getIt<ApiConfigModel>().storeCloudFlareKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteCloudFlareKey() async {
|
||||||
|
await box.delete(BNames.cloudFlareKey);
|
||||||
|
getIt<ApiConfigModel>().init();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> saveDomain(final ServerDomain serverDomain) async {
|
Future<void> saveDomain(final ServerDomain serverDomain) async {
|
||||||
await getIt<ApiConfigModel>().storeServerDomain(serverDomain);
|
await getIt<ApiConfigModel>().storeServerDomain(serverDomain);
|
||||||
}
|
}
|
||||||
|
@ -652,10 +735,11 @@ class ServerInstallationRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteServer(final ServerDomain serverDomain) async {
|
Future<void> deleteServer(final ServerDomain serverDomain) async {
|
||||||
final HetznerApi hetznerApi = HetznerApi();
|
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||||
final CloudflareApi cloudFlare = CloudflareApi();
|
final DnsProviderApi dnsProviderApi =
|
||||||
|
dnsProviderApiFactory!.getDnsProvider();
|
||||||
|
|
||||||
await hetznerApi.deleteSelfprivacyServerAndAllVolumes(
|
await api.deleteServer(
|
||||||
domainName: serverDomain.domainName,
|
domainName: serverDomain.domainName,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -666,7 +750,7 @@ class ServerInstallationRepository {
|
||||||
await box.put(BNames.isLoading, false);
|
await box.put(BNames.isLoading, false);
|
||||||
await box.put(BNames.serverDetails, null);
|
await box.put(BNames.serverDetails, null);
|
||||||
|
|
||||||
await cloudFlare.removeSimilarRecords(cloudFlareDomain: serverDomain);
|
await dnsProviderApi.removeSimilarRecords(domain: serverDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteServerRelatedRecords() async {
|
Future<void> deleteServerRelatedRecords() async {
|
||||||
|
|
|
@ -2,7 +2,7 @@ part of '../server_installation/server_installation_cubit.dart';
|
||||||
|
|
||||||
abstract class ServerInstallationState extends Equatable {
|
abstract class ServerInstallationState extends Equatable {
|
||||||
const ServerInstallationState({
|
const ServerInstallationState({
|
||||||
required this.hetznerKey,
|
required this.providerApiToken,
|
||||||
required this.cloudFlareKey,
|
required this.cloudFlareKey,
|
||||||
required this.backblazeCredential,
|
required this.backblazeCredential,
|
||||||
required this.serverDomain,
|
required this.serverDomain,
|
||||||
|
@ -15,7 +15,7 @@ abstract class ServerInstallationState extends Equatable {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [
|
List<Object?> get props => [
|
||||||
hetznerKey,
|
providerApiToken,
|
||||||
cloudFlareKey,
|
cloudFlareKey,
|
||||||
backblazeCredential,
|
backblazeCredential,
|
||||||
serverDomain,
|
serverDomain,
|
||||||
|
@ -25,7 +25,7 @@ abstract class ServerInstallationState extends Equatable {
|
||||||
isServerResetedFirstTime,
|
isServerResetedFirstTime,
|
||||||
];
|
];
|
||||||
|
|
||||||
final String? hetznerKey;
|
final String? providerApiToken;
|
||||||
final String? cloudFlareKey;
|
final String? cloudFlareKey;
|
||||||
final BackblazeCredential? backblazeCredential;
|
final BackblazeCredential? backblazeCredential;
|
||||||
final ServerDomain? serverDomain;
|
final ServerDomain? serverDomain;
|
||||||
|
@ -35,11 +35,11 @@ abstract class ServerInstallationState extends Equatable {
|
||||||
final bool isServerResetedFirstTime;
|
final bool isServerResetedFirstTime;
|
||||||
final bool isServerResetedSecondTime;
|
final bool isServerResetedSecondTime;
|
||||||
|
|
||||||
bool get isHetznerFilled => hetznerKey != null;
|
bool get isServerProviderFilled => providerApiToken != null;
|
||||||
bool get isCloudFlareFilled => cloudFlareKey != null;
|
bool get isDnsProviderFilled => cloudFlareKey != null;
|
||||||
bool get isBackblazeFilled => backblazeCredential != null;
|
bool get isBackupsProviderFilled => backblazeCredential != null;
|
||||||
bool get isDomainFilled => serverDomain != null;
|
bool get isDomainSelected => serverDomain != null;
|
||||||
bool get isUserFilled => rootUser != null;
|
bool get isPrimaryUserFilled => rootUser != null;
|
||||||
bool get isServerCreated => serverDetails != null;
|
bool get isServerCreated => serverDetails != null;
|
||||||
|
|
||||||
bool get isFullyInitilized => _fulfilementList.every((final el) => el!);
|
bool get isFullyInitilized => _fulfilementList.every((final el) => el!);
|
||||||
|
@ -58,11 +58,11 @@ abstract class ServerInstallationState extends Equatable {
|
||||||
|
|
||||||
List<bool?> get _fulfilementList {
|
List<bool?> get _fulfilementList {
|
||||||
final List<bool> res = [
|
final List<bool> res = [
|
||||||
isHetznerFilled,
|
isServerProviderFilled,
|
||||||
isCloudFlareFilled,
|
isDnsProviderFilled,
|
||||||
isBackblazeFilled,
|
isBackupsProviderFilled,
|
||||||
isDomainFilled,
|
isDomainSelected,
|
||||||
isUserFilled,
|
isPrimaryUserFilled,
|
||||||
isServerCreated,
|
isServerCreated,
|
||||||
isServerStarted,
|
isServerStarted,
|
||||||
isServerResetedFirstTime,
|
isServerResetedFirstTime,
|
||||||
|
@ -80,7 +80,7 @@ class TimerState extends ServerInstallationNotFinished {
|
||||||
this.timerStart,
|
this.timerStart,
|
||||||
this.duration,
|
this.duration,
|
||||||
}) : super(
|
}) : super(
|
||||||
hetznerKey: dataState.hetznerKey,
|
providerApiToken: dataState.providerApiToken,
|
||||||
cloudFlareKey: dataState.cloudFlareKey,
|
cloudFlareKey: dataState.cloudFlareKey,
|
||||||
backblazeCredential: dataState.backblazeCredential,
|
backblazeCredential: dataState.backblazeCredential,
|
||||||
serverDomain: dataState.serverDomain,
|
serverDomain: dataState.serverDomain,
|
||||||
|
@ -124,7 +124,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
||||||
required final super.isServerResetedSecondTime,
|
required final super.isServerResetedSecondTime,
|
||||||
required final this.isLoading,
|
required final this.isLoading,
|
||||||
required this.dnsMatches,
|
required this.dnsMatches,
|
||||||
final super.hetznerKey,
|
final super.providerApiToken,
|
||||||
final super.cloudFlareKey,
|
final super.cloudFlareKey,
|
||||||
final super.backblazeCredential,
|
final super.backblazeCredential,
|
||||||
final super.serverDomain,
|
final super.serverDomain,
|
||||||
|
@ -136,7 +136,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [
|
List<Object?> get props => [
|
||||||
hetznerKey,
|
providerApiToken,
|
||||||
cloudFlareKey,
|
cloudFlareKey,
|
||||||
backblazeCredential,
|
backblazeCredential,
|
||||||
serverDomain,
|
serverDomain,
|
||||||
|
@ -149,7 +149,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
||||||
];
|
];
|
||||||
|
|
||||||
ServerInstallationNotFinished copyWith({
|
ServerInstallationNotFinished copyWith({
|
||||||
final String? hetznerKey,
|
final String? providerApiToken,
|
||||||
final String? cloudFlareKey,
|
final String? cloudFlareKey,
|
||||||
final BackblazeCredential? backblazeCredential,
|
final BackblazeCredential? backblazeCredential,
|
||||||
final ServerDomain? serverDomain,
|
final ServerDomain? serverDomain,
|
||||||
|
@ -162,7 +162,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
||||||
final Map<String, bool>? dnsMatches,
|
final Map<String, bool>? dnsMatches,
|
||||||
}) =>
|
}) =>
|
||||||
ServerInstallationNotFinished(
|
ServerInstallationNotFinished(
|
||||||
hetznerKey: hetznerKey ?? this.hetznerKey,
|
providerApiToken: providerApiToken ?? this.providerApiToken,
|
||||||
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
|
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
|
||||||
backblazeCredential: backblazeCredential ?? this.backblazeCredential,
|
backblazeCredential: backblazeCredential ?? this.backblazeCredential,
|
||||||
serverDomain: serverDomain ?? this.serverDomain,
|
serverDomain: serverDomain ?? this.serverDomain,
|
||||||
|
@ -178,7 +178,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
||||||
);
|
);
|
||||||
|
|
||||||
ServerInstallationFinished finish() => ServerInstallationFinished(
|
ServerInstallationFinished finish() => ServerInstallationFinished(
|
||||||
hetznerKey: hetznerKey!,
|
providerApiToken: providerApiToken!,
|
||||||
cloudFlareKey: cloudFlareKey!,
|
cloudFlareKey: cloudFlareKey!,
|
||||||
backblazeCredential: backblazeCredential!,
|
backblazeCredential: backblazeCredential!,
|
||||||
serverDomain: serverDomain!,
|
serverDomain: serverDomain!,
|
||||||
|
@ -193,7 +193,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
||||||
class ServerInstallationEmpty extends ServerInstallationNotFinished {
|
class ServerInstallationEmpty extends ServerInstallationNotFinished {
|
||||||
const ServerInstallationEmpty()
|
const ServerInstallationEmpty()
|
||||||
: super(
|
: super(
|
||||||
hetznerKey: null,
|
providerApiToken: null,
|
||||||
cloudFlareKey: null,
|
cloudFlareKey: null,
|
||||||
backblazeCredential: null,
|
backblazeCredential: null,
|
||||||
serverDomain: null,
|
serverDomain: null,
|
||||||
|
@ -209,7 +209,7 @@ class ServerInstallationEmpty extends ServerInstallationNotFinished {
|
||||||
|
|
||||||
class ServerInstallationFinished extends ServerInstallationState {
|
class ServerInstallationFinished extends ServerInstallationState {
|
||||||
const ServerInstallationFinished({
|
const ServerInstallationFinished({
|
||||||
required final String super.hetznerKey,
|
required final String super.providerApiToken,
|
||||||
required final String super.cloudFlareKey,
|
required final String super.cloudFlareKey,
|
||||||
required final BackblazeCredential super.backblazeCredential,
|
required final BackblazeCredential super.backblazeCredential,
|
||||||
required final ServerDomain super.serverDomain,
|
required final ServerDomain super.serverDomain,
|
||||||
|
@ -222,7 +222,7 @@ class ServerInstallationFinished extends ServerInstallationState {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [
|
List<Object?> get props => [
|
||||||
hetznerKey,
|
providerApiToken,
|
||||||
cloudFlareKey,
|
cloudFlareKey,
|
||||||
backblazeCredential,
|
backblazeCredential,
|
||||||
serverDomain,
|
serverDomain,
|
||||||
|
@ -260,7 +260,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
||||||
const ServerInstallationRecovery({
|
const ServerInstallationRecovery({
|
||||||
required this.currentStep,
|
required this.currentStep,
|
||||||
required this.recoveryCapabilities,
|
required this.recoveryCapabilities,
|
||||||
final super.hetznerKey,
|
final super.providerApiToken,
|
||||||
final super.cloudFlareKey,
|
final super.cloudFlareKey,
|
||||||
final super.backblazeCredential,
|
final super.backblazeCredential,
|
||||||
final super.serverDomain,
|
final super.serverDomain,
|
||||||
|
@ -276,7 +276,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [
|
List<Object?> get props => [
|
||||||
hetznerKey,
|
providerApiToken,
|
||||||
cloudFlareKey,
|
cloudFlareKey,
|
||||||
backblazeCredential,
|
backblazeCredential,
|
||||||
serverDomain,
|
serverDomain,
|
||||||
|
@ -288,7 +288,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
||||||
];
|
];
|
||||||
|
|
||||||
ServerInstallationRecovery copyWith({
|
ServerInstallationRecovery copyWith({
|
||||||
final String? hetznerKey,
|
final String? providerApiToken,
|
||||||
final String? cloudFlareKey,
|
final String? cloudFlareKey,
|
||||||
final BackblazeCredential? backblazeCredential,
|
final BackblazeCredential? backblazeCredential,
|
||||||
final ServerDomain? serverDomain,
|
final ServerDomain? serverDomain,
|
||||||
|
@ -298,7 +298,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
||||||
final ServerRecoveryCapabilities? recoveryCapabilities,
|
final ServerRecoveryCapabilities? recoveryCapabilities,
|
||||||
}) =>
|
}) =>
|
||||||
ServerInstallationRecovery(
|
ServerInstallationRecovery(
|
||||||
hetznerKey: hetznerKey ?? this.hetznerKey,
|
providerApiToken: providerApiToken ?? this.providerApiToken,
|
||||||
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
|
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
|
||||||
backblazeCredential: backblazeCredential ?? this.backblazeCredential,
|
backblazeCredential: backblazeCredential ?? this.backblazeCredential,
|
||||||
serverDomain: serverDomain ?? this.serverDomain,
|
serverDomain: serverDomain ?? this.serverDomain,
|
||||||
|
@ -309,7 +309,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
||||||
);
|
);
|
||||||
|
|
||||||
ServerInstallationFinished finish() => ServerInstallationFinished(
|
ServerInstallationFinished finish() => ServerInstallationFinished(
|
||||||
hetznerKey: hetznerKey!,
|
providerApiToken: providerApiToken!,
|
||||||
cloudFlareKey: cloudFlareKey!,
|
cloudFlareKey: cloudFlareKey!,
|
||||||
backblazeCredential: backblazeCredential!,
|
backblazeCredential: backblazeCredential!,
|
||||||
serverDomain: serverDomain!,
|
serverDomain: serverDomain!,
|
||||||
|
|
117
lib/logic/cubit/server_jobs/server_jobs_cubit.dart
Normal file
117
lib/logic/cubit/server_jobs/server_jobs_cubit.dart
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:selfprivacy/config/get_it_config.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/models/json/server_job.dart';
|
||||||
|
|
||||||
|
export 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
part 'server_jobs_state.dart';
|
||||||
|
|
||||||
|
class ServerJobsCubit
|
||||||
|
extends ServerInstallationDependendCubit<ServerJobsState> {
|
||||||
|
ServerJobsCubit(final ServerInstallationCubit serverInstallationCubit)
|
||||||
|
: super(
|
||||||
|
serverInstallationCubit,
|
||||||
|
ServerJobsState(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Timer? timer;
|
||||||
|
final ServerApi api = ServerApi();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void clear() async {
|
||||||
|
emit(
|
||||||
|
ServerJobsState(),
|
||||||
|
);
|
||||||
|
if (timer != null && timer!.isActive) {
|
||||||
|
timer!.cancel();
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void load() async {
|
||||||
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
|
final List<ServerJob> jobs = await api.getServerJobs();
|
||||||
|
emit(
|
||||||
|
ServerJobsState(
|
||||||
|
serverJobList: jobs,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
timer = Timer(const Duration(seconds: 5), () => reload(useTimer: true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> migrateToBinds(final Map<String, String> serviceToDisk) async {
|
||||||
|
final result = await api.migrateToBinds(serviceToDisk);
|
||||||
|
if (!result.success || result.jobUid == null) {
|
||||||
|
getIt<NavigationService>().showSnackBar(result.message!);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(
|
||||||
|
ServerJobsState(
|
||||||
|
migrationJobUid: result.jobUid,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerJob? getServerJobByUid(final String uid) {
|
||||||
|
ServerJob? job;
|
||||||
|
|
||||||
|
try {
|
||||||
|
job = state.serverJobList.firstWhere(
|
||||||
|
(final ServerJob job) => job.uid == uid,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> removeServerJob(final String uid) async {
|
||||||
|
final result = await api.removeApiJob(uid);
|
||||||
|
if (!result.success) {
|
||||||
|
getIt<NavigationService>().showSnackBar(result.message!);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(
|
||||||
|
ServerJobsState(
|
||||||
|
serverJobList: [
|
||||||
|
for (final ServerJob job in state.serverJobList)
|
||||||
|
if (job.uid != uid) job
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
print('removed job $uid');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> removeAllFinishedJobs() async {
|
||||||
|
final List<ServerJob> finishedJobs = state.serverJobList
|
||||||
|
.where(
|
||||||
|
(final ServerJob job) =>
|
||||||
|
job.status == JobStatusEnum.finished ||
|
||||||
|
job.status == JobStatusEnum.error,
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
for (final ServerJob job in finishedJobs) {
|
||||||
|
await removeServerJob(job.uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> reload({final bool useTimer = false}) async {
|
||||||
|
final List<ServerJob> jobs = await api.getServerJobs();
|
||||||
|
emit(
|
||||||
|
ServerJobsState(
|
||||||
|
serverJobList: jobs,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (useTimer) {
|
||||||
|
timer = Timer(const Duration(seconds: 5), () => reload(useTimer: true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
lib/logic/cubit/server_jobs/server_jobs_state.dart
Normal file
37
lib/logic/cubit/server_jobs/server_jobs_state.dart
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
part of 'server_jobs_cubit.dart';
|
||||||
|
|
||||||
|
class ServerJobsState extends ServerInstallationDependendState {
|
||||||
|
ServerJobsState({
|
||||||
|
final serverJobList = const <ServerJob>[],
|
||||||
|
this.migrationJobUid,
|
||||||
|
}) {
|
||||||
|
_serverJobList = serverJobList;
|
||||||
|
}
|
||||||
|
|
||||||
|
late final List<ServerJob> _serverJobList;
|
||||||
|
final String? migrationJobUid;
|
||||||
|
|
||||||
|
List<ServerJob> get serverJobList {
|
||||||
|
final List<ServerJob> list = _serverJobList;
|
||||||
|
list.sort((final a, final b) => b.createdAt.compareTo(a.createdAt));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get hasRemovableJobs => serverJobList.any(
|
||||||
|
(final job) =>
|
||||||
|
job.status == JobStatusEnum.finished ||
|
||||||
|
job.status == JobStatusEnum.error,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [migrationJobUid, _serverJobList];
|
||||||
|
|
||||||
|
ServerJobsState copyWith({
|
||||||
|
final List<ServerJob>? serverJobList,
|
||||||
|
final String? migrationJobUid,
|
||||||
|
}) =>
|
||||||
|
ServerJobsState(
|
||||||
|
serverJobList: serverJobList ?? _serverJobList,
|
||||||
|
migrationJobUid: migrationJobUid ?? this.migrationJobUid,
|
||||||
|
);
|
||||||
|
}
|
78
lib/logic/cubit/server_volumes/server_volume_cubit.dart
Normal file
78
lib/logic/cubit/server_volumes/server_volume_cubit.dart
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/disk_status.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
||||||
|
|
||||||
|
part 'server_volume_state.dart';
|
||||||
|
|
||||||
|
class ApiServerVolumeCubit
|
||||||
|
extends ServerInstallationDependendCubit<ApiServerVolumeState> {
|
||||||
|
ApiServerVolumeCubit(
|
||||||
|
final ServerInstallationCubit serverInstallationCubit,
|
||||||
|
this.providerVolumeCubit,
|
||||||
|
) : super(serverInstallationCubit, ApiServerVolumeState.initial()) {
|
||||||
|
_providerVolumeSubscription =
|
||||||
|
providerVolumeCubit.stream.listen(checkProviderVolumes);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ServerApi serverApi = ServerApi();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> load() async {
|
||||||
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
late StreamSubscription<ApiProviderVolumeState> _providerVolumeSubscription;
|
||||||
|
final ApiProviderVolumeCubit providerVolumeCubit;
|
||||||
|
|
||||||
|
void checkProviderVolumes(final ApiProviderVolumeState state) {
|
||||||
|
emit(
|
||||||
|
ApiServerVolumeState(
|
||||||
|
this.state._volumes,
|
||||||
|
this.state.status,
|
||||||
|
this.state.usesBinds,
|
||||||
|
DiskStatus.fromVolumes(this.state._volumes, state.volumes),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> reload() async {
|
||||||
|
final volumes = await serverApi.getServerDiskVolumes();
|
||||||
|
final usesBinds = await serverApi.isUsingBinds();
|
||||||
|
var status = LoadingStatus.error;
|
||||||
|
|
||||||
|
if (volumes.isNotEmpty) {
|
||||||
|
status = LoadingStatus.success;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(
|
||||||
|
ApiServerVolumeState(
|
||||||
|
volumes,
|
||||||
|
status,
|
||||||
|
usesBinds,
|
||||||
|
DiskStatus.fromVolumes(
|
||||||
|
volumes,
|
||||||
|
providerVolumeCubit.state.volumes,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void clear() {
|
||||||
|
emit(ApiServerVolumeState.initial());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
_providerVolumeSubscription.cancel();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
}
|
42
lib/logic/cubit/server_volumes/server_volume_state.dart
Normal file
42
lib/logic/cubit/server_volumes/server_volume_state.dart
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
part of 'server_volume_cubit.dart';
|
||||||
|
|
||||||
|
class ApiServerVolumeState extends ServerInstallationDependendState {
|
||||||
|
const ApiServerVolumeState(
|
||||||
|
this._volumes,
|
||||||
|
this.status,
|
||||||
|
this.usesBinds,
|
||||||
|
this._diskStatus,
|
||||||
|
);
|
||||||
|
|
||||||
|
ApiServerVolumeState.initial()
|
||||||
|
: this(const [], LoadingStatus.uninitialized, null, DiskStatus());
|
||||||
|
|
||||||
|
final List<ServerDiskVolume> _volumes;
|
||||||
|
final DiskStatus _diskStatus;
|
||||||
|
final bool? usesBinds;
|
||||||
|
final LoadingStatus status;
|
||||||
|
|
||||||
|
List<DiskVolume> get volumes => _diskStatus.diskVolumes;
|
||||||
|
DiskStatus get diskStatus => _diskStatus;
|
||||||
|
|
||||||
|
DiskVolume getVolume(final String volumeName) => volumes.firstWhere(
|
||||||
|
(final volume) => volume.name == volumeName,
|
||||||
|
orElse: () => DiskVolume(),
|
||||||
|
);
|
||||||
|
|
||||||
|
ApiServerVolumeState copyWith({
|
||||||
|
final List<ServerDiskVolume>? volumes,
|
||||||
|
final LoadingStatus? status,
|
||||||
|
final bool? usesBinds,
|
||||||
|
final DiskStatus? diskStatus,
|
||||||
|
}) =>
|
||||||
|
ApiServerVolumeState(
|
||||||
|
volumes ?? _volumes,
|
||||||
|
status ?? this.status,
|
||||||
|
usesBinds ?? this.usesBinds,
|
||||||
|
diskStatus ?? _diskStatus,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [_volumes, status, usesBinds];
|
||||||
|
}
|
|
@ -1,31 +1,72 @@
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
import 'package:selfprivacy/logic/common_enum/common_enum.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';
|
||||||
|
|
||||||
part 'services_state.dart';
|
part 'services_state.dart';
|
||||||
|
|
||||||
class ServicesCubit extends ServerInstallationDependendCubit<ServicesState> {
|
class ServicesCubit extends ServerInstallationDependendCubit<ServicesState> {
|
||||||
ServicesCubit(final ServerInstallationCubit serverInstallationCubit)
|
ServicesCubit(final ServerInstallationCubit serverInstallationCubit)
|
||||||
: super(serverInstallationCubit, ServicesState.allOff());
|
: super(serverInstallationCubit, const ServicesState.empty());
|
||||||
final ServerApi api = ServerApi();
|
final ServerApi api = ServerApi();
|
||||||
|
Timer? timer;
|
||||||
@override
|
@override
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
final Map<ServiceTypes, bool> statuses = await api.servicesPowerCheck();
|
final List<Service> services = await api.getAllServices();
|
||||||
emit(
|
emit(
|
||||||
ServicesState(
|
ServicesState(
|
||||||
isPasswordManagerEnable: statuses[ServiceTypes.passwordManager]!,
|
services: services,
|
||||||
isCloudEnable: statuses[ServiceTypes.cloud]!,
|
lockedServices: const [],
|
||||||
isGitEnable: statuses[ServiceTypes.git]!,
|
|
||||||
isSocialNetworkEnable: statuses[ServiceTypes.socialNetwork]!,
|
|
||||||
isVpnEnable: statuses[ServiceTypes.vpn]!,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
timer = Timer(const Duration(seconds: 10), () => reload(useTimer: true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> reload({final bool useTimer = false}) async {
|
||||||
|
final List<Service> services = await api.getAllServices();
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
services: services,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (useTimer) {
|
||||||
|
timer = Timer(const Duration(seconds: 60), () => reload(useTimer: true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> restart(final String serviceId) async {
|
||||||
|
emit(state.copyWith(lockedServices: [...state.lockedServices, serviceId]));
|
||||||
|
await api.restartService(serviceId);
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
reload();
|
||||||
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
lockedServices: state.lockedServices
|
||||||
|
.where((final element) => element != serviceId)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> moveService(
|
||||||
|
final String serviceId,
|
||||||
|
final String destination,
|
||||||
|
) async {
|
||||||
|
await api.moveService(serviceId, destination);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void clear() async {
|
void clear() async {
|
||||||
emit(ServicesState.allOff());
|
emit(const ServicesState.empty());
|
||||||
|
if (timer != null && timer!.isActive) {
|
||||||
|
timer!.cancel();
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,93 +1,91 @@
|
||||||
part of 'services_cubit.dart';
|
part of 'services_cubit.dart';
|
||||||
|
|
||||||
class ServicesState extends ServerInstallationDependendState {
|
class ServicesState extends ServerInstallationDependendState {
|
||||||
factory ServicesState.allOn() => const ServicesState(
|
|
||||||
isPasswordManagerEnable: true,
|
|
||||||
isCloudEnable: true,
|
|
||||||
isGitEnable: true,
|
|
||||||
isSocialNetworkEnable: true,
|
|
||||||
isVpnEnable: true,
|
|
||||||
);
|
|
||||||
|
|
||||||
factory ServicesState.allOff() => const ServicesState(
|
|
||||||
isPasswordManagerEnable: false,
|
|
||||||
isCloudEnable: false,
|
|
||||||
isGitEnable: false,
|
|
||||||
isSocialNetworkEnable: false,
|
|
||||||
isVpnEnable: false,
|
|
||||||
);
|
|
||||||
const ServicesState({
|
const ServicesState({
|
||||||
required this.isPasswordManagerEnable,
|
required this.services,
|
||||||
required this.isCloudEnable,
|
required this.lockedServices,
|
||||||
required this.isGitEnable,
|
|
||||||
required this.isSocialNetworkEnable,
|
|
||||||
required this.isVpnEnable,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final bool isPasswordManagerEnable;
|
const ServicesState.empty()
|
||||||
final bool isCloudEnable;
|
: this(services: const [], lockedServices: const []);
|
||||||
final bool isGitEnable;
|
|
||||||
final bool isSocialNetworkEnable;
|
|
||||||
final bool isVpnEnable;
|
|
||||||
|
|
||||||
ServicesState enableList(
|
final List<Service> services;
|
||||||
final List<ServiceTypes> list,
|
final List<String> lockedServices;
|
||||||
) =>
|
|
||||||
ServicesState(
|
|
||||||
isPasswordManagerEnable: list.contains(ServiceTypes.passwordManager)
|
|
||||||
? true
|
|
||||||
: isPasswordManagerEnable,
|
|
||||||
isCloudEnable: list.contains(ServiceTypes.cloud) ? true : isCloudEnable,
|
|
||||||
isGitEnable:
|
|
||||||
list.contains(ServiceTypes.git) ? true : isPasswordManagerEnable,
|
|
||||||
isSocialNetworkEnable: list.contains(ServiceTypes.socialNetwork)
|
|
||||||
? true
|
|
||||||
: isPasswordManagerEnable,
|
|
||||||
isVpnEnable:
|
|
||||||
list.contains(ServiceTypes.vpn) ? true : isPasswordManagerEnable,
|
|
||||||
);
|
|
||||||
|
|
||||||
ServicesState disableList(
|
bool isServiceLocked(final String serviceId) =>
|
||||||
final List<ServiceTypes> list,
|
lockedServices.contains(serviceId);
|
||||||
) =>
|
|
||||||
ServicesState(
|
bool get isPasswordManagerEnable => services
|
||||||
isPasswordManagerEnable: list.contains(ServiceTypes.passwordManager)
|
.firstWhere(
|
||||||
? false
|
(final service) => service.id == 'bitwarden',
|
||||||
: isPasswordManagerEnable,
|
orElse: () => Service.empty,
|
||||||
isCloudEnable:
|
)
|
||||||
list.contains(ServiceTypes.cloud) ? false : isCloudEnable,
|
.isEnabled;
|
||||||
isGitEnable:
|
bool get isCloudEnable => services
|
||||||
list.contains(ServiceTypes.git) ? false : isPasswordManagerEnable,
|
.firstWhere(
|
||||||
isSocialNetworkEnable: list.contains(ServiceTypes.socialNetwork)
|
(final service) => service.id == 'nextcloud',
|
||||||
? false
|
orElse: () => Service.empty,
|
||||||
: isPasswordManagerEnable,
|
)
|
||||||
isVpnEnable:
|
.isEnabled;
|
||||||
list.contains(ServiceTypes.vpn) ? false : isPasswordManagerEnable,
|
bool get isGitEnable => services
|
||||||
);
|
.firstWhere(
|
||||||
|
(final service) => service.id == 'gitea',
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
)
|
||||||
|
.isEnabled;
|
||||||
|
bool get isSocialNetworkEnable => services
|
||||||
|
.firstWhere(
|
||||||
|
(final service) => service.id == 'pleroma',
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
)
|
||||||
|
.isEnabled;
|
||||||
|
bool get isVpnEnable => services
|
||||||
|
.firstWhere(
|
||||||
|
(final service) => service.id == 'ocserv',
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
)
|
||||||
|
.isEnabled;
|
||||||
|
|
||||||
|
Service? getServiceById(final String id) {
|
||||||
|
final service = services.firstWhere(
|
||||||
|
(final service) => service.id == id,
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
);
|
||||||
|
if (service.id == 'empty') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [
|
List<Object> get props => [
|
||||||
isPasswordManagerEnable,
|
services,
|
||||||
isCloudEnable,
|
lockedServices,
|
||||||
isGitEnable,
|
|
||||||
isSocialNetworkEnable,
|
|
||||||
isVpnEnable
|
|
||||||
];
|
];
|
||||||
|
|
||||||
bool isEnableByType(final ServiceTypes type) {
|
bool isEnableByType(final ServiceTypes type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ServiceTypes.passwordManager:
|
case ServiceTypes.bitwarden:
|
||||||
return isPasswordManagerEnable;
|
return isPasswordManagerEnable;
|
||||||
case ServiceTypes.cloud:
|
case ServiceTypes.nextcloud:
|
||||||
return isCloudEnable;
|
return isCloudEnable;
|
||||||
case ServiceTypes.socialNetwork:
|
case ServiceTypes.pleroma:
|
||||||
return isSocialNetworkEnable;
|
return isSocialNetworkEnable;
|
||||||
case ServiceTypes.git:
|
case ServiceTypes.gitea:
|
||||||
return isGitEnable;
|
return isGitEnable;
|
||||||
case ServiceTypes.vpn:
|
case ServiceTypes.ocserv:
|
||||||
return isVpnEnable;
|
return isVpnEnable;
|
||||||
default:
|
default:
|
||||||
throw Exception('wrong state');
|
throw Exception('wrong state');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServicesState copyWith({
|
||||||
|
final List<Service>? services,
|
||||||
|
final List<String>? lockedServices,
|
||||||
|
}) =>
|
||||||
|
ServicesState(
|
||||||
|
services: services ?? this.services,
|
||||||
|
lockedServices: lockedServices ?? this.lockedServices,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/config/hive_config.dart';
|
import 'package:selfprivacy/config/hive_config.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/hive/user.dart';
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
|
|
||||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
|
||||||
|
|
||||||
export 'package:provider/provider.dart';
|
export 'package:provider/provider.dart';
|
||||||
|
|
||||||
part 'users_state.dart';
|
part 'users_state.dart';
|
||||||
|
@ -15,8 +16,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
serverInstallationCubit,
|
serverInstallationCubit,
|
||||||
const UsersState(
|
const UsersState(
|
||||||
<User>[],
|
<User>[],
|
||||||
User(login: 'root'),
|
false,
|
||||||
User(login: 'loading...'),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
Box<User> box = Hive.box<User>(BNames.usersBox);
|
Box<User> box = Hive.box<User>(BNames.usersBox);
|
||||||
|
@ -26,173 +26,43 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
if (serverInstallationCubit.state is! ServerInstallationFinished) {
|
||||||
final List<User> loadedUsers = box.values.toList();
|
return;
|
||||||
final primaryUser = serverInstallationBox.get(
|
}
|
||||||
BNames.rootUser,
|
final List<User> loadedUsers = box.values.toList();
|
||||||
defaultValue: const User(login: 'loading...'),
|
if (loadedUsers.isNotEmpty) {
|
||||||
);
|
|
||||||
final List<String> rootKeys = [
|
|
||||||
...serverInstallationBox.get(BNames.rootKeys, defaultValue: [])
|
|
||||||
];
|
|
||||||
if (loadedUsers.isNotEmpty) {
|
|
||||||
emit(
|
|
||||||
UsersState(
|
|
||||||
loadedUsers,
|
|
||||||
User(login: 'root', sshKeys: rootKeys),
|
|
||||||
primaryUser,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final ApiResponse<List<String>> usersFromServer =
|
|
||||||
await api.getUsersList();
|
|
||||||
if (usersFromServer.isSuccess) {
|
|
||||||
final List<User> updatedList =
|
|
||||||
mergeLocalAndServerUsers(loadedUsers, usersFromServer.data);
|
|
||||||
emit(
|
|
||||||
UsersState(
|
|
||||||
updatedList,
|
|
||||||
User(login: 'root', sshKeys: rootKeys),
|
|
||||||
primaryUser,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<User> usersWithSshKeys = await loadSshKeys(state.users);
|
|
||||||
// Update the users it the box
|
|
||||||
box.clear();
|
|
||||||
box.addAll(usersWithSshKeys);
|
|
||||||
|
|
||||||
final User rootUserWithSshKeys =
|
|
||||||
(await loadSshKeys([state.rootUser])).first;
|
|
||||||
serverInstallationBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys);
|
|
||||||
final User primaryUserWithSshKeys =
|
|
||||||
(await loadSshKeys([state.primaryUser])).first;
|
|
||||||
serverInstallationBox.put(BNames.rootUser, primaryUserWithSshKeys);
|
|
||||||
emit(
|
emit(
|
||||||
UsersState(
|
UsersState(
|
||||||
usersWithSshKeys,
|
loadedUsers,
|
||||||
rootUserWithSshKeys,
|
false,
|
||||||
primaryUserWithSshKeys,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<User> mergeLocalAndServerUsers(
|
|
||||||
final List<User> localUsers,
|
|
||||||
final List<String> serverUsers,
|
|
||||||
) {
|
|
||||||
// If local user not exists on server, add it with isFoundOnServer = false
|
|
||||||
// If server user not exists on local, add it
|
|
||||||
|
|
||||||
final List<User> mergedUsers = [];
|
|
||||||
final List<String> serverUsersCopy = List.from(serverUsers);
|
|
||||||
|
|
||||||
for (final User localUser in localUsers) {
|
|
||||||
if (serverUsersCopy.contains(localUser.login)) {
|
|
||||||
mergedUsers.add(
|
|
||||||
User(
|
|
||||||
login: localUser.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: localUser.password,
|
|
||||||
sshKeys: localUser.sshKeys,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
serverUsersCopy.remove(localUser.login);
|
|
||||||
} else {
|
|
||||||
mergedUsers.add(
|
|
||||||
User(
|
|
||||||
login: localUser.login,
|
|
||||||
isFoundOnServer: false,
|
|
||||||
password: localUser.password,
|
|
||||||
note: localUser.note,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final String serverUser in serverUsersCopy) {
|
|
||||||
mergedUsers.add(
|
|
||||||
User(
|
|
||||||
login: serverUser,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mergedUsers;
|
refresh();
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<User>> loadSshKeys(final List<User> users) async {
|
|
||||||
final List<User> updatedUsers = [];
|
|
||||||
|
|
||||||
for (final User user in users) {
|
|
||||||
if (user.isFoundOnServer ||
|
|
||||||
user.login == 'root' ||
|
|
||||||
user.login == state.primaryUser.login) {
|
|
||||||
final ApiResponse<List<String>> sshKeys =
|
|
||||||
await api.getUserSshKeys(user);
|
|
||||||
print('sshKeys for $user: ${sshKeys.data}');
|
|
||||||
if (sshKeys.isSuccess) {
|
|
||||||
updatedUsers.add(
|
|
||||||
User(
|
|
||||||
login: user.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: user.password,
|
|
||||||
sshKeys: sshKeys.data,
|
|
||||||
note: user.note,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
updatedUsers.add(
|
|
||||||
User(
|
|
||||||
login: user.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: user.password,
|
|
||||||
note: user.note,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updatedUsers.add(
|
|
||||||
User(
|
|
||||||
login: user.login,
|
|
||||||
isFoundOnServer: false,
|
|
||||||
password: user.password,
|
|
||||||
note: user.note,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return updatedUsers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> refresh() async {
|
Future<void> refresh() async {
|
||||||
List<User> updatedUsers = List<User>.from(state.users);
|
if (serverInstallationCubit.state is! ServerInstallationFinished) {
|
||||||
final ApiResponse<List<String>> usersFromServer = await api.getUsersList();
|
return;
|
||||||
if (usersFromServer.isSuccess) {
|
}
|
||||||
updatedUsers =
|
emit(state.copyWith(isLoading: true));
|
||||||
mergeLocalAndServerUsers(updatedUsers, usersFromServer.data);
|
final List<User> usersFromServer = await api.getAllUsers();
|
||||||
|
if (usersFromServer.isNotEmpty) {
|
||||||
|
emit(
|
||||||
|
UsersState(
|
||||||
|
usersFromServer,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
// Update the users it the box
|
||||||
|
await box.clear();
|
||||||
|
await box.addAll(usersFromServer);
|
||||||
|
} else {
|
||||||
|
getIt<NavigationService>()
|
||||||
|
.showSnackBar('users.could_not_fetch_users'.tr());
|
||||||
|
emit(state.copyWith(isLoading: false));
|
||||||
}
|
}
|
||||||
final List<User> usersWithSshKeys = await loadSshKeys(updatedUsers);
|
|
||||||
box.clear();
|
|
||||||
box.addAll(usersWithSshKeys);
|
|
||||||
final User rootUserWithSshKeys =
|
|
||||||
(await loadSshKeys([state.rootUser])).first;
|
|
||||||
serverInstallationBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys);
|
|
||||||
final User primaryUserWithSshKeys =
|
|
||||||
(await loadSshKeys([state.primaryUser])).first;
|
|
||||||
serverInstallationBox.put(BNames.rootUser, primaryUserWithSshKeys);
|
|
||||||
emit(
|
|
||||||
UsersState(
|
|
||||||
usersWithSshKeys,
|
|
||||||
rootUserWithSshKeys,
|
|
||||||
primaryUserWithSshKeys,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createUser(final User user) async {
|
Future<void> createUser(final User user) async {
|
||||||
|
@ -201,18 +71,24 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
.any((final User u) => u.login == user.login && u.isFoundOnServer)) {
|
.any((final User u) => u.login == user.login && u.isFoundOnServer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If user is root or primary user, do nothing
|
final String? password = user.password;
|
||||||
if (user.login == 'root' || user.login == state.primaryUser.login) {
|
if (password == null) {
|
||||||
|
getIt<NavigationService>()
|
||||||
|
.showSnackBar('users.could_not_create_user'.tr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If API returned error, do nothing
|
// If API returned error, do nothing
|
||||||
final ApiResponse<User> result = await api.createUser(user);
|
final UserMutationResult result =
|
||||||
if (!result.isSuccess) {
|
await api.createUser(user.login, password);
|
||||||
|
final User? createdUser = result.user;
|
||||||
|
if (!result.success || createdUser == null) {
|
||||||
|
getIt<NavigationService>()
|
||||||
|
.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(result.data);
|
loadedUsers.add(createdUser);
|
||||||
await box.clear();
|
await box.clear();
|
||||||
await box.addAll(loadedUsers);
|
await box.addAll(loadedUsers);
|
||||||
emit(state.copyWith(users: loadedUsers));
|
emit(state.copyWith(users: loadedUsers));
|
||||||
|
@ -220,142 +96,69 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
|
|
||||||
Future<void> deleteUser(final User user) async {
|
Future<void> deleteUser(final User user) async {
|
||||||
// If user is primary or root, don't delete
|
// If user is primary or root, don't delete
|
||||||
if (user.login == state.primaryUser.login || user.login == 'root') {
|
if (user.type != UserType.normal) {
|
||||||
|
getIt<NavigationService>()
|
||||||
|
.showSnackBar('users.could_not_delete_user'.tr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final List<User> loadedUsers = List<User>.from(state.users);
|
final List<User> loadedUsers = List<User>.from(state.users);
|
||||||
final bool result = await api.deleteUser(user);
|
final GenericMutationResult result = await api.deleteUser(user.login);
|
||||||
if (result) {
|
if (result.success) {
|
||||||
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 {
|
||||||
|
getIt<NavigationService>()
|
||||||
|
.showSnackBar(result.message ?? 'users.could_not_delete_user'.tr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> changeUserPassword(
|
||||||
|
final User user,
|
||||||
|
final String newPassword,
|
||||||
|
) async {
|
||||||
|
if (user.type == UserType.root) {
|
||||||
|
getIt<NavigationService>()
|
||||||
|
.showSnackBar('users.could_not_change_password'.tr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final UserMutationResult result =
|
||||||
|
await api.updateUser(user.login, newPassword);
|
||||||
|
if (!result.success) {
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
result.message ?? 'users.could_not_change_password'.tr(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addSshKey(final User user, final String publicKey) async {
|
Future<void> addSshKey(final User user, final String publicKey) async {
|
||||||
// If adding root key, use api.addRootSshKey
|
final UserMutationResult result =
|
||||||
// Otherwise, use api.addUserSshKey
|
await api.addSshKey(user.login, publicKey);
|
||||||
if (user.login == 'root') {
|
if (result.success) {
|
||||||
final ApiResponse<void> result = await api.addRootSshKey(publicKey);
|
final User updatedUser = result.user!;
|
||||||
if (result.isSuccess) {
|
final int index =
|
||||||
// Add ssh key to the array of root keys
|
state.users.indexWhere((final User u) => u.login == user.login);
|
||||||
final List<String> rootKeys = serverInstallationBox
|
await box.putAt(index, updatedUser);
|
||||||
.get(BNames.rootKeys, defaultValue: []) as List<String>;
|
emit(
|
||||||
rootKeys.add(publicKey);
|
state.copyWith(
|
||||||
serverInstallationBox.put(BNames.rootKeys, rootKeys);
|
users: box.values.toList(),
|
||||||
emit(
|
),
|
||||||
state.copyWith(
|
);
|
||||||
rootUser: User(
|
|
||||||
login: state.rootUser.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: state.rootUser.password,
|
|
||||||
sshKeys: rootKeys,
|
|
||||||
note: state.rootUser.note,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
final ApiResponse<void> result = await api.addUserSshKey(user, publicKey);
|
getIt<NavigationService>()
|
||||||
if (result.isSuccess) {
|
.showSnackBar(result.message ?? 'users.could_not_add_ssh_key'.tr());
|
||||||
// If it is primary user, update primary user
|
|
||||||
if (user.login == state.primaryUser.login) {
|
|
||||||
final List<String> primaryUserKeys =
|
|
||||||
List<String>.from(state.primaryUser.sshKeys);
|
|
||||||
primaryUserKeys.add(publicKey);
|
|
||||||
final User updatedUser = User(
|
|
||||||
login: state.primaryUser.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: state.primaryUser.password,
|
|
||||||
sshKeys: primaryUserKeys,
|
|
||||||
note: state.primaryUser.note,
|
|
||||||
);
|
|
||||||
serverInstallationBox.put(BNames.rootUser, updatedUser);
|
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
primaryUser: updatedUser,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// If it is not primary user, update user
|
|
||||||
final List<String> userKeys = List<String>.from(user.sshKeys);
|
|
||||||
userKeys.add(publicKey);
|
|
||||||
final User updatedUser = User(
|
|
||||||
login: user.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: user.password,
|
|
||||||
sshKeys: userKeys,
|
|
||||||
note: user.note,
|
|
||||||
);
|
|
||||||
await box.putAt(box.values.toList().indexOf(user), updatedUser);
|
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
users: box.values.toList(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteSshKey(final User user, final String publicKey) async {
|
Future<void> deleteSshKey(final User user, final String publicKey) async {
|
||||||
// All keys are deleted via api.deleteUserSshKey
|
final UserMutationResult result =
|
||||||
|
await api.removeSshKey(user.login, publicKey);
|
||||||
final ApiResponse<void> result =
|
if (result.success) {
|
||||||
await api.deleteUserSshKey(user, publicKey);
|
final User updatedUser = result.user!;
|
||||||
if (result.isSuccess) {
|
final int index =
|
||||||
// If it is root user, delete key from root keys
|
state.users.indexWhere((final User u) => u.login == user.login);
|
||||||
// If it is primary user, update primary user
|
await box.putAt(index, updatedUser);
|
||||||
// If it is not primary user, update user
|
|
||||||
|
|
||||||
if (user.login == 'root') {
|
|
||||||
final List<String> rootKeys = serverInstallationBox
|
|
||||||
.get(BNames.rootKeys, defaultValue: []) as List<String>;
|
|
||||||
rootKeys.remove(publicKey);
|
|
||||||
serverInstallationBox.put(BNames.rootKeys, rootKeys);
|
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
rootUser: User(
|
|
||||||
login: state.rootUser.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: state.rootUser.password,
|
|
||||||
sshKeys: rootKeys,
|
|
||||||
note: state.rootUser.note,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (user.login == state.primaryUser.login) {
|
|
||||||
final List<String> primaryUserKeys =
|
|
||||||
List<String>.from(state.primaryUser.sshKeys);
|
|
||||||
primaryUserKeys.remove(publicKey);
|
|
||||||
final User updatedUser = User(
|
|
||||||
login: state.primaryUser.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: state.primaryUser.password,
|
|
||||||
sshKeys: primaryUserKeys,
|
|
||||||
note: state.primaryUser.note,
|
|
||||||
);
|
|
||||||
serverInstallationBox.put(BNames.rootUser, updatedUser);
|
|
||||||
emit(
|
|
||||||
state.copyWith(
|
|
||||||
primaryUser: updatedUser,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final List<String> userKeys = List<String>.from(user.sshKeys);
|
|
||||||
userKeys.remove(publicKey);
|
|
||||||
final User updatedUser = User(
|
|
||||||
login: user.login,
|
|
||||||
isFoundOnServer: true,
|
|
||||||
password: user.password,
|
|
||||||
sshKeys: userKeys,
|
|
||||||
note: user.note,
|
|
||||||
);
|
|
||||||
await box.putAt(box.values.toList().indexOf(user), updatedUser);
|
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
users: box.values.toList(),
|
users: box.values.toList(),
|
||||||
|
@ -369,8 +172,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
emit(
|
emit(
|
||||||
const UsersState(
|
const UsersState(
|
||||||
<User>[],
|
<User>[],
|
||||||
User(login: 'root'),
|
false,
|
||||||
User(login: 'loading...'),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,34 @@
|
||||||
part of 'users_cubit.dart';
|
part of 'users_cubit.dart';
|
||||||
|
|
||||||
class UsersState extends ServerInstallationDependendState {
|
class UsersState extends ServerInstallationDependendState {
|
||||||
const UsersState(this.users, this.rootUser, this.primaryUser);
|
const UsersState(this.users, this.isLoading);
|
||||||
|
|
||||||
final List<User> users;
|
final List<User> users;
|
||||||
final User rootUser;
|
final bool isLoading;
|
||||||
final User primaryUser;
|
|
||||||
|
User get rootUser =>
|
||||||
|
users.firstWhere((final user) => user.type == UserType.root);
|
||||||
|
|
||||||
|
User get primaryUser =>
|
||||||
|
users.firstWhere((final user) => user.type == UserType.primary);
|
||||||
|
|
||||||
|
List<User> get normalUsers =>
|
||||||
|
users.where((final user) => user.type == UserType.normal).toList();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [users, rootUser, primaryUser];
|
List<Object> get props => [users, isLoading];
|
||||||
|
|
||||||
UsersState copyWith({
|
UsersState copyWith({
|
||||||
final List<User>? users,
|
final List<User>? users,
|
||||||
final User? rootUser,
|
final bool? isLoading,
|
||||||
final User? primaryUser,
|
|
||||||
}) =>
|
}) =>
|
||||||
UsersState(
|
UsersState(
|
||||||
users ?? this.users,
|
users ?? this.users,
|
||||||
rootUser ?? this.rootUser,
|
isLoading ?? this.isLoading,
|
||||||
primaryUser ?? this.primaryUser,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
bool isLoginRegistered(final String login) =>
|
bool isLoginRegistered(final String login) =>
|
||||||
users.any((final User user) => user.login == login) ||
|
users.any((final User user) => user.login == login);
|
||||||
login == rootUser.login ||
|
|
||||||
login == primaryUser.login;
|
|
||||||
|
|
||||||
bool get isEmpty => users.isEmpty;
|
bool get isEmpty => users.isEmpty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ class ApiConfigModel {
|
||||||
|
|
||||||
Future<void> storeBackblazeCredential(final BackblazeCredential value) async {
|
Future<void> storeBackblazeCredential(final BackblazeCredential value) async {
|
||||||
await _box.put(BNames.backblazeCredential, value);
|
await _box.put(BNames.backblazeCredential, value);
|
||||||
|
|
||||||
_backblazeCredential = value;
|
_backblazeCredential = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +63,6 @@ class ApiConfigModel {
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
_hetznerKey = _box.get(BNames.hetznerKey);
|
_hetznerKey = _box.get(BNames.hetznerKey);
|
||||||
|
|
||||||
_cloudFlareKey = _box.get(BNames.cloudFlareKey);
|
_cloudFlareKey = _box.get(BNames.cloudFlareKey);
|
||||||
_backblazeCredential = _box.get(BNames.backblazeCredential);
|
_backblazeCredential = _box.get(BNames.backblazeCredential);
|
||||||
_serverDomain = _box.get(BNames.serverDomain);
|
_serverDomain = _box.get(BNames.serverDomain);
|
||||||
|
|
18
lib/logic/models/auto_upgrade_settings.dart
Normal file
18
lib/logic/models/auto_upgrade_settings.dart
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_settings.graphql.dart';
|
||||||
|
|
||||||
|
class AutoUpgradeSettings {
|
||||||
|
AutoUpgradeSettings({
|
||||||
|
required this.enable,
|
||||||
|
required this.allowReboot,
|
||||||
|
});
|
||||||
|
|
||||||
|
AutoUpgradeSettings.fromGraphQL(
|
||||||
|
final Query$SystemSettings$system$settings$autoUpgrade autoUpgrade,
|
||||||
|
) : this(
|
||||||
|
enable: autoUpgrade.enable,
|
||||||
|
allowReboot: autoUpgrade.allowReboot,
|
||||||
|
);
|
||||||
|
|
||||||
|
final bool enable;
|
||||||
|
final bool allowReboot;
|
||||||
|
}
|
38
lib/logic/models/disk_size.dart
Normal file
38
lib/logic/models/disk_size.dart
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
|
class DiskSize {
|
||||||
|
const DiskSize({final this.byte = 0});
|
||||||
|
|
||||||
|
DiskSize.fromKibibyte(final double kibibyte)
|
||||||
|
: this(byte: (kibibyte * 1024).round());
|
||||||
|
DiskSize.fromMebibyte(final double mebibyte)
|
||||||
|
: this(byte: (mebibyte * 1024 * 1024).round());
|
||||||
|
DiskSize.fromGibibyte(final double gibibyte)
|
||||||
|
: this(byte: (gibibyte * 1024 * 1024 * 1024).round());
|
||||||
|
|
||||||
|
final int byte;
|
||||||
|
|
||||||
|
double get kibibyte => byte / 1024.0;
|
||||||
|
double get mebibyte => byte / 1024.0 / 1024.0;
|
||||||
|
double get gibibyte => byte / 1024.0 / 1024.0 / 1024.0;
|
||||||
|
|
||||||
|
DiskSize operator +(final DiskSize other) =>
|
||||||
|
DiskSize(byte: byte + other.byte);
|
||||||
|
DiskSize operator -(final DiskSize other) =>
|
||||||
|
DiskSize(byte: byte - other.byte);
|
||||||
|
DiskSize operator *(final double other) =>
|
||||||
|
DiskSize(byte: (byte * other).round());
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
if (byte < 1024) {
|
||||||
|
return '${byte.toStringAsFixed(0)} ${tr('bytes')}';
|
||||||
|
} else if (byte < 1024 * 1024) {
|
||||||
|
return 'providers.storage.kb'.tr(args: [kibibyte.toStringAsFixed(1)]);
|
||||||
|
} else if (byte < 1024 * 1024 * 1024) {
|
||||||
|
return 'providers.storage.mb'.tr(args: [mebibyte.toStringAsFixed(1)]);
|
||||||
|
} else {
|
||||||
|
return 'providers.storage.gb'.tr(args: [gibibyte.toStringAsFixed(1)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
122
lib/logic/models/disk_status.dart
Normal file
122
lib/logic/models/disk_status.dart
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
||||||
|
|
||||||
|
class DiskVolume {
|
||||||
|
DiskVolume({
|
||||||
|
this.name = '',
|
||||||
|
this.sizeTotal = const DiskSize(byte: 0),
|
||||||
|
this.sizeUsed = const DiskSize(byte: 0),
|
||||||
|
this.root = false,
|
||||||
|
this.isResizable = false,
|
||||||
|
this.serverDiskVolume,
|
||||||
|
this.providerVolume,
|
||||||
|
});
|
||||||
|
|
||||||
|
DiskVolume.fromServerDiscVolume(
|
||||||
|
final ServerDiskVolume volume,
|
||||||
|
final ServerVolume? providerVolume,
|
||||||
|
) : this(
|
||||||
|
name: volume.name,
|
||||||
|
sizeTotal: DiskSize(
|
||||||
|
byte:
|
||||||
|
volume.totalSpace == 'None' ? 0 : int.parse(volume.totalSpace),
|
||||||
|
),
|
||||||
|
sizeUsed: DiskSize(
|
||||||
|
byte: volume.usedSpace == 'None' ? 0 : int.parse(volume.usedSpace),
|
||||||
|
),
|
||||||
|
root: volume.root,
|
||||||
|
isResizable: providerVolume != null,
|
||||||
|
serverDiskVolume: volume,
|
||||||
|
providerVolume: providerVolume,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Get the display name of the volume
|
||||||
|
///
|
||||||
|
/// If it is sda1 and root the name is "System disk"
|
||||||
|
/// If there is a mapping to providerVolume, the name is "Expandable volume"
|
||||||
|
/// Otherwise the name is the name of the volume
|
||||||
|
String get displayName {
|
||||||
|
if (root) {
|
||||||
|
return 'System disk';
|
||||||
|
} else if (providerVolume != null) {
|
||||||
|
return 'Expandable volume';
|
||||||
|
} else {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DiskSize sizeUsed;
|
||||||
|
DiskSize sizeTotal;
|
||||||
|
String name;
|
||||||
|
bool root;
|
||||||
|
bool isResizable;
|
||||||
|
ServerDiskVolume? serverDiskVolume;
|
||||||
|
ServerVolume? providerVolume;
|
||||||
|
|
||||||
|
/// from 0.0 to 1.0
|
||||||
|
double get percentage =>
|
||||||
|
sizeTotal.byte == 0 ? 0 : sizeUsed.byte / sizeTotal.byte;
|
||||||
|
bool get isDiskOkay =>
|
||||||
|
percentage < 0.8 && sizeTotal.gibibyte - sizeUsed.gibibyte > 2.0;
|
||||||
|
|
||||||
|
DiskVolume copyWith({
|
||||||
|
final DiskSize? sizeUsed,
|
||||||
|
final DiskSize? sizeTotal,
|
||||||
|
final String? name,
|
||||||
|
final bool? root,
|
||||||
|
final bool? isResizable,
|
||||||
|
final ServerDiskVolume? serverDiskVolume,
|
||||||
|
final ServerVolume? providerVolume,
|
||||||
|
}) =>
|
||||||
|
DiskVolume(
|
||||||
|
sizeUsed: sizeUsed ?? this.sizeUsed,
|
||||||
|
sizeTotal: sizeTotal ?? this.sizeTotal,
|
||||||
|
name: name ?? this.name,
|
||||||
|
root: root ?? this.root,
|
||||||
|
isResizable: isResizable ?? this.isResizable,
|
||||||
|
serverDiskVolume: serverDiskVolume ?? this.serverDiskVolume,
|
||||||
|
providerVolume: providerVolume ?? this.providerVolume,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DiskStatus {
|
||||||
|
DiskStatus.fromVolumes(
|
||||||
|
final List<ServerDiskVolume> serverVolumes,
|
||||||
|
final List<ServerVolume> providerVolumes,
|
||||||
|
) {
|
||||||
|
diskVolumes = serverVolumes.map((
|
||||||
|
final ServerDiskVolume volume,
|
||||||
|
) {
|
||||||
|
ServerVolume? providerVolume;
|
||||||
|
|
||||||
|
for (final ServerVolume iterableProviderVolume in providerVolumes) {
|
||||||
|
if (iterableProviderVolume.linuxDevice == null ||
|
||||||
|
volume.model == null ||
|
||||||
|
volume.serial == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String deviceId =
|
||||||
|
iterableProviderVolume.linuxDevice!.split('/').last;
|
||||||
|
if (deviceId.contains(volume.model!) &&
|
||||||
|
deviceId.contains(volume.serial!)) {
|
||||||
|
providerVolume = iterableProviderVolume;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final DiskVolume diskVolume =
|
||||||
|
DiskVolume.fromServerDiscVolume(volume, providerVolume);
|
||||||
|
|
||||||
|
return diskVolume;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
DiskStatus() {
|
||||||
|
diskVolumes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get isDiskOkay => diskVolumes.every((final volume) => volume.isDiskOkay);
|
||||||
|
|
||||||
|
List<DiskVolume> diskVolumes = [];
|
||||||
|
}
|
|
@ -7,7 +7,8 @@
|
||||||
5. ServerVolume
|
5. ServerVolume
|
||||||
6. BackblazeBucket
|
6. BackblazeBucket
|
||||||
|
|
||||||
|
|
||||||
## Enums
|
## Enums
|
||||||
|
|
||||||
100. DnsProvider
|
100. DnsProvider
|
||||||
101. ServerProvider
|
101. ServerProvider
|
||||||
|
102. UserType
|
||||||
|
|
|
@ -55,12 +55,21 @@ class ServerVolume {
|
||||||
ServerVolume({
|
ServerVolume({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
|
required this.sizeByte,
|
||||||
|
required this.serverId,
|
||||||
|
required this.linuxDevice,
|
||||||
});
|
});
|
||||||
|
|
||||||
@HiveField(1)
|
@HiveField(1)
|
||||||
int id;
|
int id;
|
||||||
@HiveField(2)
|
@HiveField(2)
|
||||||
String name;
|
String name;
|
||||||
|
@HiveField(3, defaultValue: 10737418240) // 10 Gb
|
||||||
|
int sizeByte;
|
||||||
|
@HiveField(4, defaultValue: null)
|
||||||
|
int? serverId;
|
||||||
|
@HiveField(5, defaultValue: null)
|
||||||
|
String? linuxDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
@HiveType(typeId: 101)
|
@HiveType(typeId: 101)
|
||||||
|
|
|
@ -73,17 +73,26 @@ class ServerVolumeAdapter extends TypeAdapter<ServerVolume> {
|
||||||
return ServerVolume(
|
return ServerVolume(
|
||||||
id: fields[1] as int,
|
id: fields[1] as int,
|
||||||
name: fields[2] as String,
|
name: fields[2] as String,
|
||||||
|
sizeByte: fields[3] == null ? 10737418240 : fields[3] as int,
|
||||||
|
serverId: fields[4] as int?,
|
||||||
|
linuxDevice: fields[5] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void write(BinaryWriter writer, ServerVolume obj) {
|
void write(BinaryWriter writer, ServerVolume obj) {
|
||||||
writer
|
writer
|
||||||
..writeByte(2)
|
..writeByte(5)
|
||||||
..writeByte(1)
|
..writeByte(1)
|
||||||
..write(obj.id)
|
..write(obj.id)
|
||||||
..writeByte(2)
|
..writeByte(2)
|
||||||
..write(obj.name);
|
..write(obj.name)
|
||||||
|
..writeByte(3)
|
||||||
|
..write(obj.sizeByte)
|
||||||
|
..writeByte(4)
|
||||||
|
..write(obj.serverId)
|
||||||
|
..writeByte(5)
|
||||||
|
..write(obj.linuxDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -2,6 +2,8 @@ import 'dart:ui';
|
||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.graphql.dart';
|
||||||
import 'package:selfprivacy/utils/color_utils.dart';
|
import 'package:selfprivacy/utils/color_utils.dart';
|
||||||
|
|
||||||
part 'user.g.dart';
|
part 'user.g.dart';
|
||||||
|
@ -10,12 +12,21 @@ part 'user.g.dart';
|
||||||
class User extends Equatable {
|
class User extends Equatable {
|
||||||
const User({
|
const User({
|
||||||
required this.login,
|
required this.login,
|
||||||
|
required this.type,
|
||||||
this.password,
|
this.password,
|
||||||
this.sshKeys = const [],
|
this.sshKeys = const [],
|
||||||
this.isFoundOnServer = true,
|
this.isFoundOnServer = true,
|
||||||
this.note,
|
this.note,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
User.fromGraphQL(final Fragment$userFields user)
|
||||||
|
: this(
|
||||||
|
login: user.username,
|
||||||
|
type: UserType.fromGraphQL(user.userType),
|
||||||
|
sshKeys: user.sshKeys,
|
||||||
|
isFoundOnServer: true,
|
||||||
|
);
|
||||||
|
|
||||||
@HiveField(0)
|
@HiveField(0)
|
||||||
final String login;
|
final String login;
|
||||||
|
|
||||||
|
@ -31,6 +42,9 @@ class User extends Equatable {
|
||||||
@HiveField(4)
|
@HiveField(4)
|
||||||
final String? note;
|
final String? note;
|
||||||
|
|
||||||
|
@HiveField(5, defaultValue: UserType.normal)
|
||||||
|
final UserType type;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [login, password, sshKeys, isFoundOnServer, note];
|
List<Object?> get props => [login, password, sshKeys, isFoundOnServer, note];
|
||||||
|
|
||||||
|
@ -40,3 +54,26 @@ class User extends Equatable {
|
||||||
String toString() =>
|
String toString() =>
|
||||||
'$login, ${isFoundOnServer ? 'found' : 'not found'}, ${sshKeys.length} ssh keys, note: $note';
|
'$login, ${isFoundOnServer ? 'found' : 'not found'}, ${sshKeys.length} ssh keys, note: $note';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@HiveType(typeId: 102)
|
||||||
|
enum UserType {
|
||||||
|
@HiveField(0)
|
||||||
|
root,
|
||||||
|
@HiveField(1)
|
||||||
|
primary,
|
||||||
|
@HiveField(2)
|
||||||
|
normal;
|
||||||
|
|
||||||
|
factory UserType.fromGraphQL(final Enum$UserType type) {
|
||||||
|
switch (type) {
|
||||||
|
case Enum$UserType.ROOT:
|
||||||
|
return root;
|
||||||
|
case Enum$UserType.PRIMARY:
|
||||||
|
return primary;
|
||||||
|
case Enum$UserType.NORMAL:
|
||||||
|
return normal;
|
||||||
|
case Enum$UserType.$unknown:
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue