feat(auth): detect session expiry live and offer re-login in place
Every response already funnels through runtimeFetch, so a classifier there spots 401s, confirms them against /auth/session (a proxied provider 401 must not read as a logout), and flips a small auth-session store. The web and hosted surfaces show a frosted banner under the header whose Log in button hands off to the session gate's existing unlock flow; sends are paused while expired, the session-load error screen explains the auth case and retries itself after login, and returning to a long-idle window revalidates once via visibility/focus. Native mobile feeds the same signal into its connection re-probe instead of showing the banner; VS Code is exempt.
This commit is contained in:
@@ -2140,7 +2140,8 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.btw.toast.promoteFailed': 'Falha ao manter a sessão btw',
|
||||
"chat.container.readOnlySubagentPromptBanner": "Sessões de subagente não podem receber prompts.",
|
||||
"chat.container.sessionLoadError.title": "Não foi possível carregar a sessão",
|
||||
"chat.container.sessionLoadError.description": "Verifique a conexão e tente carregar esta sessão novamente.",
|
||||
"chat.container.sessionLoadError.description": "Não foi possível buscar a conversa — o servidor pode estar desligado ou inacessível. Nada foi perdido; tente novamente quando ele voltar.",
|
||||
"chat.container.sessionLoadError.authDescription": "Sua sessão expirou, então o servidor recusou a solicitação. Entre e a conversa será carregada.",
|
||||
"chat.container.sessionLoadError.retry": "Tentar novamente",
|
||||
"sessions.sidebar.group.empty.loadingSessions": "Carregando sessões…",
|
||||
"sessions.sidebar.group.empty.loadFailed": "Não foi possível atualizar as sessões.",
|
||||
@@ -2673,6 +2674,9 @@ export const dict: Record<I18nKey, string> = {
|
||||
"sessionAuth.error.passkeySignInCanceled": "O início de sessão com chave de acesso foi cancelado.",
|
||||
"sessionAuth.error.enterPasswordForPasskey": "Digite sua senha para adicionar uma chave de acesso.",
|
||||
"sessionAuth.locked.tunnelTitle": "É necessário acesso por túnel",
|
||||
"sessionAuth.expired.banner": "Sua sessão expirou — entre para continuar.",
|
||||
"sessionAuth.expired.loginAction": "Entrar",
|
||||
"sessionAuth.expired.sendBlocked": "Sessão expirada — entre para enviar mensagens.",
|
||||
"sessionAuth.locked.unlockTitle": "Desbloquear OpenChamber",
|
||||
"sessionAuth.locked.tunnelDescription": "Abra este túnel usando o link de conexão única do aplicativo desktop.",
|
||||
"sessionAuth.locked.passwordDescription": "Esta sessão está protegida com senha.",
|
||||
|
||||
Reference in New Issue
Block a user