Merge remote-tracking branch 'sp/master' into feat_token_management

pull/482/head
Aliaksei Tratseuski 2024-05-15 20:12:13 +04:00
commit a7ed0d20b2
6 changed files with 132 additions and 30 deletions

6
.gitignore vendored
View File

@ -40,3 +40,9 @@ app.*.symbols
# Obfuscation related
app.*.map.json
# Flatpak
.flatpak-builder/
flatpak-build/
flatpak-repo/
*.flatpak

View File

@ -1,6 +1,6 @@
app-id: org.selfprivacy.app
runtime: org.freedesktop.Platform
runtime-version: '22.08'
runtime-version: '23.08'
sdk: org.freedesktop.Sdk
command: selfprivacy
finish-args:
@ -11,6 +11,7 @@ finish-args:
- "--share=network"
- "--own-name=org.selfprivacy.app"
- "--device=dri"
- "--talk-name=org.freedesktop.secrets"
modules:
- name: selfprivacy
buildsystem: simple
@ -35,7 +36,7 @@ modules:
sources:
- type: git
url: https://gitlab.gnome.org/GNOME/libsecret.git
tag: 0.20.5
tag: 0.21.4
- name: libjsoncpp
buildsystem: meson
config-opts:

View File

@ -1,6 +1,6 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
@ -28,33 +28,47 @@ class HiveConfig {
await Hive.openBox(BNames.appSettingsBox);
final HiveAesCipher cipher = HiveAesCipher(
await getEncryptedKey(BNames.serverInstallationEncryptionKey),
);
try {
final HiveAesCipher cipher = HiveAesCipher(
await getEncryptedKey(BNames.serverInstallationEncryptionKey),
);
await Hive.openBox<User>(BNames.usersDeprecated);
await Hive.openBox<User>(BNames.usersBox, encryptionCipher: cipher);
await Hive.openBox<User>(BNames.usersDeprecated);
await Hive.openBox<User>(BNames.usersBox, encryptionCipher: cipher);
final Box<User> deprecatedUsers = Hive.box<User>(BNames.usersDeprecated);
if (deprecatedUsers.isNotEmpty) {
final Box<User> users = Hive.box<User>(BNames.usersBox);
await users.addAll(deprecatedUsers.values.toList());
await deprecatedUsers.clear();
final Box<User> deprecatedUsers = Hive.box<User>(BNames.usersDeprecated);
if (deprecatedUsers.isNotEmpty) {
final Box<User> users = Hive.box<User>(BNames.usersBox);
await users.addAll(deprecatedUsers.values.toList());
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 {
const FlutterSecureStorage secureStorage = FlutterSecureStorage();
final bool hasEncryptionKey = await secureStorage.containsKey(key: encKey);
if (!hasEncryptionKey) {
final List<int> key = Hive.generateSecureKey();
await secureStorage.write(key: encKey, value: base64UrlEncode(key));
}
try {
final bool hasEncryptionKey =
await secureStorage.containsKey(key: encKey);
if (!hasEncryptionKey) {
final List<int> key = Hive.generateSecureKey();
await secureStorage.write(key: encKey, value: base64UrlEncode(key));
}
final String? string = await secureStorage.read(key: encKey);
return base64Url.decode(string!);
final String? string = await secureStorage.read(key: encKey);
return base64Url.decode(string!);
} on PlatformException catch (e) {
print('HiveConfig: Error while getting encryption key: $e');
rethrow;
}
}
}

View File

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/config/app_controller/inherited_app_controller.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/preferences_repository/datasources/preferences_hive_datasource.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:timezone/data/latest.dart' as tz;
@ -24,13 +26,19 @@ void main() async {
// print(e);
// }
await Future.wait(
<Future<void>>[
HiveConfig.init(),
EasyLocalization.ensureInitialized(),
],
);
await getItSetup();
try {
await Future.wait(
<Future<void>>[
HiveConfig.init(),
EasyLocalization.ensureInitialized(),
],
);
await getItSetup();
} on PlatformException catch (e) {
runApp(
FailedToInitSecureStorageScreen(e: e),
);
}
tz.initializeTimeZones();

View File

@ -127,7 +127,9 @@ class _HeroSliverAppBarState extends State<HeroSliverAppBar> {
Widget build(final BuildContext context) {
final isMobile =
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(
expandedHeight:
widget.hasHeroIcon ? 148.0 + _size.height : 72.0 + _size.height,

View 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',
),
],
),
);
}