mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-04 17:07:00 +01:00
backup: the Proton login runs from the workspace
:backup login <username> shows Proton's third-party disclosure (and a warning when no session key file seals the stored session), asks for the password, then for a two-factor code when the account has one. If Proton answers with a human check, its own verify.proton.me page opens in a sheet; the token it posts back resumes the login. :backup logout forgets the session and ends it on Proton's side where Proton answers. The mirror picks up a new session within a minute, without a restart. The login is split into steps in backup::proton (start, second_factor, verified), and a half-done login waits in memory for five minutes at most. Every step goes through its own throttle, so the workspace cannot hammer Proton into locking the account. FIDO2-only accounts are told to add an authenticator app. The CLI runs over the same steps and points to :backup login when Proton wants a human check. The CSP lets verify.proton.me into a frame and nothing else.
This commit is contained in:
1 parent
3387db1c4d
commit
e0a4c01654
15 files changed
+638
-39
No files matched your search
@@ -216,6 +216,18 @@ export interface BackupStatus {
|
||||
last_success_at: number | null
|
||||
last_error: string | null
|
||||
last: { uploaded: number; skipped: number; pruned: number; bytes: number } | null
|
||||
/** What Proton asks a third-party client to say before it takes a login. */
|
||||
disclosure?: string
|
||||
/** Whether a stored session is sealed under a key file off the data volume. */
|
||||
sealed_session?: boolean
|
||||
}
|
||||
|
||||
/** What a Proton login from the workspace needs next. */
|
||||
export interface BackupLogin {
|
||||
next: 'done' | 'totp' | 'captcha'
|
||||
/** Proton's human-check page, for `captcha`. */
|
||||
url?: string
|
||||
status: BackupStatus
|
||||
}
|
||||
|
||||
export class ApiError extends Error {
|
||||
@@ -472,6 +484,16 @@ export const api = {
|
||||
|
||||
backupNow: () => request<BackupStatus>('/backup', { method: 'POST' }),
|
||||
|
||||
backupLogin: (username: string, password: string) =>
|
||||
request<BackupLogin>('/backup/login', { method: 'POST', body: body({ username, password }) }),
|
||||
|
||||
backupTotp: (code: string) => request<BackupLogin>('/backup/login/totp', { method: 'POST', body: body({ code }) }),
|
||||
|
||||
backupCaptcha: (token: string) =>
|
||||
request<BackupLogin>('/backup/login/captcha', { method: 'POST', body: body({ token }) }),
|
||||
|
||||
backupLogout: () => request<BackupStatus>('/backup/login', { method: 'DELETE' }),
|
||||
|
||||
readShared: (token: string, key: string) =>
|
||||
request<SharedDocument>(`/share/${encodeURIComponent(token)}`, { method: 'POST', body: body({ key }) }),
|
||||
|
||||
|
||||
Reference in new issue
Block a user