core: improve logout UX with account picker and warn on missing refresh token

This commit is contained in:
Kit Langton
2026-03-10 10:13:20 -04:00
parent 41114b1b6e
commit e59e104ad3
2 changed files with 26 additions and 5 deletions

View File

@@ -349,6 +349,9 @@ export class AccountService extends ServiceMap.Service<
const now = yield* Clock.currentTimeMillis
const expiry = now + (parsed.expires_in ?? 0) * 1000
const refresh = parsed.refresh_token ?? ""
if (!refresh) {
yield* Effect.logWarning("Server did not return a refresh token — session may expire without ability to refresh")
}
yield* repo.persistAccount({
id: userId,

View File

@@ -54,20 +54,38 @@ const loginEffect = Effect.fn("login")(function* (url?: string) {
const logoutEffect = Effect.fn("logout")(function* (email?: string) {
const service = yield* AccountService
const accounts = yield* service.list()
if (accounts.length === 0) return yield* println("Not logged in")
if (email) {
const accounts = yield* service.list()
const match = accounts.find((a) => a.email === email)
if (!match) return yield* println("Account not found: " + email)
yield* service.remove(match.id)
yield* println("Logged out from " + email)
yield* Prompt.outro("Logged out from " + email)
return
}
const active = yield* service.active()
if (Option.isNone(active)) return yield* println("Not logged in")
yield* service.remove(active.value.id)
yield* println("Logged out from " + active.value.email)
const activeID = Option.map(active, (a) => a.id)
yield* Prompt.intro("Log out")
const opts = accounts.map((a) => {
const isActive = Option.isSome(activeID) && activeID.value === a.id
const server = UI.Style.TEXT_DIM + a.url + UI.Style.TEXT_NORMAL
return {
value: a,
label: isActive
? `${a.email} ${server}` + UI.Style.TEXT_DIM + " (active)"
: `${a.email} ${server}`,
}
})
const selected = yield* Prompt.select({ message: "Select account to log out", options: opts })
if (Option.isNone(selected)) return
yield* service.remove(selected.value.id)
yield* Prompt.outro("Logged out from " + selected.value.email)
})
interface OrgChoice {