| | 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;
|
| | };
|
| |
|