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

This commit is contained in:
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 # Obfuscation related
app.*.map.json app.*.map.json
# Flatpak
.flatpak-builder/
flatpak-build/
flatpak-repo/
*.flatpak

View file

@ -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:

View file

@ -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,6 +28,7 @@ class HiveConfig {
await Hive.openBox(BNames.appSettingsBox); await Hive.openBox(BNames.appSettingsBox);
try {
final HiveAesCipher cipher = HiveAesCipher( final HiveAesCipher cipher = HiveAesCipher(
await getEncryptedKey(BNames.serverInstallationEncryptionKey), await getEncryptedKey(BNames.serverInstallationEncryptionKey),
); );
@ -42,12 +43,21 @@ class HiveConfig {
await deprecatedUsers.clear(); await deprecatedUsers.clear();
} }
await Hive.openBox(BNames.serverInstallationBox, encryptionCipher: cipher); await Hive.openBox(
BNames.serverInstallationBox,
encryptionCipher: cipher,
);
} on PlatformException catch (e) {
print('HiveConfig: Error while opening boxes: $e');
rethrow;
}
} }
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 {
final bool hasEncryptionKey =
await secureStorage.containsKey(key: encKey);
if (!hasEncryptionKey) { if (!hasEncryptionKey) {
final List<int> key = Hive.generateSecureKey(); final List<int> key = Hive.generateSecureKey();
await secureStorage.write(key: encKey, value: base64UrlEncode(key)); await secureStorage.write(key: encKey, value: base64UrlEncode(key));
@ -55,6 +65,10 @@ class HiveConfig {
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;
}
} }
} }

View file

@ -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,6 +26,7 @@ void main() async {
// print(e); // print(e);
// } // }
try {
await Future.wait( await Future.wait(
<Future<void>>[ <Future<void>>[
HiveConfig.init(), HiveConfig.init(),
@ -31,6 +34,11 @@ void main() async {
], ],
); );
await getItSetup(); await getItSetup();
} on PlatformException catch (e) {
runApp(
FailedToInitSecureStorageScreen(e: e),
);
}
tz.initializeTimeZones(); tz.initializeTimeZones();

View file

@ -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,

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