aboutsummaryrefslogtreecommitdiff
path: root/src/contexts/AuthContext.tsx
blob: 2d0a725b7ee4a7324cb25e94ab3479a80853b191 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { User } from '@/types';
import React, { createContext, useContext, useEffect, useState } from 'react';
import * as SecureStore from 'expo-secure-store';
import * as LocalAuthentication from 'expo-local-authentication';
import { apiLogin, apiRegister, LoginPayload, RegisterPayload, setApiToken } from '@/services/api';

interface AuthContextData {
    user: User | null;
    token: string | null;
    isLoading: boolean;
    login: (data: LoginPayload) => Promise<void>;
    register: (data: RegisterPayload) => Promise<void>;
    logout: () => Promise<void>;
    updateUser: (newUser: User) => Promise<void>;
}

const AuthContext = createContext<AuthContextData>({} as AuthContextData);

export function AuthProvider({ children }: { children: React.ReactNode }) {
    const [user, setUser] = useState<User | null>(null);
    const [token, setToken] = useState<string | null>(null);
    const [isLoading, setIsLoading] = useState<boolean>(true);

    useEffect(() => {
        async function loadStorageData() {
            try {
                const storedToken = await SecureStore.getItemAsync('yaba_token');
                const storedUser = await SecureStore.getItemAsync('yaba_user');
                const useBiometrics = await SecureStore.getItemAsync('yaba_use_biometrics');

                if (storedToken && storedUser) {
                    let authenticated = true;

                    if (useBiometrics === 'true') {
                        const hasHardware = await LocalAuthentication.hasHardwareAsync();
                        const isEnrolled = await LocalAuthentication.isEnrolledAsync();

                        if (hasHardware && isEnrolled) {
                            const result = await LocalAuthentication.authenticateAsync({
                                promptMessage: 'Use sua digital para continuar',
                                fallbackLabel: 'Usar senha',
                            });

                            authenticated = result.success;
                        }
                    }

                    if (authenticated) {
                        setApiToken(storedToken);
                        setToken(storedToken);
                        setUser(JSON.parse(storedUser));
                    } else {
                        await SecureStore.deleteItemAsync('yaba_token');
                        await SecureStore.deleteItemAsync('yaba_user');
                    }
                }
            } catch (error) {
                console.error('Error loading storage data:', error);
            } finally {
                setIsLoading(false);
            }
        }

        loadStorageData();
    }, []);

    async function login(data: LoginPayload) {
        const res = await apiLogin(data);
        await SecureStore.setItemAsync('yaba_token', res.token);
        await SecureStore.setItemAsync('yaba_user', JSON.stringify(res.user));
        setApiToken(res.token);
        setToken(res.token);
        setUser(res.user);
    }

    async function register(data: RegisterPayload) {
        const res = await apiRegister(data);
        console.log('Register response:', res);
        await SecureStore.setItemAsync('yaba_token', res.token);
        await SecureStore.setItemAsync('yaba_user', JSON.stringify(res.user));
        setApiToken(res.token);
        setToken(res.token);
        setUser(res.user);
    }

    async function logout() {
        await SecureStore.deleteItemAsync('yaba_token');
        await SecureStore.deleteItemAsync('yaba_user');
        setApiToken(null);
        setToken(null);
        setUser(null);
    }

    async function updateUser(newUser: User) {
        await SecureStore.setItemAsync('yaba_user', JSON.stringify(newUser));
        setUser(newUser);
    }

    return (
        <AuthContext.Provider value={{ user, token, isLoading, login, register, logout, updateUser }}>
            {children}
        </AuthContext.Provider>
    );
}

export function useAuth() {
    return useContext(AuthContext);
}