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:
@@ -1,12 +1,13 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
View, Text, TouchableOpacity, StyleSheet, Alert,
|
||||
View, Text, TouchableOpacity, StyleSheet, Alert, Platform,
|
||||
} from 'react-native';
|
||||
import { useLocalSearchParams, useRouter } from 'expo-router';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import * as FileSystem from 'expo-file-system/legacy';
|
||||
import * as Sharing from 'expo-sharing';
|
||||
import * as IntentLauncher from 'expo-intent-launcher';
|
||||
import { useFilamentStore } from '@store/filamentStore';
|
||||
import { usePresetStore } from '@store/presetStore';
|
||||
import { calcFilamentPercentage } from '@domain/Filament';
|
||||
@@ -111,7 +112,14 @@ export default function LabelScreen(): React.ReactElement {
|
||||
await FileSystem.writeAsStringAsync(fileUri, base64, {
|
||||
encoding: FileSystem.EncodingType.Base64,
|
||||
});
|
||||
if (await Sharing.isAvailableAsync()) {
|
||||
if (Platform.OS === 'android') {
|
||||
const contentUri = await FileSystem.getContentUriAsync(fileUri);
|
||||
await IntentLauncher.startActivityAsync('android.intent.action.VIEW', {
|
||||
data: contentUri,
|
||||
flags: 1, // FLAG_GRANT_READ_URI_PERMISSION
|
||||
type: 'application/pdf',
|
||||
});
|
||||
} else if (await Sharing.isAvailableAsync()) {
|
||||
await Sharing.shareAsync(fileUri, { mimeType: 'application/pdf', UTI: 'com.adobe.pdf' });
|
||||
} else {
|
||||
Alert.alert('Compartilhamento indisponível', 'Este dispositivo não suporta compartilhamento de arquivos.');
|
||||
@@ -123,7 +131,14 @@ export default function LabelScreen(): React.ReactElement {
|
||||
);
|
||||
const fileUri = `${FileSystem.cacheDirectory}meowspool-label-${id}.svg`;
|
||||
await FileSystem.writeAsStringAsync(fileUri, response.data, { encoding: 'utf8' });
|
||||
if (await Sharing.isAvailableAsync()) {
|
||||
if (Platform.OS === 'android') {
|
||||
const contentUri = await FileSystem.getContentUriAsync(fileUri);
|
||||
await IntentLauncher.startActivityAsync('android.intent.action.VIEW', {
|
||||
data: contentUri,
|
||||
flags: 1, // FLAG_GRANT_READ_URI_PERMISSION
|
||||
type: 'image/svg+xml',
|
||||
});
|
||||
} else if (await Sharing.isAvailableAsync()) {
|
||||
await Sharing.shareAsync(fileUri, { mimeType: 'image/svg+xml', UTI: 'public.svg-image' });
|
||||
} else {
|
||||
Alert.alert('Compartilhamento indisponível', 'Este dispositivo não suporta compartilhamento de arquivos.');
|
||||
|
||||
Reference in New Issue
Block a user