mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-26 18:56:38 +00:00
- Refactor Hive boxes
- Delete SSH generation leftovers - Migrate users box to an encrypted box
This commit is contained in:
parent
19bc780db1
commit
bf79fb1adf
|
@ -27,7 +27,7 @@ class BlocAndProviderConfig extends StatelessWidget {
|
|||
BlocProvider(
|
||||
create: (_) => AppSettingsCubit(
|
||||
isDarkModeOn: isDark,
|
||||
isOnbordingShowing: true,
|
||||
isOnboardingShowing: true,
|
||||
)..load(),
|
||||
),
|
||||
BlocProvider(create: (_) => serverInstallationCubit, lazy: false),
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'package:get_it/get_it.dart';
|
|||
import 'package:selfprivacy/logic/get_it/api_config.dart';
|
||||
import 'package:selfprivacy/logic/get_it/console.dart';
|
||||
import 'package:selfprivacy/logic/get_it/navigation.dart';
|
||||
import 'package:selfprivacy/logic/get_it/ssh.dart';
|
||||
import 'package:selfprivacy/logic/get_it/timer.dart';
|
||||
|
||||
export 'package:selfprivacy/logic/get_it/api_config.dart';
|
||||
|
@ -17,7 +16,6 @@ Future<void> getItSetup() async {
|
|||
|
||||
getIt.registerSingleton<ConsoleModel>(ConsoleModel());
|
||||
getIt.registerSingleton<TimerModel>(TimerModel());
|
||||
getIt.registerSingleton<SSHModel>(SSHModel()..init());
|
||||
getIt.registerSingleton<ApiConfigModel>(ApiConfigModel()..init());
|
||||
|
||||
await getIt.allReady();
|
||||
|
|
|
@ -19,15 +19,22 @@ class HiveConfig {
|
|||
Hive.registerAdapter(BackblazeBucketAdapter());
|
||||
Hive.registerAdapter(ServerVolumeAdapter());
|
||||
|
||||
await Hive.openBox(BNames.appSettings);
|
||||
await Hive.openBox<User>(BNames.users);
|
||||
await Hive.openBox(BNames.servicesState);
|
||||
await Hive.openBox(BNames.appSettingsBox);
|
||||
|
||||
var cipher = HiveAesCipher(await getEncryptedKey(BNames.key));
|
||||
await Hive.openBox(BNames.appConfig, encryptionCipher: cipher);
|
||||
var cipher = HiveAesCipher(
|
||||
await getEncryptedKey(BNames.serverInstallationEncryptionKey));
|
||||
|
||||
var sshCipher = HiveAesCipher(await getEncryptedKey(BNames.sshEnckey));
|
||||
await Hive.openBox(BNames.sshConfig, encryptionCipher: sshCipher);
|
||||
await Hive.openBox<User>(BNames.usersDeprecated);
|
||||
await Hive.openBox<User>(BNames.users, encryptionCipher: cipher);
|
||||
|
||||
Box<User> deprecatedUsers = Hive.box<User>(BNames.usersDeprecated);
|
||||
if (deprecatedUsers.isNotEmpty) {
|
||||
Box<User> users = Hive.box<User>(BNames.users);
|
||||
users.addAll(deprecatedUsers.values.toList());
|
||||
deprecatedUsers.clear();
|
||||
}
|
||||
|
||||
await Hive.openBox(BNames.serverInstallation, encryptionCipher: cipher);
|
||||
}
|
||||
|
||||
static Future<Uint8List> getEncryptedKey(String encKey) async {
|
||||
|
@ -43,33 +50,65 @@ class HiveConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/// Mappings for the different boxes and their keys
|
||||
class BNames {
|
||||
static String appConfig = 'appConfig';
|
||||
/// App settings box. Contains app settings like [isDarkModeOn], [isOnboardingShowing]
|
||||
static String appSettingsBox = 'appSettings';
|
||||
|
||||
/// A boolean field of [appSettingsBox] box.
|
||||
static String isDarkModeOn = 'isDarkModeOn';
|
||||
static String isOnbordingShowing = 'isOnbordingShowing';
|
||||
static String users = 'users';
|
||||
|
||||
/// A boolean field of [appSettingsBox] box.
|
||||
static String isOnboardingShowing = 'isOnboardingShowing';
|
||||
|
||||
/// Encryption key to decrypt [serverInstallation] and [users] box.
|
||||
static String serverInstallationEncryptionKey = 'key';
|
||||
|
||||
/// Server installation box. Contains server details and provider tokens.
|
||||
static String serverInstallation = 'appConfig';
|
||||
|
||||
/// A List<String> field of [serverInstallation] box.
|
||||
static String rootKeys = 'rootKeys';
|
||||
|
||||
static String appSettings = 'appSettings';
|
||||
static String servicesState = 'servicesState';
|
||||
|
||||
static String key = 'key';
|
||||
static String sshEnckey = 'sshEngkey';
|
||||
|
||||
/// A boolean field of [serverInstallation] box.
|
||||
static String hasFinalChecked = 'hasFinalChecked';
|
||||
|
||||
/// A boolean field of [serverInstallation] box.
|
||||
static String isServerStarted = 'isServerStarted';
|
||||
|
||||
/// A [ServerDomain] field of [serverInstallation] box.
|
||||
static String serverDomain = 'cloudFlareDomain';
|
||||
|
||||
/// A String field of [serverInstallation] box.
|
||||
static String hetznerKey = 'hetznerKey';
|
||||
|
||||
/// A String field of [serverInstallation] box.
|
||||
static String cloudFlareKey = 'cloudFlareKey';
|
||||
|
||||
/// A [User] field of [serverInstallation] box.
|
||||
static String rootUser = 'rootUser';
|
||||
|
||||
/// A [ServerHostingDetails] field of [serverInstallation] box.
|
||||
static String serverDetails = 'hetznerServer';
|
||||
static String backblazeKey = 'backblazeKey';
|
||||
|
||||
/// A [BackblazeCredential] field of [serverInstallation] box.
|
||||
static String backblazeCredential = 'backblazeKey';
|
||||
|
||||
/// A [BackblazeBucket] field of [serverInstallation] box.
|
||||
static String backblazeBucket = 'backblazeBucket';
|
||||
|
||||
/// A boolean field of [serverInstallation] box.
|
||||
static String isLoading = 'isLoading';
|
||||
|
||||
/// A boolean field of [serverInstallation] box.
|
||||
static String isServerResetedFirstTime = 'isServerResetedFirstTime';
|
||||
|
||||
/// A boolean field of [serverInstallation] box.
|
||||
static String isServerResetedSecondTime = 'isServerResetedSecondTime';
|
||||
static String sshConfig = 'sshConfig';
|
||||
static String sshPrivateKey = "sshPrivateKey";
|
||||
static String sshPublicKey = "sshPublicKey";
|
||||
|
||||
/// Deprecated users box as it is unencrypted
|
||||
static String usersDeprecated = 'users';
|
||||
|
||||
/// Box with users
|
||||
static String users = 'usersEncrypted';
|
||||
}
|
||||
|
|
|
@ -10,11 +10,12 @@ part 'authentication_dependend_state.dart';
|
|||
abstract class ServerInstallationDependendCubit<
|
||||
T extends ServerInstallationDependendState> extends Cubit<T> {
|
||||
ServerInstallationDependendCubit(
|
||||
this.appConfigCubit,
|
||||
this.serverInstallationCubit,
|
||||
T initState,
|
||||
) : super(initState) {
|
||||
authCubitSubscription = appConfigCubit.stream.listen(checkAuthStatus);
|
||||
checkAuthStatus(appConfigCubit.state);
|
||||
authCubitSubscription =
|
||||
serverInstallationCubit.stream.listen(checkAuthStatus);
|
||||
checkAuthStatus(serverInstallationCubit.state);
|
||||
}
|
||||
|
||||
void checkAuthStatus(ServerInstallationState state) {
|
||||
|
@ -26,7 +27,7 @@ abstract class ServerInstallationDependendCubit<
|
|||
}
|
||||
|
||||
late StreamSubscription authCubitSubscription;
|
||||
final ServerInstallationCubit appConfigCubit;
|
||||
final ServerInstallationCubit serverInstallationCubit;
|
||||
|
||||
void load();
|
||||
void clear();
|
||||
|
|
|
@ -9,22 +9,22 @@ part 'app_settings_state.dart';
|
|||
class AppSettingsCubit extends Cubit<AppSettingsState> {
|
||||
AppSettingsCubit({
|
||||
required bool isDarkModeOn,
|
||||
required bool isOnbordingShowing,
|
||||
required bool isOnboardingShowing,
|
||||
}) : super(
|
||||
AppSettingsState(
|
||||
isDarkModeOn: isDarkModeOn,
|
||||
isOnbordingShowing: isOnbordingShowing,
|
||||
isOnboardingShowing: isOnboardingShowing,
|
||||
),
|
||||
);
|
||||
|
||||
Box box = Hive.box(BNames.appSettings);
|
||||
Box box = Hive.box(BNames.appSettingsBox);
|
||||
|
||||
void load() {
|
||||
bool? isDarkModeOn = box.get(BNames.isDarkModeOn);
|
||||
bool? isOnbordingShowing = box.get(BNames.isOnbordingShowing);
|
||||
bool? isOnboardingShowing = box.get(BNames.isOnboardingShowing);
|
||||
emit(state.copyWith(
|
||||
isDarkModeOn: isDarkModeOn,
|
||||
isOnbordingShowing: isOnbordingShowing,
|
||||
isOnboardingShowing: isOnboardingShowing,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,8 @@ class AppSettingsCubit extends Cubit<AppSettingsState> {
|
|||
}
|
||||
|
||||
void turnOffOnboarding() {
|
||||
box.put(BNames.isOnbordingShowing, false);
|
||||
box.put(BNames.isOnboardingShowing, false);
|
||||
|
||||
emit(state.copyWith(isOnbordingShowing: false));
|
||||
emit(state.copyWith(isOnboardingShowing: false));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,18 +3,18 @@ part of 'app_settings_cubit.dart';
|
|||
class AppSettingsState extends Equatable {
|
||||
const AppSettingsState({
|
||||
required this.isDarkModeOn,
|
||||
required this.isOnbordingShowing,
|
||||
required this.isOnboardingShowing,
|
||||
});
|
||||
|
||||
final bool isDarkModeOn;
|
||||
final bool isOnbordingShowing;
|
||||
final bool isOnboardingShowing;
|
||||
|
||||
AppSettingsState copyWith({isDarkModeOn, isOnbordingShowing}) =>
|
||||
AppSettingsState copyWith({isDarkModeOn, isOnboardingShowing}) =>
|
||||
AppSettingsState(
|
||||
isDarkModeOn: isDarkModeOn ?? this.isDarkModeOn,
|
||||
isOnbordingShowing: isOnbordingShowing ?? this.isOnbordingShowing,
|
||||
isOnboardingShowing: isOnboardingShowing ?? this.isOnboardingShowing,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object> get props => [isDarkModeOn, isOnbordingShowing];
|
||||
List<Object> get props => [isDarkModeOn, isOnboardingShowing];
|
||||
}
|
||||
|
|
|
@ -11,14 +11,14 @@ import 'package:selfprivacy/logic/models/json/backup.dart';
|
|||
part 'backups_state.dart';
|
||||
|
||||
class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||
BackupsCubit(ServerInstallationCubit appConfigCubit)
|
||||
: super(appConfigCubit, BackupsState(preventActions: true));
|
||||
BackupsCubit(ServerInstallationCubit serverInstallationCubit)
|
||||
: super(serverInstallationCubit, BackupsState(preventActions: true));
|
||||
|
||||
final api = ServerApi();
|
||||
final backblaze = BackblazeApi();
|
||||
|
||||
Future<void> load() async {
|
||||
if (appConfigCubit.state is ServerInstallationFinished) {
|
||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||
final bucket = getIt<ApiConfigModel>().backblazeBucket;
|
||||
if (bucket == null) {
|
||||
emit(BackupsState(
|
||||
|
@ -85,9 +85,9 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
|||
|
||||
Future<void> createBucket() async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
final domain = appConfigCubit.state.serverDomain!.domainName
|
||||
final domain = serverInstallationCubit.state.serverDomain!.domainName
|
||||
.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '-');
|
||||
final serverId = appConfigCubit.state.serverDetails!.id;
|
||||
final serverId = serverInstallationCubit.state.serverDetails!.id;
|
||||
var bucketName = 'selfprivacy-$domain-$serverId';
|
||||
// If bucket name is too long, shorten it
|
||||
if (bucketName.length > 49) {
|
||||
|
|
|
@ -10,8 +10,8 @@ part 'dns_records_state.dart';
|
|||
|
||||
class DnsRecordsCubit
|
||||
extends ServerInstallationDependendCubit<DnsRecordsState> {
|
||||
DnsRecordsCubit(ServerInstallationCubit appConfigCubit)
|
||||
: super(appConfigCubit,
|
||||
DnsRecordsCubit(ServerInstallationCubit serverInstallationCubit)
|
||||
: super(serverInstallationCubit,
|
||||
DnsRecordsState(dnsState: DnsRecordsStatus.refreshing));
|
||||
|
||||
final api = ServerApi();
|
||||
|
@ -21,11 +21,12 @@ class DnsRecordsCubit
|
|||
emit(DnsRecordsState(
|
||||
dnsState: DnsRecordsStatus.refreshing,
|
||||
dnsRecords: _getDesiredDnsRecords(
|
||||
appConfigCubit.state.serverDomain?.domainName, "", "")));
|
||||
serverInstallationCubit.state.serverDomain?.domainName, "", "")));
|
||||
print('Loading DNS status');
|
||||
if (appConfigCubit.state is ServerInstallationFinished) {
|
||||
final ServerDomain? domain = appConfigCubit.state.serverDomain;
|
||||
final String? ipAddress = appConfigCubit.state.serverDetails?.ip4;
|
||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||
final ServerDomain? domain = serverInstallationCubit.state.serverDomain;
|
||||
final String? ipAddress =
|
||||
serverInstallationCubit.state.serverDetails?.ip4;
|
||||
if (domain != null && ipAddress != null) {
|
||||
final List<DnsRecord> records =
|
||||
await cloudflare.getDnsRecords(cloudFlareDomain: domain);
|
||||
|
@ -96,8 +97,8 @@ class DnsRecordsCubit
|
|||
|
||||
Future<void> fix() async {
|
||||
emit(state.copyWith(dnsState: DnsRecordsStatus.refreshing));
|
||||
final ServerDomain? domain = appConfigCubit.state.serverDomain;
|
||||
final String? ipAddress = appConfigCubit.state.serverDetails?.ip4;
|
||||
final ServerDomain? domain = serverInstallationCubit.state.serverDomain;
|
||||
final String? ipAddress = serverInstallationCubit.state.serverDetails?.ip4;
|
||||
final String? dkimPublicKey = await api.getDkim();
|
||||
await cloudflare.removeSimilarRecords(cloudFlareDomain: domain!);
|
||||
await cloudflare.createMultipleDnsRecords(
|
||||
|
|
|
@ -2,8 +2,6 @@ import 'dart:async';
|
|||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/get_it/ssh.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
|
@ -18,7 +16,7 @@ part '../server_installation/server_installation_state.dart';
|
|||
class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||
ServerInstallationCubit() : super(ServerInstallationEmpty());
|
||||
|
||||
final repository = AppConfigRepository();
|
||||
final repository = ServerInstallationRepository();
|
||||
|
||||
Timer? timer;
|
||||
|
||||
|
@ -266,7 +264,6 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
|
||||
if (state.serverDetails != null) {
|
||||
await repository.deleteServer(state.serverDomain!);
|
||||
await getIt<SSHModel>().clear();
|
||||
}
|
||||
await repository.deleteRecords();
|
||||
emit(ServerInstallationNotFinished(
|
||||
|
|
|
@ -17,8 +17,8 @@ import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart';
|
|||
|
||||
import '../server_installation/server_installation_cubit.dart';
|
||||
|
||||
class AppConfigRepository {
|
||||
Box box = Hive.box(BNames.appConfig);
|
||||
class ServerInstallationRepository {
|
||||
Box box = Hive.box(BNames.serverInstallation);
|
||||
|
||||
Future<ServerInstallationState> load() async {
|
||||
final hetznerToken = getIt<ApiConfigModel>().hetznerKey;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:selfprivacy/config/hive_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/server.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||
|
@ -7,13 +5,11 @@ import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_depe
|
|||
part 'services_state.dart';
|
||||
|
||||
class ServicesCubit extends ServerInstallationDependendCubit<ServicesState> {
|
||||
ServicesCubit(ServerInstallationCubit appConfigCubit)
|
||||
: super(appConfigCubit, ServicesState.allOff());
|
||||
|
||||
Box box = Hive.box(BNames.servicesState);
|
||||
ServicesCubit(ServerInstallationCubit serverInstallationCubit)
|
||||
: super(serverInstallationCubit, ServicesState.allOff());
|
||||
final api = ServerApi();
|
||||
Future<void> load() async {
|
||||
if (appConfigCubit.state is ServerInstallationFinished) {
|
||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||
var statuses = await api.servicesPowerCheck();
|
||||
emit(
|
||||
ServicesState(
|
||||
|
@ -29,7 +25,6 @@ class ServicesCubit extends ServerInstallationDependendCubit<ServicesState> {
|
|||
|
||||
@override
|
||||
void clear() async {
|
||||
box.clear();
|
||||
emit(ServicesState.allOff());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:selfprivacy/config/hive_config.dart';
|
||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||
|
@ -11,23 +10,23 @@ export 'package:provider/provider.dart';
|
|||
part 'users_state.dart';
|
||||
|
||||
class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||
UsersCubit(ServerInstallationCubit appConfigCubit)
|
||||
UsersCubit(ServerInstallationCubit serverInstallationCubit)
|
||||
: super(
|
||||
appConfigCubit,
|
||||
serverInstallationCubit,
|
||||
UsersState(
|
||||
<User>[], User(login: 'root'), User(login: 'loading...')));
|
||||
Box<User> box = Hive.box<User>(BNames.users);
|
||||
Box configBox = Hive.box(BNames.appConfig);
|
||||
Box serverInstallationBox = Hive.box(BNames.serverInstallation);
|
||||
|
||||
final api = ServerApi();
|
||||
|
||||
Future<void> load() async {
|
||||
if (appConfigCubit.state is ServerInstallationFinished) {
|
||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||
var loadedUsers = box.values.toList();
|
||||
final primaryUser = configBox.get(BNames.rootUser,
|
||||
final primaryUser = serverInstallationBox.get(BNames.rootUser,
|
||||
defaultValue: User(login: 'loading...'));
|
||||
List<String> rootKeys = [
|
||||
...configBox.get(BNames.rootKeys, defaultValue: [])
|
||||
...serverInstallationBox.get(BNames.rootKeys, defaultValue: [])
|
||||
];
|
||||
if (loadedUsers.isNotEmpty) {
|
||||
emit(UsersState(
|
||||
|
@ -48,10 +47,10 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
box.addAll(usersWithSshKeys);
|
||||
|
||||
final rootUserWithSshKeys = (await loadSshKeys([state.rootUser])).first;
|
||||
configBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys);
|
||||
serverInstallationBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys);
|
||||
final primaryUserWithSshKeys =
|
||||
(await loadSshKeys([state.primaryUser])).first;
|
||||
configBox.put(BNames.rootUser, primaryUserWithSshKeys);
|
||||
serverInstallationBox.put(BNames.rootUser, primaryUserWithSshKeys);
|
||||
emit(UsersState(
|
||||
usersWithSshKeys, rootUserWithSshKeys, primaryUserWithSshKeys));
|
||||
}
|
||||
|
@ -142,10 +141,10 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
box.clear();
|
||||
box.addAll(usersWithSshKeys);
|
||||
final rootUserWithSshKeys = (await loadSshKeys([state.rootUser])).first;
|
||||
configBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys);
|
||||
serverInstallationBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys);
|
||||
final primaryUserWithSshKeys =
|
||||
(await loadSshKeys([state.primaryUser])).first;
|
||||
configBox.put(BNames.rootUser, primaryUserWithSshKeys);
|
||||
serverInstallationBox.put(BNames.rootUser, primaryUserWithSshKeys);
|
||||
emit(UsersState(
|
||||
usersWithSshKeys, rootUserWithSshKeys, primaryUserWithSshKeys));
|
||||
return;
|
||||
|
@ -195,10 +194,10 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
final result = await api.addRootSshKey(publicKey);
|
||||
if (result.isSuccess) {
|
||||
// Add ssh key to the array of root keys
|
||||
final rootKeys =
|
||||
configBox.get(BNames.rootKeys, defaultValue: []) as List<String>;
|
||||
final rootKeys = serverInstallationBox
|
||||
.get(BNames.rootKeys, defaultValue: []) as List<String>;
|
||||
rootKeys.add(publicKey);
|
||||
configBox.put(BNames.rootKeys, rootKeys);
|
||||
serverInstallationBox.put(BNames.rootKeys, rootKeys);
|
||||
emit(state.copyWith(
|
||||
rootUser: User(
|
||||
login: state.rootUser.login,
|
||||
|
@ -224,7 +223,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
sshKeys: primaryUserKeys,
|
||||
note: state.primaryUser.note,
|
||||
);
|
||||
configBox.put(BNames.rootUser, updatedUser);
|
||||
serverInstallationBox.put(BNames.rootUser, updatedUser);
|
||||
emit(state.copyWith(
|
||||
primaryUser: updatedUser,
|
||||
));
|
||||
|
@ -258,10 +257,10 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
// If it is not primary user, update user
|
||||
|
||||
if (user.login == 'root') {
|
||||
final rootKeys =
|
||||
configBox.get(BNames.rootKeys, defaultValue: []) as List<String>;
|
||||
final rootKeys = serverInstallationBox
|
||||
.get(BNames.rootKeys, defaultValue: []) as List<String>;
|
||||
rootKeys.remove(publicKey);
|
||||
configBox.put(BNames.rootKeys, rootKeys);
|
||||
serverInstallationBox.put(BNames.rootKeys, rootKeys);
|
||||
emit(state.copyWith(
|
||||
rootUser: User(
|
||||
login: state.rootUser.login,
|
||||
|
@ -284,7 +283,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
sshKeys: primaryUserKeys,
|
||||
note: state.primaryUser.note,
|
||||
);
|
||||
configBox.put(BNames.rootUser, updatedUser);
|
||||
serverInstallationBox.put(BNames.rootUser, updatedUser);
|
||||
emit(state.copyWith(
|
||||
primaryUser: updatedUser,
|
||||
));
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
|||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
|
||||
class ApiConfigModel {
|
||||
Box _box = Hive.box(BNames.appConfig);
|
||||
Box _box = Hive.box(BNames.serverInstallation);
|
||||
|
||||
ServerHostingDetails? get serverDetails => _serverDetails;
|
||||
String? get hetznerKey => _hetznerKey;
|
||||
|
@ -33,7 +33,7 @@ class ApiConfigModel {
|
|||
}
|
||||
|
||||
Future<void> storeBackblazeCredential(BackblazeCredential value) async {
|
||||
await _box.put(BNames.backblazeKey, value);
|
||||
await _box.put(BNames.backblazeCredential, value);
|
||||
|
||||
_backblazeCredential = value;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class ApiConfigModel {
|
|||
_hetznerKey = _box.get(BNames.hetznerKey);
|
||||
|
||||
_cloudFlareKey = _box.get(BNames.cloudFlareKey);
|
||||
_backblazeCredential = _box.get(BNames.backblazeKey);
|
||||
_backblazeCredential = _box.get(BNames.backblazeCredential);
|
||||
_serverDomain = _box.get(BNames.serverDomain);
|
||||
_serverDetails = _box.get(BNames.serverDetails);
|
||||
_backblazeBucket = _box.get(BNames.backblazeBucket);
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:pointycastle/pointycastle.dart';
|
||||
import 'package:rsa_encrypt/rsa_encrypt.dart';
|
||||
import 'package:selfprivacy/config/hive_config.dart';
|
||||
import 'package:pointycastle/api.dart' as crypto;
|
||||
import 'package:ssh_key/ssh_key.dart' as ssh_key;
|
||||
|
||||
class SSHModel {
|
||||
Box _box = Hive.box(BNames.sshConfig);
|
||||
String? savedPrivateKey;
|
||||
String? savedPubKey;
|
||||
|
||||
Future<void> generateKeys() async {
|
||||
var helper = RsaKeyHelper();
|
||||
crypto.AsymmetricKeyPair pair =
|
||||
await helper.computeRSAKeyPair(helper.getSecureRandom());
|
||||
var privateKey = pair.privateKey as RSAPrivateKey;
|
||||
var publicKey = pair.publicKey as RSAPublicKey;
|
||||
|
||||
savedPrivateKey = helper.encodePrivateKeyToPemPKCS1(privateKey);
|
||||
savedPubKey = publicKey.encode(ssh_key.PubKeyEncoding.openSsh);
|
||||
|
||||
await _box.put(BNames.sshPrivateKey, savedPrivateKey);
|
||||
await _box.put(BNames.sshPublicKey, savedPubKey);
|
||||
}
|
||||
|
||||
void init() async {
|
||||
savedPrivateKey = _box.get(BNames.sshPrivateKey);
|
||||
savedPubKey = _box.get(BNames.sshPublicKey);
|
||||
}
|
||||
|
||||
bool get isSSHKeyGenerated => savedPrivateKey != null && savedPubKey != null;
|
||||
|
||||
Future<void> clear() async {
|
||||
savedPrivateKey = null;
|
||||
savedPubKey = null;
|
||||
await _box.clear();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'api_token.g.dart';
|
||||
|
|
|
@ -83,7 +83,7 @@ class MyApp extends StatelessWidget {
|
|||
darkTheme: darkThemeData,
|
||||
themeMode:
|
||||
appSettings.isDarkModeOn ? ThemeMode.dark : ThemeMode.light,
|
||||
home: appSettings.isOnbordingShowing
|
||||
home: appSettings.isOnboardingShowing
|
||||
? OnboardingPage(nextPage: InitializingPage())
|
||||
: RootPage(),
|
||||
builder: (BuildContext context, Widget? widget) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:flutter/services.dart' show rootBundle;
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:selfprivacy/config/brand_colors.dart';
|
||||
import 'package:selfprivacy/config/text_themes.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class BrandMarkdown extends StatefulWidget {
|
||||
const BrandMarkdown({
|
||||
|
@ -60,9 +60,9 @@ class _BrandMarkdownState extends State<BrandMarkdown> {
|
|||
styleSheet: markdown,
|
||||
onTapLink: (String text, String? href, String title) {
|
||||
if (href != null) {
|
||||
canLaunch(href).then((canLaunchURL) {
|
||||
canLaunchUrlString(href).then((canLaunchURL) {
|
||||
if (canLaunchURL) {
|
||||
launch(href);
|
||||
launchUrlString(href);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ class BrandSpanButton extends TextSpan {
|
|||
);
|
||||
|
||||
static _launchURL(String link) async {
|
||||
if (await canLaunch(link)) {
|
||||
await launch(link);
|
||||
if (await canLaunchUrl(Uri.parse(link))) {
|
||||
await launchUrl(Uri.parse(link));
|
||||
} else {
|
||||
throw 'Could not launch $link';
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import 'package:selfprivacy/ui/components/icon_status_mask/icon_status_mask.dart
|
|||
import 'package:selfprivacy/ui/components/not_ready_card/not_ready_card.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:selfprivacy/utils/ui_helpers.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
import '../rootRoute.dart';
|
||||
|
||||
|
@ -39,13 +39,12 @@ class ServicesPage extends StatefulWidget {
|
|||
}
|
||||
|
||||
void _launchURL(url) async {
|
||||
var _possible = await canLaunch(url);
|
||||
var _possible = await canLaunchUrlString(url);
|
||||
|
||||
if (_possible) {
|
||||
try {
|
||||
await launch(
|
||||
await launchUrlString(
|
||||
url,
|
||||
enableJavaScript: true,
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
|
@ -151,11 +150,9 @@ class _Card extends StatelessWidget {
|
|||
builder: (context) {
|
||||
late bool isActive;
|
||||
if (hasSwitchJob) {
|
||||
isActive = ((jobState as JobsStateWithJobs)
|
||||
.jobList
|
||||
.firstWhere((el) =>
|
||||
el is ServiceToggleJob &&
|
||||
el.type == serviceType) as ServiceToggleJob)
|
||||
isActive = ((jobState).jobList.firstWhere((el) =>
|
||||
el is ServiceToggleJob &&
|
||||
el.type == serviceType) as ServiceToggleJob)
|
||||
.needToTurnOn;
|
||||
} else {
|
||||
isActive = serviceState.isEnableByType(serviceType);
|
||||
|
|
|
@ -10,11 +10,11 @@ import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.da
|
|||
class RecoveryDomain extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var appConfig = context.watch<ServerInstallationCubit>();
|
||||
var serverInstallation = context.watch<ServerInstallationCubit>();
|
||||
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
RecoveryDomainFormCubit(appConfig, FieldCubitFactory(context)),
|
||||
create: (context) => RecoveryDomainFormCubit(
|
||||
serverInstallation, FieldCubitFactory(context)),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
var formCubitState = context.watch<RecoveryDomainFormCubit>().state;
|
||||
|
|
|
@ -715,7 +715,7 @@ packages:
|
|||
source: hosted
|
||||
version: "2.1.2"
|
||||
pointycastle:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -770,13 +770,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
rsa_encrypt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: rsa_encrypt
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -34,10 +34,8 @@ dependencies:
|
|||
modal_bottom_sheet: ^2.0.1
|
||||
nanoid: ^1.0.0
|
||||
package_info: ^2.0.2
|
||||
pointycastle: ^3.5.1
|
||||
pretty_dio_logger: ^1.2.0-beta-1
|
||||
provider: ^6.0.2
|
||||
rsa_encrypt: ^2.0.0
|
||||
share_plus: ^4.0.4
|
||||
ssh_key: ^0.7.1
|
||||
system_theme: ^2.0.0
|
||||
|
|
Loading…
Reference in a new issue