| import React, { createContext, useState, useContext, useEffect } from 'react';
|
| import { base44 } from '@/api/base44Client';
|
| import { appParams } from '@/lib/app-params';
|
| import { createAxiosClient } from '@base44/sdk/dist/utils/axios-client';
|
|
|
| const AuthContext = createContext();
|
|
|
| export const AuthProvider = ({ children }) => {
|
| const [user, setUser] = useState(null);
|
| const [isAuthenticated, setIsAuthenticated] = useState(false);
|
| const [isLoadingAuth, setIsLoadingAuth] = useState(true);
|
| const [isLoadingPublicSettings, setIsLoadingPublicSettings] = useState(true);
|
| const [authError, setAuthError] = useState(null);
|
| const [appPublicSettings, setAppPublicSettings] = useState(null);
|
|
|
| useEffect(() => {
|
|
|
| setIsLoadingAuth(false);
|
| setIsLoadingPublicSettings(false);
|
| }, []);
|
|
|
| const checkAppState = async () => {
|
| try {
|
| setIsLoadingPublicSettings(true);
|
| setAuthError(null);
|
|
|
|
|
|
|
| const appClient = createAxiosClient({
|
| baseURL: `/api/apps/public`,
|
| headers: {
|
| 'X-App-Id': appParams.appId
|
| },
|
| token: appParams.token,
|
| interceptResponses: true
|
| });
|
|
|
| try {
|
| const publicSettings = await appClient.get(`/prod/public-settings/by-id/${appParams.appId}`);
|
| setAppPublicSettings(publicSettings);
|
|
|
|
|
| if (appParams.token) {
|
| await checkUserAuth();
|
| } else {
|
| setIsLoadingAuth(false);
|
| setIsAuthenticated(false);
|
| }
|
| setIsLoadingPublicSettings(false);
|
| } catch (appError) {
|
| console.error('App state check failed:', appError);
|
|
|
|
|
| if (appError.status === 403 && appError.data?.extra_data?.reason) {
|
| const reason = appError.data.extra_data.reason;
|
| if (reason === 'auth_required') {
|
| setAuthError({
|
| type: 'auth_required',
|
| message: 'Authentication required'
|
| });
|
| } else if (reason === 'user_not_registered') {
|
| setAuthError({
|
| type: 'user_not_registered',
|
| message: 'User not registered for this app'
|
| });
|
| } else {
|
| setAuthError({
|
| type: reason,
|
| message: appError.message
|
| });
|
| }
|
| } else {
|
| setAuthError({
|
| type: 'unknown',
|
| message: appError.message || 'Failed to load app'
|
| });
|
| }
|
| setIsLoadingPublicSettings(false);
|
| setIsLoadingAuth(false);
|
| }
|
| } catch (error) {
|
| console.error('Unexpected error:', error);
|
| setAuthError({
|
| type: 'unknown',
|
| message: error.message || 'An unexpected error occurred'
|
| });
|
| setIsLoadingPublicSettings(false);
|
| setIsLoadingAuth(false);
|
| }
|
| };
|
|
|
| const checkUserAuth = async () => {
|
| try {
|
|
|
| setIsLoadingAuth(true);
|
| const currentUser = await base44.auth.me();
|
| setUser(currentUser);
|
| setIsAuthenticated(true);
|
| setIsLoadingAuth(false);
|
| } catch (error) {
|
| console.error('User auth check failed:', error);
|
| setIsLoadingAuth(false);
|
| setIsAuthenticated(false);
|
|
|
|
|
| if (error.status === 401 || error.status === 403) {
|
| setAuthError({
|
| type: 'auth_required',
|
| message: 'Authentication required'
|
| });
|
| }
|
| }
|
| };
|
|
|
| const logout = (shouldRedirect = true) => {
|
| setUser(null);
|
| setIsAuthenticated(false);
|
|
|
| if (shouldRedirect) {
|
|
|
| base44.auth.logout(window.location.href);
|
| } else {
|
|
|
| base44.auth.logout();
|
| }
|
| };
|
|
|
| const navigateToLogin = () => {
|
|
|
| base44.auth.redirectToLogin(window.location.href);
|
| };
|
|
|
| return (
|
| <AuthContext.Provider value={{
|
| user,
|
| isAuthenticated,
|
| isLoadingAuth,
|
| isLoadingPublicSettings,
|
| authError,
|
| appPublicSettings,
|
| logout,
|
| navigateToLogin,
|
| checkAppState
|
| }}>
|
| {children}
|
| </AuthContext.Provider>
|
| );
|
| };
|
|
|
| export const useAuth = () => {
|
| const context = useContext(AuthContext);
|
| if (!context) {
|
| throw new Error('useAuth must be used within an AuthProvider');
|
| }
|
| return context;
|
| };
|
|
|