feat: implement Google OAuth support for Android and iOS
- Added support for Google OAuth with separate client IDs for Android and iOS. - Updated `verify_google_id_token` to validate `aud` against both client IDs and check `email_verified`. - Modified `google_oauth_handler` to accept and process the new client IDs. - Enhanced security by enforcing explicit JWT algorithm validation. - Updated mobile app to handle Google OAuth flow using `expo-auth-session`. - Fixed API request to send `id_token` in snake_case as expected by the backend. - Added necessary environment variables for Google client IDs in mobile app. - Implemented intent filter for Google OAuth redirect in AndroidManifest.xml.
This commit is contained in:
@@ -487,6 +487,84 @@ GET /api/v1/filaments/:id/label.svg?width_mm=22&height_mm=14&fields=color,name,q
|
||||
|
||||
---
|
||||
|
||||
## Mudanças Recentes (19/03/2026) — segunda entrada
|
||||
|
||||
### ✅ Google OAuth — suporte a client IDs Android e iOS
|
||||
|
||||
**Arquivos modificados**: `src/config.rs`, `src/adapters/inbound/auth_handler.rs`
|
||||
|
||||
**Problema**: o backend lia apenas `GOOGLE_CLIENT_ID` (Android). Tokens emitidos pelo fluxo iOS tinham `aud` diferente e eram rejeitados.
|
||||
|
||||
**Mudanças**:
|
||||
|
||||
- `Config` ganhou campo `google_client_id_ios: String` lido de `GOOGLE_CLIENT_ID_APPLE`
|
||||
- `verify_google_id_token` aceita agora dois client IDs e valida `aud` contra ambos:
|
||||
|
||||
```rust
|
||||
let valid_ids = [client_id_android, client_id_ios];
|
||||
let audience_valid = valid_ids.iter().any(|id| !id.is_empty() && *id == aud);
|
||||
if !audience_valid { return Err(AppError::Unauthorized); }
|
||||
```
|
||||
|
||||
- Assinatura atualizada: `verify_google_id_token(id_token, client_id_android, client_id_ios)`
|
||||
- Call site em `google_oauth_handler` passa `state.config.google_client_id` e `state.config.google_client_id_ios`
|
||||
|
||||
**Variável de ambiente adicionada**:
|
||||
|
||||
| Variável | Valor no .env |
|
||||
| ---------------------- | ------------------------------------------------------------------ |
|
||||
| `GOOGLE_CLIENT_ID` | `724520558909-bg5a7e4u24jmis8lgg41ucs0kv0nfp1v.apps.googleusercontent.com` |
|
||||
| `GOOGLE_CLIENT_ID_APPLE` | `724520558909-v3kubsvmf3vda7fep8qaabenmdap53hs.apps.googleusercontent.com` |
|
||||
|
||||
---
|
||||
|
||||
## Mudanças Recentes (19/03/2026)
|
||||
|
||||
### ✅ Hardening de segurança — Google OAuth e JWT
|
||||
|
||||
**Arquivos modificados**: `src/adapters/inbound/auth_handler.rs`, `src/application/auth_service.rs`
|
||||
|
||||
#### Google OAuth — validação de `aud` e `email_verified`
|
||||
|
||||
**Problema**: a função `verify_google_id_token` recebia `_client_id` como parâmetro mas nunca o usava. Qualquer portador de um token Google válido — emitido para qualquer app — podia autenticar no MeowSpool.
|
||||
|
||||
**Correção** (`auth_handler.rs`):
|
||||
|
||||
```rust
|
||||
// Valida audience: o token deve ter sido emitido para este app
|
||||
let aud = payload["aud"].as_str().ok_or(AppError::Unauthorized)?;
|
||||
if !client_id.is_empty() && aud != client_id {
|
||||
tracing::warn!(aud, client_id, "Google id_token audience mismatch");
|
||||
return Err(AppError::Unauthorized);
|
||||
}
|
||||
|
||||
// Rejeita contas Google com e-mail não verificado
|
||||
let email_verified = payload["email_verified"].as_str().unwrap_or("false");
|
||||
if email_verified != "true" {
|
||||
tracing::warn!("Google account email not verified");
|
||||
return Err(AppError::Unauthorized);
|
||||
}
|
||||
```
|
||||
|
||||
- Parâmetro renomeado de `_client_id` para `client_id`
|
||||
- Rejeições geram `tracing::warn!` para auditoria
|
||||
|
||||
#### JWT — algoritmo explícito
|
||||
|
||||
**Problema**: `Validation::default()` não fixava o algoritmo permitido, abrindo margem para ataques com algoritmos inesperados.
|
||||
|
||||
**Correção** (`auth_service.rs`): substituído `Validation::default()` por `Validation::new(Algorithm::HS256)` em ambos os pontos de decodificação:
|
||||
|
||||
```rust
|
||||
// validate_access_token e decode_refresh_token:
|
||||
let validation = Validation::new(Algorithm::HS256);
|
||||
decode::<Claims>(token, &key, &validation)
|
||||
```
|
||||
|
||||
`Algorithm` importado de `jsonwebtoken`.
|
||||
|
||||
---
|
||||
|
||||
## Mudanças Recentes (14/03/2026)
|
||||
|
||||
### ✅ Reenvio de e-mail de verificação
|
||||
|
||||
Reference in New Issue
Block a user