Skip to content

feat: Password management#1127

Merged
GT-610 merged 7 commits intolollipopkit:mainfrom
GT-610:pwd-manage
Apr 12, 2026
Merged

feat: Password management#1127
GT-610 merged 7 commits intolollipopkit:mainfrom
GT-610:pwd-manage

Conversation

@GT-610
Copy link
Copy Markdown
Collaborator

@GT-610 GT-610 commented Apr 12, 2026

Resolve #1070.

Resolve #471.

Summary by CodeRabbit

  • New Features

    • Per-server sudo password overrides: set, edit, clear and persist from server edit UI; cleared when servers are removed or renamed.
    • Virtual keyboard key to insert sudo passwords into terminals.
    • SSH action to detect sudo prompts and submit stored passwords with success/failure feedback.
    • Desktop option to auto-copy SSH password to clipboard before launching terminal (auto-clear).
    • Optional biometric authentication for password-related actions.
  • Localization

    • Added "mismatch system" message in many languages.
  • Chores

    • Submodule updates and contributor list additions.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 12, 2026

📝 Walkthrough

Walkthrough

Adds per-server secure sudo-password overrides via a new SudoPassword utility (read/write/clear, terminal resolution, and biometric-gated authentication). UI to view, edit, clear, and persist sudo-passwords is added to the server edit page and integrated into the save flow. Adds a virtual key and app-bar action to inject stored sudo passwords into SSH terminals with prompt detection. Adds a desktop setting to optionally auto-copy SSH passwords, updates Hive adapters/enums/localizations, and clears stored sudo overrides when servers are deleted.

Possibly related PRs

Suggested reviewers

  • lollipopkit
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Password management' is directly related to the changeset, which introduces comprehensive password management features including sudo password storage, biometric authentication, and desktop password auto-copy functionality.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from both linked issues: sudo password per-server storage with biometric authentication (#1070) and automatic password copying to clipboard before terminal launch on desktop (#471).
Out of Scope Changes check ✅ Passed All changes are directly aligned with the linked issues. GitHub contributor additions and submodule updates are reasonable maintenance activities. No unrelated feature development or scope creep detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot requested a review from lollipopkit April 12, 2026 05:57
devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment thread lib/view/widget/server_func_btns.dart
Comment thread lib/view/page/ssh/page/page.dart
coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 12, 2026
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 7 additional findings in Devin Review.

Open in Devin Review

Comment thread lib/core/utils/sudo_password.dart
Comment thread lib/view/page/server/edit/actions.dart
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/data/provider/server/all.dart (1)

243-243: Isolate secure-storage cleanup failures to avoid partial delete flows.

A thrown error from SudoPassword.clearOverride(...) can short-circuit later cleanup in these methods. Consider making override cleanup best-effort and logging failures.

♻️ Suggested hardening
@@
-    await SudoPassword.clearOverride(id);
+    try {
+      await SudoPassword.clearOverride(id);
+    } catch (e) {
+      Loggers.app.warning('Failed to clear sudo override for $id: $e');
+    }
@@
-    await Future.wait(serverIds.map(SudoPassword.clearOverride));
+    await Future.wait(
+      serverIds.map((id) async {
+        try {
+          await SudoPassword.clearOverride(id);
+        } catch (e) {
+          Loggers.app.warning('Failed to clear sudo override for $id: $e');
+        }
+      }),
+    );

Also applies to: 267-267

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/data/provider/server/all.dart` at line 243, Make the secure-storage
cleanup a best-effort operation by wrapping calls to
SudoPassword.clearOverride(id) in a try/catch so any thrown error is caught and
logged (using the existing logger in the file) and does not short-circuit the
remaining cleanup or delete flow; update every place where
SudoPassword.clearOverride is invoked (including the other occurrence mentioned)
to catch exceptions, log a descriptive message with the error and id/context,
and then continue without rethrowing so later cleanup and deletion proceed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/data/provider/server/all.dart`:
- Line 243: Make the secure-storage cleanup a best-effort operation by wrapping
calls to SudoPassword.clearOverride(id) in a try/catch so any thrown error is
caught and logged (using the existing logger in the file) and does not
short-circuit the remaining cleanup or delete flow; update every place where
SudoPassword.clearOverride is invoked (including the other occurrence mentioned)
to catch exceptions, log a descriptive message with the error and id/context,
and then continue without rethrowing so later cleanup and deletion proceed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 24f80193-71e1-4f5a-9293-665ef7019ec8

