forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtokenStore.ts
More file actions
40 lines (35 loc) · 1.34 KB
/
Copy pathtokenStore.ts
File metadata and controls
40 lines (35 loc) · 1.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Persist the Google refresh token encrypted at rest via Electron safeStorage
// (DPAPI on Windows). The access token is NOT persisted (kept in oauth.ts memory).
import { app, safeStorage } from 'electron'
import { existsSync, readFileSync, writeFileSync, rmSync } from 'fs'
import { join } from 'path'
type StoredFile = { refreshToken: string; email?: string }
function file(): string {
return join(app.getPath('userData'), 'google-tokens.json')
}
export function saveRefreshToken(refreshToken: string, email?: string): void {
if (!safeStorage.isEncryptionAvailable()) {
throw new Error('Secure storage is unavailable on this system')
}
const enc = safeStorage.encryptString(refreshToken).toString('base64')
writeFileSync(file(), JSON.stringify({ refreshToken: enc, email } satisfies StoredFile), 'utf8')
}
export function loadRefreshToken(): { refreshToken: string; email?: string } | null {
const f = file()
if (!existsSync(f)) return null
try {
const raw = JSON.parse(readFileSync(f, 'utf8')) as StoredFile
if (!raw.refreshToken) return null
const dec = safeStorage.decryptString(Buffer.from(raw.refreshToken, 'base64'))
return { refreshToken: dec, email: raw.email }
} catch {
return null
}
}
export function clearRefreshToken(): void {
try {
rmSync(file(), { force: true })
} catch {
/* best-effort */
}
}