Skip to content

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: memoryStorage não persiste entre sessões — logout implícito ao fechar a aba
  • 🟡 revoke silencioso — token pode continuar válido no Google após logout local
  • 🟡 UsuarioLogadoRepository nã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