Skip to content

Commit

Permalink
Try to use biometric storage
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert-Stackflow committed Sep 6, 2024
1 parent 2d030cb commit fd645c5
Show file tree
Hide file tree
Showing 88 changed files with 4,508 additions and 519 deletions.
26 changes: 13 additions & 13 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,28 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.cloudchewie.cloudotp">

<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
</intent>
</queries>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEOS" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-sdk tools:overrideLibrary="dev.isar.isar_flutter_libs"/>

<uses-sdk tools:overrideLibrary="dev.isar.isar_flutter_libs" />
<application
android:name="${applicationName}"
android:allowBackup="false"
android:enableOnBackInvokedCallback="true"
android:extractNativeLibs="true"
android:fullBackupContent="false"
android:icon="@mipmap/ic_launcher"
android:label="CloudOTP"
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:enableOnBackInvokedCallback="true"
android:extractNativeLibs="true"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
Expand All @@ -50,8 +48,10 @@
android:exported="true">
<intent-filter android:label="flutter_web_auth_2">
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="cloudotp" />
<data android:scheme="com.cloudchewie.cloudotp" />
</intent-filter>
Expand Down
1 change: 1 addition & 0 deletions lib/Api/github_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import '../Utils/ilogger.dart';
class GithubApi {
static Future<List<ReleaseItem>> getReleases(String user, String repo) async {
try {
ILogger.info("Getting releases for $user/$repo");
final response =
await Dio().get("https://api.github.com/repos/$user/$repo/releases");
if (response.statusCode == 200) {
Expand Down
4 changes: 4 additions & 0 deletions lib/Database/database_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:cloudotp/Database/token_dao.dart';
import 'package:cloudotp/Models/opt_token.dart';
import 'package:cloudotp/Models/token_category.dart';
import 'package:cloudotp/Models/token_category_binding.dart';
import 'package:cloudotp/Utils/app_provider.dart';
import 'package:cloudotp/Utils/file_util.dart';
import 'package:path/path.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
Expand Down Expand Up @@ -46,6 +47,7 @@ class DatabaseManager {

static Future<void> initDataBase(String password) async {
if (_database == null) {
appProvider.currentDatabasePassword = password;
String path = join(await FileUtil.getDatabaseDir(), _dbName);
File file = File(path);
if (file.existsSync()) {
Expand All @@ -66,6 +68,7 @@ class DatabaseManager {
isDatabaseEncrypted = true;
_currentDbFactory = cipherDbFactory;
password = await HiveUtil.regeneratePassword();
appProvider.currentDatabasePassword = password;
ILogger.info("Database not exist and new password is $password");
await HiveUtil.setEncryptDatabaseStatus(
EncryptDatabaseStatus.defaultPassword);
Expand Down Expand Up @@ -93,6 +96,7 @@ class DatabaseManager {
await _database!.rawQuery("PRAGMA rekey='$password'");
ILogger.info("Change database password result is $res");
if (res.isNotEmpty) {
appProvider.currentDatabasePassword = password;
return true;
}
} else {
Expand Down
3 changes: 2 additions & 1 deletion lib/Models/github_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class ReleaseItem {

///Release Asset,Data related to a release.
class ReleaseAsset {
String pkgsDownloadUrl = "";
String browserDownloadUrl;
String contentType;
DateTime createdAt;
Expand Down Expand Up @@ -179,7 +180,7 @@ class ReleaseAsset {

@override
String toString() {
return 'ReleaseAsset{browserDownloadUrl: $browserDownloadUrl, contentType: $contentType, createdAt: $createdAt, downloadCount: $downloadCount, id: $id, label: $label, name: $name, nodeId: $nodeId, size: $size, state: $state, updatedAt: $updatedAt, uploader: $uploader, url: $url}';
return 'ReleaseAsset{pkgsDownloadUrl: $pkgsDownloadUrl, browserDownloadUrl: $browserDownloadUrl, contentType: $contentType, createdAt: $createdAt, downloadCount: $downloadCount, id: $id, label: $label, name: $name, nodeId: $nodeId, size: $size, state: $state, updatedAt: $updatedAt, uploader: $uploader, url: $url}';
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/Resources/theme_color_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class ThemeColorData {
iconColor: const Color(0xFF333333),
splashColor: const Color(0x44c8c8c8),
highlightColor: const Color(0x44bcbcbc),
shadowColor: Colors.grey.shade200,
shadowColor: const Color(0x12000000),
appBarShadowColor: const Color(0xFFF6F6F6),
appBarBackgroundColor: const Color(0xFFF7F8F9),
appBarSurfaceTintColor: const Color(0xFFF7F8F9),
Expand All @@ -117,7 +117,7 @@ class ThemeColorData {
textDisabledColor: const Color(0xFFD4E2FA),
buttonTextColor: const Color(0xFFF2F2F2),
buttonDisabledColor: const Color(0xFF96BBFA),
dividerColor: const Color(0xFFF5F5F5),
dividerColor: Colors.grey.shade200,
tagBackground: const Color(0xFFF5F5F5),
tagColor: const Color(0xFFBDBDBD),
cardBackground: const Color(0x119E9E9E),
Expand Down
50 changes: 28 additions & 22 deletions lib/Screens/Backup/dropbox_service_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import '../../Utils/ilogger.dart';
import '../../Widgets/BottomSheet/Backups/dropbox_backups_bottom_sheet.dart';
import '../../Widgets/BottomSheet/bottom_sheet_builder.dart';
import '../../Widgets/Dialog/custom_dialog.dart';
import '../../Widgets/Dialog/dialog_builder.dart';
import '../../Widgets/Dialog/progress_dialog.dart';
import '../../Widgets/Item/input_item.dart';
import '../../generated/l10n.dart';
Expand Down Expand Up @@ -219,7 +220,7 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
Expanded(
child: ItemBuilder.buildRoundButton(
context,
text: S.current.webDavSignin,
text: S.current.cloudSignin,
background: Theme.of(context).primaryColor,
fontSizeDelta: 2,
onTap: () async {
Expand All @@ -244,19 +245,19 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
Expanded(
child: ItemBuilder.buildFramedButton(
context,
text: S.current.webDavPullBackup,
text: S.current.cloudPullBackup,
padding: const EdgeInsets.symmetric(vertical: 12),
outline: Theme.of(context).primaryColor,
color: Theme.of(context).primaryColor,
fontSizeDelta: 2,
onTap: () async {
CustomLoadingDialog.showLoading(title: S.current.webDavPulling);
CustomLoadingDialog.showLoading(title: S.current.cloudPulling);
try {
List<DropboxFileInfo>? files =
await _dropboxCloudService!.listBackups();
if (files == null) {
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.webDavPullFailed);
IToast.show(S.current.cloudPullFailed);
return;
}
CloudServiceConfigDao.updateLastPullTime(
Expand All @@ -273,7 +274,7 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
cloudService: _dropboxCloudService!,
onSelected: (selectedFile) async {
var dialog = showProgressDialog(
msg: S.current.webDavPulling,
msg: S.current.cloudPulling,
showProgress: true,
);
Uint8List? res =
Expand All @@ -288,12 +289,12 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
),
);
} else {
IToast.show(S.current.webDavNoBackupFile);
IToast.show(S.current.cloudNoBackupFile);
}
} catch (e, t) {
ILogger.error("Failed to pull file from dropbox", e, t);
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.webDavPullFailed);
IToast.show(S.current.cloudPullFailed);
}
},
),
Expand All @@ -304,7 +305,7 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
context,
padding: const EdgeInsets.symmetric(vertical: 12),
background: Theme.of(context).primaryColor,
text: S.current.webDavPushBackup,
text: S.current.cloudPushBackup,
fontSizeDelta: 2,
onTap: () async {
ExportTokenUtil.backupEncryptToCloud(
Expand All @@ -320,23 +321,28 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
context,
padding: const EdgeInsets.symmetric(vertical: 12),
background: Colors.red,
text: S.current.webDavLogout,
text: S.current.cloudLogout,
fontSizeDelta: 2,
onTap: () async {
CustomLoadingDialog.showLoading(
title: S.current.webDavLoggingOut);
await _dropboxCloudService!.signOut();
setState(() {
_dropboxCloudServiceConfig!.connected = false;
_dropboxCloudServiceConfig!.account = "";
_dropboxCloudServiceConfig!.email = "";
_dropboxCloudServiceConfig!.totalSize =
_dropboxCloudServiceConfig!.remainingSize =
_dropboxCloudServiceConfig!.usedSize = -1;
updateConfig(_dropboxCloudServiceConfig!);
DialogBuilder.showConfirmDialog(context,
title: S.current.cloudLogout,
message: S.current.cloudLogoutMessage,
onTapConfirm: () async {
CustomLoadingDialog.showLoading(
title: S.current.cloudLoggingOut);
await _dropboxCloudService!.signOut();
setState(() {
_dropboxCloudServiceConfig!.connected = false;
_dropboxCloudServiceConfig!.account = "";
_dropboxCloudServiceConfig!.email = "";
_dropboxCloudServiceConfig!.totalSize =
_dropboxCloudServiceConfig!.remainingSize =
_dropboxCloudServiceConfig!.usedSize = -1;
updateConfig(_dropboxCloudServiceConfig!);
});
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.cloudLogoutSuccess);
});
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.webDavLogoutSuccess);
},
),
),
Expand Down
42 changes: 24 additions & 18 deletions lib/Screens/Backup/googledrive_service_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import '../../Utils/ilogger.dart';
import '../../Widgets/BottomSheet/Backups/googledrive_backups_bottom_sheet.dart';
import '../../Widgets/BottomSheet/bottom_sheet_builder.dart';
import '../../Widgets/Dialog/custom_dialog.dart';
import '../../Widgets/Dialog/dialog_builder.dart';
import '../../Widgets/Dialog/progress_dialog.dart';
import '../../Widgets/Item/input_item.dart';
import '../../generated/l10n.dart';
Expand Down Expand Up @@ -220,7 +221,7 @@ class _GoogleDriveServiceScreenState extends State<GoogleDriveServiceScreen>
Expanded(
child: ItemBuilder.buildRoundButton(
context,
text: S.current.webDavSignin,
text: S.current.cloudSignin,
background: Theme.of(context).primaryColor,
fontSizeDelta: 2,
onTap: () async {
Expand All @@ -245,19 +246,19 @@ class _GoogleDriveServiceScreenState extends State<GoogleDriveServiceScreen>
Expanded(
child: ItemBuilder.buildFramedButton(
context,
text: S.current.webDavPullBackup,
text: S.current.cloudPullBackup,
padding: const EdgeInsets.symmetric(vertical: 12),
outline: Theme.of(context).primaryColor,
color: Theme.of(context).primaryColor,
fontSizeDelta: 2,
onTap: () async {
CustomLoadingDialog.showLoading(title: S.current.webDavPulling);
CustomLoadingDialog.showLoading(title: S.current.cloudPulling);
try {
List<GoogleDriveFileInfo>? files =
await _googledriveCloudService!.listBackups();
if (files == null) {
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.webDavPullFailed);
IToast.show(S.current.cloudPullFailed);
return;
}
CloudServiceConfigDao.updateLastPullTime(
Expand All @@ -274,7 +275,7 @@ class _GoogleDriveServiceScreenState extends State<GoogleDriveServiceScreen>
cloudService: _googledriveCloudService!,
onSelected: (selectedFile) async {
var dialog = showProgressDialog(
msg: S.current.webDavPulling,
msg: S.current.cloudPulling,
showProgress: true,
);
Uint8List? res =
Expand All @@ -289,12 +290,12 @@ class _GoogleDriveServiceScreenState extends State<GoogleDriveServiceScreen>
),
);
} else {
IToast.show(S.current.webDavNoBackupFile);
IToast.show(S.current.cloudNoBackupFile);
}
} catch (e, t) {
ILogger.error("Failed to pull from google drive", e, t);
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.webDavPullFailed);
IToast.show(S.current.cloudPullFailed);
}
},
),
Expand All @@ -305,7 +306,7 @@ class _GoogleDriveServiceScreenState extends State<GoogleDriveServiceScreen>
context,
padding: const EdgeInsets.symmetric(vertical: 12),
background: Theme.of(context).primaryColor,
text: S.current.webDavPushBackup,
text: S.current.cloudPushBackup,
fontSizeDelta: 2,
onTap: () async {
ExportTokenUtil.backupEncryptToCloud(
Expand All @@ -321,18 +322,23 @@ class _GoogleDriveServiceScreenState extends State<GoogleDriveServiceScreen>
context,
padding: const EdgeInsets.symmetric(vertical: 12),
background: Colors.red,
text: S.current.webDavLogout,
text: S.current.cloudLogout,
fontSizeDelta: 2,
onTap: () async {
await _googledriveCloudService!.signOut();
setState(() {
_googledriveCloudServiceConfig!.connected = false;
_googledriveCloudServiceConfig!.account = "";
_googledriveCloudServiceConfig!.email = "";
_googledriveCloudServiceConfig!.totalSize =
_googledriveCloudServiceConfig!.remainingSize =
_googledriveCloudServiceConfig!.usedSize = -1;
updateConfig(_googledriveCloudServiceConfig!);
DialogBuilder.showConfirmDialog(context,
title: S.current.cloudLogout,
message: S.current.cloudLogoutMessage,
onTapConfirm: () async {
await _googledriveCloudService!.signOut();
setState(() {
_googledriveCloudServiceConfig!.connected = false;
_googledriveCloudServiceConfig!.account = "";
_googledriveCloudServiceConfig!.email = "";
_googledriveCloudServiceConfig!.totalSize =
_googledriveCloudServiceConfig!.remainingSize =
_googledriveCloudServiceConfig!.usedSize = -1;
updateConfig(_googledriveCloudServiceConfig!);
});
});
},
),
Expand Down
Loading

0 comments on commit fd645c5

Please sign in to comment.