📥 Commits

Reviewing files that changed from the base of the PR and between f17af81 and 4a1250f.

📒 Files selected for processing (1)
  • lib/data/provider/server/all.dart

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 12, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/data/provider/server/all.dart`:
- Around line 84-90: The cleanup helper _clearSudoPasswordOverrideBestEffort
currently clears sudo_pwd for the current id but updateServer's ID-rename path
leaves sudo_pwd_<oldId> behind; update the updateServer flow (the branch that
renames a server) to call _clearSudoPasswordOverrideBestEffort(oldId) (or
directly SudoPassword.clearOverride(oldId)) after a successful rename so the old
secret key sudo_pwd_<oldId> is removed; ensure this call runs even if the rename
is asynchronous/fails gracefully and keep the existing try/catch pattern used in
_clearSudoPasswordOverrideBestEffort to avoid throwing from updateServer.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 38a874b9-43a2-4496-9e19-6bd53e896149

📥 Commits

Reviewing files that changed from the base of the PR and between 4a1250f and d4687c4.

📒 Files selected for processing (1)
  • lib/data/provider/server/all.dart

Comment thread lib/data/provider/server/all.dart
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/data/provider/server/all.dart (1)

263-275: ⚠️ Potential issue | 🟠 Major

Preserve or cancel the auto-refresh timer before state reset.

At Line 271, state = const ServersState(); drops autoRefreshTimer without canceling it. The periodic timer can keep running in the background while isAutoRefreshOn becomes false, and later toggles may create duplicate timers.

🔧 Suggested fix
   Future<void> deleteAll() async {
     final serverIds = state.servers.keys.toList();

     // Remove all SSH sessions before clearing servers
     for (final id in serverIds) {
       final sessionId = 'ssh_$id';
       TermSessionManager.remove(sessionId);
     }

-    state = const ServersState();
+    state = state.copyWith(
+      servers: const <String, Spi>{},
+      serverOrder: const <String>[],
+      tags: const <String>{},
+      manualDisconnectedIds: const <String>{},
+    );

     Stores.setting.serverOrder.put([]);
     Stores.server.clear();
     await Future.wait(serverIds.map(_clearSudoPasswordOverrideBestEffort));
     await Stores.connectionStats.clearAll();
     bakSync.sync(milliDelay: 1000);
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/data/provider/server/all.dart` around lines 263 - 275, Before resetting
state to ServersState, ensure any running auto-refresh timer is stopped: check
state.autoRefreshTimer (or call an existing stop/disable helper such as
stopAutoRefresh()/toggleAutoRefreshOff) and cancel it and clear the reference so
the periodic Timer won't continue after state = const ServersState(); then
proceed to remove SSH sessions and reset Stores; update the block around state =
const ServersState() (referencing state, autoRefreshTimer, isAutoRefreshOn, and
any stopAutoRefresh/toggleAutoRefresh methods) to cancel the timer and set
isAutoRefreshOn to false (or null) before assigning the new ServersState to
avoid duplicate timers later.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@lib/data/provider/server/all.dart`:
- Around line 263-275: Before resetting state to ServersState, ensure any
running auto-refresh timer is stopped: check state.autoRefreshTimer (or call an
existing stop/disable helper such as stopAutoRefresh()/toggleAutoRefreshOff) and
cancel it and clear the reference so the periodic Timer won't continue after
state = const ServersState(); then proceed to remove SSH sessions and reset
Stores; update the block around state = const ServersState() (referencing state,
autoRefreshTimer, isAutoRefreshOn, and any stopAutoRefresh/toggleAutoRefresh
methods) to cancel the timer and set isAutoRefreshOn to false (or null) before
assigning the new ServersState to avoid duplicate timers later.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 42d18ddd-29dd-4681-8656-bc1c83f1f405

📥 Commits

Reviewing files that changed from the base of the PR and between d4687c4 and 75f0cd7.

📒 Files selected for processing (1)
  • lib/data/provider/server/all.dart

@GT-610 GT-610 merged commit 66d273a into lollipopkit:main Apr 12, 2026
2 checks passed
@GT-610 GT-610 deleted the pwd-manage branch April 12, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sudo password storage with biometric authentication windows版本在弹出终端之前能自动复制密码

1 participant