Skip to content

Commit

Permalink
linux: put the application data into $XDG_DATA_HOME (#21)
Browse files Browse the repository at this point in the history
* change the application data dir to getApplicationSupportDirectory()

* linux: add app metadata info

* dart format .
  • Loading branch information
pugaizai authored Sep 16, 2024
1 parent 3f5f051 commit df40211
Show file tree
Hide file tree
Showing 77 changed files with 356 additions and 250 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
artifact_path: /Users/runner/work/CloudOTP/CloudOTP/*.dmg
outputs:
version: ${{ steps.get_version.outputs.version }}
date: ${{ steps.get_version.outputs.date}}
runs-on: ${{ matrix.os }}
env:
FLUTTER_VERSION: 3.24.0
Expand Down Expand Up @@ -111,6 +112,7 @@ jobs:
shell: bash
run: |
echo "version=$(head -n 2 pubspec.yaml | tail -n 1 | cut -d ' ' -f 2 | cut -d '+' -f 1)" >> $GITHUB_OUTPUT
echo "date=$(date +%Y-%m-%d)" >> $GITHUB_OUTPUT
# Build Android .apk
- name: Build Android
Expand Down Expand Up @@ -188,13 +190,16 @@ jobs:
mkdir -p build/linux/CloudOTP-${{ steps.get_version.outputs.version }}-linux-amd64
cd build/linux/CloudOTP-${{ steps.get_version.outputs.version }}-linux-amd64
mkdir -p opt/CloudOTP
mkdir -p usr/share/metainfo
mkdir -p usr/share/applications
mkdir -p usr/share/icons/hicolor/scalable/apps
cp -r ../x64/release/bundle/* opt/CloudOTP
cp -r ../../../tools/linux_tools/DEBIAN .
chmod 0755 DEBIAN/postinst
chmod 0755 DEBIAN/postrm
sed -i '51i\ <release version="${{ steps.get_version.outputs.version }}" date="${{ steps.get_version.outputs.date }}">' ../../../tools/linux_tools/com.cloudchewie.cloudotp.metainfo.xml
cp ../../../tools/linux_tools/com.cloudchewie.cloudotp.metainfo.xml usr/share/metainfo
cp ../../../tools/linux_tools/com.cloudchewie.cloudotp.desktop usr/share/applications
cp ../../../assets/logo-transparent.svg usr/share/icons/hicolor/scalable/apps/com.cloudchewie.cloudotp.svg
Expand Down
4 changes: 2 additions & 2 deletions lib/Api/github_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import '../Utils/ilogger.dart';
class GithubApi {
static Future<List<ReleaseItem>> getReleases(String user, String repo) async {
try {
ILogger.info("CloudOTP","Getting releases for $user/$repo");
ILogger.info("CloudOTP", "Getting releases for $user/$repo");
final response =
await Dio().get("https://api.github.com/repos/$user/$repo/releases");
if (response.statusCode == 200) {
Expand All @@ -33,7 +33,7 @@ class GithubApi {
}
}
} catch (e, t) {
ILogger.error("CloudOTP","Failed to get releases", e, t);
ILogger.error("CloudOTP", "Failed to get releases", e, t);
}
return [];
}
Expand Down
12 changes: 7 additions & 5 deletions lib/Database/database_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,15 @@ class DatabaseManager {
} else {
isDatabaseEncrypted = true;
_currentDbFactory = cipherDbFactory;
ILogger.info("CloudOTP","Database is an encrypted SQLite database.");
ILogger.info("CloudOTP", "Database is an encrypted SQLite database.");
}
} else {
isDatabaseEncrypted = true;
_currentDbFactory = cipherDbFactory;
password = await HiveUtil.regeneratePassword();
appProvider.currentDatabasePassword = password;
ILogger.info("CloudOTP","Database not exist and new password is generated");
ILogger.info(
"CloudOTP", "Database not exist and new password is generated");
await HiveUtil.setEncryptDatabaseStatus(
EncryptDatabaseStatus.defaultPassword);
}
Expand All @@ -114,7 +115,7 @@ class DatabaseManager {
if (isDatabaseEncrypted) {
List<Map<String, Object?>> res =
await _database!.rawQuery("PRAGMA rekey='$password'");
ILogger.info("CloudOTP","Change database password result is $res");
ILogger.info("CloudOTP", "Change database password result is $res");
if (res.isNotEmpty) {
appProvider.currentDatabasePassword = password;
return true;
Expand All @@ -127,7 +128,7 @@ class DatabaseManager {
await _database!.rawQuery("DETACH DATABASE tmp");
return true;
} catch (e) {
ILogger.error("CloudOTP","Failed to change database password", e);
ILogger.error("CloudOTP", "Failed to change database password", e);
return false;
}
}
Expand All @@ -144,7 +145,8 @@ class DatabaseManager {
ILogger.info("CloudOTP",
"Configure database with cipher successfully. Result is $res");
} else {
ILogger.error("CloudOTP",
ILogger.error(
"CloudOTP",
"Failed to configure database with cipher, perhaps the sqlcipher dynamic library was not loaded.",
res,
);
Expand Down
5 changes: 3 additions & 2 deletions lib/Models/opt_token.dart
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ class OtpToken {
int lastCopyTimeStamp;
String pin;
String description;
List<String> tags=[];
List<String> tags = [];

int get pinnedInt => pinned ? 1 : 0;

Expand Down Expand Up @@ -598,7 +598,8 @@ class OtpToken {
try {
remark = jsonDecode(cloudOtpParameters.remark);
} catch (e, t) {
ILogger.error("CloudOTP","Failed to decode remark from ${cloudOtpParameters.remark}", e, t);
ILogger.error("CloudOTP",
"Failed to decode remark from ${cloudOtpParameters.remark}", e, t);
remark = {};
}
return OtpToken(
Expand Down
2 changes: 1 addition & 1 deletion lib/Resources/fonts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class CustomFont {
return CustomFont(
fontName: fontName, fontFamily: fontFamily, fontUrl: fileName);
} catch (e) {
ILogger.error("CloudOTP","Failed to copy font file", e);
ILogger.error("CloudOTP", "Failed to copy font file", e);
return null;
}
}
Expand Down
23 changes: 12 additions & 11 deletions lib/Screens/Backup/dropbox_service_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
super.build(context);
return ResponsiveUtil.isLinux()
? _buildUnsupportBody()
:inited
? _buildBody()
: ItemBuilder.buildLoadingDialog(
context,
background: Colors.transparent,
text: S.current.cloudConnecting,
mainAxisAlignment: MainAxisAlignment.start,
topPadding: 100,
);
: inited
? _buildBody()
: ItemBuilder.buildLoadingDialog(
context,
background: Colors.transparent,
text: S.current.cloudConnecting,
mainAxisAlignment: MainAxisAlignment.start,
topPadding: 100,
);
}

_buildUnsupportBody() {
Expand Down Expand Up @@ -258,7 +258,7 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
try {
ping();
} catch (e, t) {
ILogger.error("CloudOTP","Failed to connect to dropbox", e, t);
ILogger.error("CloudOTP", "Failed to connect to dropbox", e, t);
IToast.show(S.current.cloudConnectionError);
}
},
Expand Down Expand Up @@ -323,7 +323,8 @@ class _DropboxServiceScreenState extends State<DropboxServiceScreen>
IToast.show(S.current.cloudNoBackupFile);
}
} catch (e, t) {
ILogger.error("CloudOTP","Failed to pull file from dropbox", e, t);
ILogger.error(
"CloudOTP", "Failed to pull file from dropbox", e, t);
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.cloudPullFailed);
}
Expand Down
6 changes: 4 additions & 2 deletions lib/Screens/Backup/googledrive_service_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ class _GoogleDriveServiceScreenState extends State<GoogleDriveServiceScreen>
try {
ping();
} catch (e, t) {
ILogger.error("CloudOTP","Failed to connect to google drive", e, t);
ILogger.error(
"CloudOTP", "Failed to connect to google drive", e, t);
IToast.show(S.current.cloudConnectionError);
}
},
Expand Down Expand Up @@ -308,7 +309,8 @@ class _GoogleDriveServiceScreenState extends State<GoogleDriveServiceScreen>
IToast.show(S.current.cloudNoBackupFile);
}
} catch (e, t) {
ILogger.error("CloudOTP","Failed to pull from google drive", e, t);
ILogger.error(
"CloudOTP", "Failed to pull from google drive", e, t);
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.cloudPullFailed);
}
Expand Down
6 changes: 4 additions & 2 deletions lib/Screens/Backup/huawei_service_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ class _HuaweiCloudServiceScreenState extends State<HuaweiCloudServiceScreen>
try {
ping();
} catch (e, t) {
ILogger.error("CloudOTP","Failed to connect to huawei cloud", e, t);
ILogger.error(
"CloudOTP", "Failed to connect to huawei cloud", e, t);
IToast.show(S.current.cloudConnectionError);
}
},
Expand Down Expand Up @@ -300,7 +301,8 @@ class _HuaweiCloudServiceScreenState extends State<HuaweiCloudServiceScreen>
IToast.show(S.current.cloudNoBackupFile);
}
} catch (e, t) {
ILogger.error("CloudOTP","Failed to pull from huawei cloud", e, t);
ILogger.error(
"CloudOTP", "Failed to pull from huawei cloud", e, t);
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.cloudPullFailed);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/Screens/Backup/s3_service_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ class _S3CloudServiceScreenState extends State<S3CloudServiceScreen>
_s3CloudService = S3CloudService(_s3CloudServiceConfig!);
ping();
} catch (e, t) {
ILogger.error("CloudOTP","Failed to connect to S3 cloud", e, t);
ILogger.error(
"CloudOTP", "Failed to connect to S3 cloud", e, t);
IToast.show(S.current.cloudConnectionError);
}
}
Expand Down Expand Up @@ -378,7 +379,7 @@ class _S3CloudServiceScreenState extends State<S3CloudServiceScreen>
IToast.show(S.current.cloudNoBackupFile);
}
} catch (e, t) {
ILogger.error("CloudOTP","Failed to pull from S3 cloud", e, t);
ILogger.error("CloudOTP", "Failed to pull from S3 cloud", e, t);
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.cloudPullFailed);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/Screens/Backup/webdav_service_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ class _WebDavServiceScreenState extends State<WebDavServiceScreen>
try {
ping();
} catch (e, t) {
ILogger.error("CloudOTP","Failed to connect to webdav", e, t);
ILogger.error(
"CloudOTP", "Failed to connect to webdav", e, t);
IToast.show(S.current.cloudConnectionError);
}
}
Expand Down Expand Up @@ -344,7 +345,7 @@ class _WebDavServiceScreenState extends State<WebDavServiceScreen>
IToast.show(S.current.cloudNoBackupFile);
}
} catch (e, t) {
ILogger.error("CloudOTP","Failed to pull from webdav", e, t);
ILogger.error("CloudOTP", "Failed to pull from webdav", e, t);
CustomLoadingDialog.dismissLoading();
IToast.show(S.current.cloudPullFailed);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Screens/Lock/database_decrypt_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class DatabaseDecryptScreen extends StatefulWidget {
}

class DatabaseDecryptScreenState extends State<DatabaseDecryptScreen>
with WindowListener,TrayListener {
with WindowListener, TrayListener {
final FocusNode _focusNode = FocusNode();
late InputValidateAsyncController validateAsyncController;
GlobalKey<FormState> formKey = GlobalKey<FormState>();
Expand Down Expand Up @@ -84,7 +84,7 @@ class DatabaseDecryptScreenState extends State<DatabaseDecryptScreen>
IToast.showTop(canAuthenticateResponseString ?? "");
}
} catch (e, t) {
ILogger.error("CloudOTP","Failed to authenticate with biometric", e, t);
ILogger.error("CloudOTP", "Failed to authenticate with biometric", e, t);
if (e is AuthException) {
switch (e.code) {
case AuthExceptionCode.userCanceled:
Expand Down
2 changes: 1 addition & 1 deletion lib/Screens/Setting/setting_general_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ class GeneralSettingScreenState extends State<GeneralSettingScreen>
await getLogSize();
IToast.showTop(S.current.clearLogSuccess);
} catch (e, t) {
ILogger.error("CloudOTP","Failed to clear logs", e, t);
ILogger.error("CloudOTP", "Failed to clear logs", e, t);
IToast.showTop(S.current.clearLogFailed);
} finally {
CustomLoadingDialog.dismissLoading();
Expand Down
3 changes: 2 additions & 1 deletion lib/Screens/Setting/setting_operation_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class _OperationSettingScreenState extends State<OperationSettingScreen>
bool clipToCopy = HiveUtil.getBool(HiveUtil.clickToCopyKey);
bool autoCopyNextCode = HiveUtil.getBool(HiveUtil.autoCopyNextCodeKey);
bool autoDisplayNextCode = HiveUtil.getBool(HiveUtil.autoDisplayNextCodeKey);
bool autoFocusSearchBar = HiveUtil.getBool(HiveUtil.autoFocusSearchBarKey,defaultValue: false);
bool autoFocusSearchBar =
HiveUtil.getBool(HiveUtil.autoFocusSearchBarKey, defaultValue: false);
bool autoMinimizeAfterClickToCopy = HiveUtil.getBool(
HiveUtil.autoMinimizeAfterClickToCopyKey,
defaultValue: false);
Expand Down
2 changes: 1 addition & 1 deletion lib/Screens/Token/add_token_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ class _AddTokenScreenState extends State<AddTokenScreen>
_otpToken.uid, unselectedCategoryUids);
success = true;
} catch (e, t) {
ILogger.error("CloudOTP","Failed to save token", e, t);
ILogger.error("CloudOTP", "Failed to save token", e, t);
IToast.showTop(S.current.saveFailed);
} finally {
if (!_isEditing) {
Expand Down
5 changes: 3 additions & 2 deletions lib/TokenUtils/Backup/backup_encrypt_old.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class BackupEncryptionOld implements BackupEncryptInterface {
base64.decode(utf8.decode(data));
return true;
} catch (e, t) {
ILogger.error("CloudOTP","Failed to decrypt from wrong format data", e, t);
ILogger.error(
"CloudOTP", "Failed to decrypt from wrong format data", e, t);
return false;
}
}
Expand Down Expand Up @@ -120,7 +121,7 @@ class AESStringCipher {
final decryptedData = cipher.process(encryptedData);
return utf8.decode(decryptedData);
} catch (e, t) {
ILogger.error("CloudOTP","Failed to decrypt data", e, t);
ILogger.error("CloudOTP", "Failed to decrypt data", e, t);
}
return "";
}
Expand Down
11 changes: 8 additions & 3 deletions lib/TokenUtils/Backup/backup_encrypt_v1.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ class BackupEncryptionV1 implements BackupEncryptInterface {
try {
unencryptedData = cipher.process(encryptedData);
} catch (e, t) {
ILogger.error("CloudOTP","Failed to decrypt data (InvalidPasswordOrDataCorruptedException)", e, t);
ILogger.error(
"CloudOTP",
"Failed to decrypt data (InvalidPasswordOrDataCorruptedException)",
e,
t);
throw InvalidPasswordOrDataCorruptedException();
}

Expand All @@ -121,7 +125,8 @@ class BackupEncryptionV1 implements BackupEncryptInterface {
}
return true;
} catch (e, t) {
ILogger.error("CloudOTP","Failed to decrypt (FileNotBackupException)", e, t);
ILogger.error(
"CloudOTP", "Failed to decrypt (FileNotBackupException)", e, t);
throw FileNotBackupException();
}
}
Expand All @@ -138,4 +143,4 @@ class BackupEncryptionV1 implements BackupEncryptInterface {
final key = argon2.process(Uint8List.fromList(utf8.encode(password)));
return Uint8List.fromList(key);
}
}
}
Loading

0 comments on commit df40211

Please sign in to comment.