返回 DeepSeek-Reasonix
fullAccessConfirmation.ts
根目录 / desktop / frontend / src / lib / fullAccessConfirmation.ts
1 const STORAGE_KEY = "reasonix-full-access-confirmed-projects-v1";
2
3 type ConfirmationStore = {
4 version: 1;
5 projects: string[];
6 };
7
8 function storage(): Storage | undefined {
9 try {
10 return typeof localStorage === "undefined" ? undefined : localStorage;
11 } catch {
12 return undefined;
13 }
14 }
15
16 function readStore(): ConfirmationStore {
17 const target = storage();
18 if (!target) return { version: 1, projects: [] };
19 try {
20 const parsed = JSON.parse(target.getItem(STORAGE_KEY) ?? "null") as Partial<ConfirmationStore> | null;
21 if (parsed?.version !== 1 || !Array.isArray(parsed.projects)) return { version: 1, projects: [] };
22 return {
23 version: 1,
24 projects: parsed.projects.filter((entry): entry is string => typeof entry === "string" && entry.length > 0),
25 };
26 } catch {
27 return { version: 1, projects: [] };
28 }
29 }
30
31 function normalizeWorkspacePath(value: string): string {
32 let path = value.trim().replaceAll("\\", "/");
33 while (path.length > 1 && path.endsWith("/") && !/^[A-Za-z]:\/$/.test(path)) path = path.slice(0, -1);
34 return path;
35 }
36
37 /**
38 * Identifies the folder whose Full access warning has been acknowledged.
39 * Remote hosts are deliberately isolated even when their workspace paths match.
40 */
41 export function fullAccessProjectConfirmationKey(input: {
42 workspacePath?: string;
43 remoteHostId?: string;
44 }): string {
45 const workspacePath = normalizeWorkspacePath(input.workspacePath ?? "");
46 if (!workspacePath) return "";
47 const remoteHostId = input.remoteHostId?.trim();
48 return JSON.stringify([remoteHostId ? `remote:${remoteHostId}` : "local", workspacePath]);
49 }
50
51 export function hasConfirmedFullAccessForProject(projectKey: string): boolean {
52 return projectKey.length > 0 && readStore().projects.includes(projectKey);
53 }
54
55 export function rememberFullAccessConfirmationForProject(projectKey: string): void {
56 if (!projectKey || hasConfirmedFullAccessForProject(projectKey)) return;
57 const target = storage();
58 if (!target) return;
59 const current = readStore();
60 try {
61 target.setItem(STORAGE_KEY, JSON.stringify({ version: 1, projects: [...current.projects, projectKey] } satisfies ConfirmationStore));
62 } catch {
63 // Storage is an optional convenience. If it is unavailable, the safe
64 // fallback is to show the confirmation again next time.
65 }
66 }
67
67 lines TYPESCRIPT