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,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;
}
} }
} }

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,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();

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