🐛 fix(security): 完善密文升级导入覆盖与安全更新链路

- 完善连接恢复包与 legacy 导入覆盖语义及密文兼容处理

- 修复安全更新详情高亮反馈与相关前后端链路

- 补强 keyring 误判边界与安全更新回归测试
This commit is contained in:
tianqijiuyun-latiao
2026-04-11 16:53:03 +08:00
parent 070ff72ad8
commit 82e06bd94d
35 changed files with 2021 additions and 110 deletions

View File

@@ -1,10 +1,26 @@
import type { ConnectionConfig, SavedConnection } from '../types';
export type ConnectionImportKind = 'encrypted-package' | 'legacy-json' | 'invalid';
export type ConnectionPackageDialogSnapshot = {
open: boolean;
mode: 'export' | 'import';
password: string;
error: string;
confirmLoading: boolean;
};
export type ConnectionPackageDialogUpdater = (
current: ConnectionPackageDialogSnapshot,
) => ConnectionPackageDialogSnapshot;
export type ConnectionPackageExportResult =
| { kind: 'canceled'; nextDialog: ConnectionPackageDialogUpdater }
| { kind: 'succeeded' }
| { kind: 'failed'; error: string };
type JsonObject = Record<string, unknown>;
const CONNECTION_PACKAGE_KIND = 'gonavi_connection_package';
const CANCELED_MESSAGE = '已取消';
const isJsonObject = (value: unknown): value is JsonObject => (
typeof value === 'object' && value !== null && !Array.isArray(value)
@@ -69,6 +85,39 @@ export const detectConnectionImportKind = (raw: unknown): ConnectionImportKind =
export const normalizeConnectionPackagePassword = (value: string): string => value.trim();
export const isConnectionPackageExportCanceled = (result: unknown): boolean => (
isJsonObject(result)
&& result.success === false
&& result.message === CANCELED_MESSAGE
);
export const resolveConnectionPackageExportResult = (
_currentDialog: ConnectionPackageDialogSnapshot,
result: unknown,
): ConnectionPackageExportResult => {
if (isConnectionPackageExportCanceled(result)) {
return {
kind: 'canceled',
nextDialog: (current) => ({
...current,
confirmLoading: false,
error: '',
}),
};
}
if (isJsonObject(result) && result.success === true) {
return { kind: 'succeeded' };
}
return {
kind: 'failed',
error: isJsonObject(result) && typeof result.message === 'string' && result.message.trim()
? result.message
: '导出失败',
};
};
const legacyExportRemovedError = (): never => {
throw new Error('Legacy connection JSON export has been removed. Use the recovery package flow instead.');
};