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:
2026-03-19 15:24:08 -03:00
parent 31c47fe69f
commit 34cbd4a861
16 changed files with 972 additions and 220 deletions
+5 -3
View File
@@ -4,7 +4,7 @@ use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
Argon2,
};
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use uuid::Uuid;
@@ -137,10 +137,11 @@ impl AuthService {
// -------------------------------------------------------------------------
pub fn validate_access_token(&self, token: &str) -> Result<AccessClaims, AppError> {
let validation = Validation::new(Algorithm::HS256);
decode::<AccessClaims>(
token,
&DecodingKey::from_secret(self.config.jwt_secret.as_bytes()),
&Validation::default(),
&validation,
)
.map(|data| data.claims)
.map_err(|_| AppError::Unauthorized)
@@ -180,10 +181,11 @@ impl AuthService {
}
fn decode_refresh_token(&self, token: &str) -> Result<RefreshClaims, AppError> {
let validation = Validation::new(Algorithm::HS256);
decode::<RefreshClaims>(
token,
&DecodingKey::from_secret(self.config.jwt_secret.as_bytes()),
&Validation::default(),
&validation,
)
.map(|data| data.claims)
.map_err(|_| AppError::Unauthorized)