Auth — Design Técnico
Gerado pelo Writer (Reversa) em 2026-05-11
Fluxo — Auth.autenticar()
autenticar()
→ repository.getCredenciais()
→ credenciais === undefined
→ authorize(config) [abre browser PKCE]
→ repository.asCredenciais(authState)
→ Api.auth(credenciais) [POST backend]
→ repository.setCredenciais(conta, authState) [keychain]
→ UsuarioLogadoRepository.setUsuarioLogado(credenciais, conta)
→ credenciais existentes && !isAtiva()
→ refresh(config, {refreshToken})
→ repository.setCredenciaisRefreshed(state) [keychain update]
→ return credenciais.idToken
(catch) → Toast + Sentry.captureException
Fluxo — Auth.deslogar()
deslogar()
→ repository.getCredenciais()
→ revoke(config, { tokenToRevoke: credenciais.refreshToken }) [Google]
(catch silencioso — não bloqueia logout)
→ repository.logout() [remove keychain]
→ UsuarioLogadoRepository.logout() [limpa store]
CredentialsService — Estratégia por Plataforma
// Native (iOS/Android)
class NativeCredentialsStrategy {
getGenericPassword() → Keychain.getGenericPassword()
setGenericPassword() → Keychain.setGenericPassword()
resetGenericPassword() → Keychain.resetGenericPassword()
}
// Web
class WebCredentialsStrategy {
// resolveStorage() → localStorage || memoryStorage
getGenericPassword() → storage.getItem(WEB_CREDENTIALS_STORAGE_KEY) → JSON.parse
setGenericPassword() → storage.setItem(key, JSON.stringify({username, password}))
resetGenericPassword() → storage.removeItem(key)
}
Armazenamento de Credenciais
| Plataforma | Backend | Chave / Namespace |
|---|---|---|
| iOS/Android | Keychain / Keystore | Genérico (service não especificado) |
| Web | localStorage → memoryStorage | @cantaIgreja/auth/credenciais |
Formato armazenado: username = slug, password = JSON.stringify(Credenciais)
Tokens
| Campo | Uso |
|---|---|
idToken |
JWT enviado ao backend para autenticação |
accessToken |
OAuth2 access token |
refreshToken |
Para renovar via refresh() e revogar no logout |
accessTokenExpirationDate |
ISO string — verificado em isAtiva() |
Configuração OAuth2
const config = {
issuer: 'https://accounts.google.com',
clientId: `${GOOGLE_OAUTH_APP_GUID}.apps.googleusercontent.com`,
redirectUrl: `com.googleusercontent.apps.${GOOGLE_OAUTH_APP_GUID}:/oauth2redirect/google`,
scopes: ['openid', 'profile', 'email'],
};
// GOOGLE_OAUTH_APP_GUID: diferente para dev e prod (DEVELOPMENT flag)
Riscos e Lacunas
- 🟡 Web:
memoryStoragenão persiste entre sessões — logout implícito ao fechar a aba - 🟡
revokesilencioso — token pode continuar válido no Google após logout local - 🟡
UsuarioLogadoRepositorynão lido completamente — campos persistidos no store não mapeados - 🔴
Api.auth(credenciais)— endpoint do backend não documentado aqui;conta.slugé o identificador local