mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-09 18:33:11 +00:00
Merge remote-tracking branch 'sp/master' into feat_token_management
This commit is contained in:
commit
a7ed0d20b2
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -40,3 +40,9 @@ app.*.symbols
|
||||||
|
|
||||||
# Obfuscation related
|
# Obfuscation related
|
||||||
app.*.map.json
|
app.*.map.json
|
||||||
|
|
||||||
|
# Flatpak
|
||||||
|
.flatpak-builder/
|
||||||
|
flatpak-build/
|
||||||
|
flatpak-repo/
|
||||||
|
*.flatpak
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
app-id: org.selfprivacy.app
|
app-id: org.selfprivacy.app
|
||||||
runtime: org.freedesktop.Platform
|
runtime: org.freedesktop.Platform
|
||||||
runtime-version: '22.08'
|
runtime-version: '23.08'
|
||||||
sdk: org.freedesktop.Sdk
|
sdk: org.freedesktop.Sdk
|
||||||
command: selfprivacy
|
command: selfprivacy
|
||||||
finish-args:
|
finish-args:
|
||||||
|
@ -11,6 +11,7 @@ finish-args:
|
||||||
- "--share=network"
|
- "--share=network"
|
||||||
- "--own-name=org.selfprivacy.app"
|
- "--own-name=org.selfprivacy.app"
|
||||||
- "--device=dri"
|
- "--device=dri"
|
||||||
|
- "--talk-name=org.freedesktop.secrets"
|
||||||
modules:
|
modules:
|
||||||
- name: selfprivacy
|
- name: selfprivacy
|
||||||
buildsystem: simple
|
buildsystem: simple
|
||||||
|
@ -35,7 +36,7 @@ modules:
|
||||||
sources:
|
sources:
|
||||||
- type: git
|
- type: git
|
||||||
url: https://gitlab.gnome.org/GNOME/libsecret.git
|
url: https://gitlab.gnome.org/GNOME/libsecret.git
|
||||||
tag: 0.20.5
|
tag: 0.21.4
|
||||||
- name: libjsoncpp
|
- name: libjsoncpp
|
||||||
buildsystem: meson
|
buildsystem: meson
|
||||||
config-opts:
|
config-opts:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||||
|
@ -28,33 +28,47 @@ class HiveConfig {
|
||||||
|
|
||||||
await Hive.openBox(BNames.appSettingsBox);
|
await Hive.openBox(BNames.appSettingsBox);
|
||||||
|
|
||||||
final HiveAesCipher cipher = HiveAesCipher(
|
try {
|
||||||
await getEncryptedKey(BNames.serverInstallationEncryptionKey),
|
final HiveAesCipher cipher = HiveAesCipher(
|
||||||
);
|
await getEncryptedKey(BNames.serverInstallationEncryptionKey),
|
||||||
|
);
|
||||||
|
|
||||||
await Hive.openBox<User>(BNames.usersDeprecated);
|
await Hive.openBox<User>(BNames.usersDeprecated);
|
||||||
await Hive.openBox<User>(BNames.usersBox, encryptionCipher: cipher);
|
await Hive.openBox<User>(BNames.usersBox, encryptionCipher: cipher);
|
||||||
|
|
||||||
final Box<User> deprecatedUsers = Hive.box<User>(BNames.usersDeprecated);
|
final Box<User> deprecatedUsers = Hive.box<User>(BNames.usersDeprecated);
|
||||||
if (deprecatedUsers.isNotEmpty) {
|
if (deprecatedUsers.isNotEmpty) {
|
||||||
final Box<User> users = Hive.box<User>(BNames.usersBox);
|
final Box<User> users = Hive.box<User>(BNames.usersBox);
|
||||||
await users.addAll(deprecatedUsers.values.toList());
|
await users.addAll(deprecatedUsers.values.toList());
|
||||||
await deprecatedUsers.clear();
|
await deprecatedUsers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
await Hive.openBox(
|
||||||
|
BNames.serverInstallationBox,
|
||||||
|
encryptionCipher: cipher,
|
||||||
|
);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
print('HiveConfig: Error while opening boxes: $e');
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Hive.openBox(BNames.serverInstallationBox, encryptionCipher: cipher);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Uint8List> getEncryptedKey(final String encKey) async {
|
static Future<Uint8List> getEncryptedKey(final String encKey) async {
|
||||||
const FlutterSecureStorage secureStorage = FlutterSecureStorage();
|
const FlutterSecureStorage secureStorage = FlutterSecureStorage();
|
||||||
final bool hasEncryptionKey = await secureStorage.containsKey(key: encKey);
|
try {
|
||||||
if (!hasEncryptionKey) {
|
final bool hasEncryptionKey =
|
||||||
final List<int> key = Hive.generateSecureKey();
|
await secureStorage.containsKey(key: encKey);
|
||||||
await secureStorage.write(key: encKey, value: base64UrlEncode(key));
|
if (!hasEncryptionKey) {
|
||||||
}
|
final List<int> key = Hive.generateSecureKey();
|
||||||
|
await secureStorage.write(key: encKey, value: base64UrlEncode(key));
|
||||||
|
}
|
||||||
|
|
||||||
final String? string = await secureStorage.read(key: encKey);
|
final String? string = await secureStorage.read(key: encKey);
|
||||||
return base64Url.decode(string!);
|
return base64Url.decode(string!);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
print('HiveConfig: Error while getting encryption key: $e');
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:selfprivacy/config/app_controller/inherited_app_controller.dart';
|
import 'package:selfprivacy/config/app_controller/inherited_app_controller.dart';
|
||||||
import 'package:selfprivacy/config/bloc_config.dart';
|
import 'package:selfprivacy/config/bloc_config.dart';
|
||||||
|
@ -10,6 +11,7 @@ import 'package:selfprivacy/config/hive_config.dart';
|
||||||
import 'package:selfprivacy/config/localization.dart';
|
import 'package:selfprivacy/config/localization.dart';
|
||||||
import 'package:selfprivacy/config/preferences_repository/datasources/preferences_hive_datasource.dart';
|
import 'package:selfprivacy/config/preferences_repository/datasources/preferences_hive_datasource.dart';
|
||||||
import 'package:selfprivacy/config/preferences_repository/inherited_preferences_repository.dart';
|
import 'package:selfprivacy/config/preferences_repository/inherited_preferences_repository.dart';
|
||||||
|
import 'package:selfprivacy/ui/pages/errors/failed_to_init_secure_storage.dart';
|
||||||
import 'package:selfprivacy/ui/router/router.dart';
|
import 'package:selfprivacy/ui/router/router.dart';
|
||||||
import 'package:timezone/data/latest.dart' as tz;
|
import 'package:timezone/data/latest.dart' as tz;
|
||||||
|
|
||||||
|
@ -24,13 +26,19 @@ void main() async {
|
||||||
// print(e);
|
// print(e);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
await Future.wait(
|
try {
|
||||||
<Future<void>>[
|
await Future.wait(
|
||||||
HiveConfig.init(),
|
<Future<void>>[
|
||||||
EasyLocalization.ensureInitialized(),
|
HiveConfig.init(),
|
||||||
],
|
EasyLocalization.ensureInitialized(),
|
||||||
);
|
],
|
||||||
await getItSetup();
|
);
|
||||||
|
await getItSetup();
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
runApp(
|
||||||
|
FailedToInitSecureStorageScreen(e: e),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
tz.initializeTimeZones();
|
tz.initializeTimeZones();
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,9 @@ class _HeroSliverAppBarState extends State<HeroSliverAppBar> {
|
||||||
Widget build(final BuildContext context) {
|
Widget build(final BuildContext context) {
|
||||||
final isMobile =
|
final isMobile =
|
||||||
widget.ignoreBreakpoints ? true : Breakpoints.small.isActive(context);
|
widget.ignoreBreakpoints ? true : Breakpoints.small.isActive(context);
|
||||||
final isJobsListEmpty = context.watch<JobsCubit>().state is JobsStateEmpty;
|
final isJobsListEmpty = widget.hasFlashButton
|
||||||
|
? context.watch<JobsCubit>().state is JobsStateEmpty
|
||||||
|
: true;
|
||||||
return SliverAppBar(
|
return SliverAppBar(
|
||||||
expandedHeight:
|
expandedHeight:
|
||||||
widget.hasHeroIcon ? 148.0 + _size.height : 72.0 + _size.height,
|
widget.hasHeroIcon ? 148.0 + _size.height : 72.0 + _size.height,
|
||||||
|
|
71
lib/ui/pages/errors/failed_to_init_secure_storage.dart
Normal file
71
lib/ui/pages/errors/failed_to_init_secure_storage.dart
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||||
|
import 'package:selfprivacy/ui/pages/more/about_application.dart';
|
||||||
|
|
||||||
|
class FailedToInitSecureStorageScreen extends StatelessWidget {
|
||||||
|
const FailedToInitSecureStorageScreen({
|
||||||
|
required this.e,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final PlatformException e;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => MaterialApp(
|
||||||
|
home: BrandHeroScreen(
|
||||||
|
heroIcon: Icons.error_outline,
|
||||||
|
heroTitle: 'Failed to initialize secure storage',
|
||||||
|
hasBackButton: false,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'SelfPrivacy requires a secure storage provided by your operating system to encrypt sensitive data, but it failed to initialize.',
|
||||||
|
),
|
||||||
|
if (Platform.isLinux)
|
||||||
|
const Text(
|
||||||
|
'Please make sure that the libsecret library is installed.',
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
Text('Error: ${e.message}'),
|
||||||
|
const Gap(16),
|
||||||
|
const Divider(),
|
||||||
|
const Gap(16),
|
||||||
|
const LinkListTile(
|
||||||
|
title: 'Our website',
|
||||||
|
subtitle: 'selfprivacy.org',
|
||||||
|
uri: 'https://selfprivacy.org/',
|
||||||
|
icon: Icons.language_outlined,
|
||||||
|
),
|
||||||
|
const LinkListTile(
|
||||||
|
title: 'Documentation',
|
||||||
|
subtitle: 'selfprivacy.org/docs',
|
||||||
|
uri: 'https://selfprivacy.org/docs/',
|
||||||
|
icon: Icons.library_books_outlined,
|
||||||
|
),
|
||||||
|
const LinkListTile(
|
||||||
|
title: 'Privacy Policy',
|
||||||
|
subtitle: 'selfprivacy.org/privacy-policy',
|
||||||
|
uri: 'https://selfprivacy.org/privacy-policy/',
|
||||||
|
icon: Icons.policy_outlined,
|
||||||
|
),
|
||||||
|
const LinkListTile(
|
||||||
|
title: 'Matrix support chat',
|
||||||
|
subtitle: '#chat:selfprivacy.org',
|
||||||
|
uri: 'https://matrix.to/#/#chat:selfprivacy.org',
|
||||||
|
icon: Icons.question_answer_outlined,
|
||||||
|
longPressText: '#chat:selfprivacy.org',
|
||||||
|
),
|
||||||
|
const LinkListTile(
|
||||||
|
title: 'Telegram support chat',
|
||||||
|
subtitle: '@selfprivacy_chat',
|
||||||
|
uri: 'https://t.me/selfprivacy_chat',
|
||||||
|
icon: Icons.question_answer_outlined,
|
||||||
|
longPressText: '@selfprivacy_chat',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in a new issue