@digilogiclabs/saas-factory-auth 0.2.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/native/index.js +603 -0
- package/dist/components/native/index.js.map +1 -0
- package/dist/components/native/index.mjs +595 -0
- package/dist/components/native/index.mjs.map +1 -0
- package/dist/components/web/index.d.mts +39 -0
- package/dist/components/web/index.d.ts +39 -0
- package/dist/components/web/index.js +417 -0
- package/dist/components/web/index.js.map +1 -0
- package/dist/components/web/index.mjs +411 -0
- package/dist/components/web/index.mjs.map +1 -0
- package/dist/index.d.mts +582 -56
- package/dist/index.d.ts +582 -56
- package/dist/index.js +1833 -91
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1809 -89
- package/dist/index.mjs.map +1 -1
- package/package.json +139 -93
- package/src/components/native/index.d.ts +29 -0
- package/README.md +0 -148
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/IAuthProvider.ts","../../../src/components/AuthProvider.tsx","../../../src/hooks/useAuthForm.ts","../../../src/components/native/AuthForm.tsx","../../../src/hooks/useAuth.ts","../../../src/components/native/AuthStatus.tsx","../../../src/hooks/useProtectedRoute.ts","../../../src/components/native/ProtectedRoute.tsx"],"names":["useState","jsx","useContext","useEffect","View","styles","Text","jsxs","TouchableOpacity","StyleSheet","Fragment"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Common user interface that abstracts user data across different authentication providers\r\n */\r\nexport interface CommonUser {\r\n /** Unique user identifier */\r\n id: string;\r\n /** User's email address */\r\n email: string | undefined;\r\n /** User's display name */\r\n displayName?: string | null;\r\n /** URL to user's profile photo */\r\n photoURL?: string | null;\r\n /** User roles for authorization */\r\n roles?: string[];\r\n /** Provider-specific metadata */\r\n metadata: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Authentication session interface that wraps user data\r\n */\r\nexport interface AuthSession {\r\n /** Current authenticated user */\r\n user: CommonUser | null;\r\n /** Session expiration timestamp (optional) */\r\n expiresAt?: number;\r\n /** Access token (optional, provider-specific) */\r\n accessToken?: string;\r\n}\r\n\r\n/**\r\n * Authentication error types for better error handling\r\n */\r\nexport enum AuthErrorType {\r\n INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',\r\n USER_NOT_FOUND = 'USER_NOT_FOUND',\r\n EMAIL_ALREADY_EXISTS = 'EMAIL_ALREADY_EXISTS',\r\n WEAK_PASSWORD = 'WEAK_PASSWORD',\r\n NETWORK_ERROR = 'NETWORK_ERROR',\r\n PROVIDER_ERROR = 'PROVIDER_ERROR',\r\n CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',\r\n VALIDATION_ERROR = 'VALIDATION_ERROR'\r\n}\r\n\r\n/**\r\n * Custom authentication error class\r\n */\r\nexport class AuthError extends Error {\r\n public readonly timestamp: Date;\r\n public readonly code: string;\r\n\r\n constructor(\r\n public readonly type: AuthErrorType,\r\n message: string,\r\n public readonly originalError?: any,\r\n public readonly context?: Record<string, any>\r\n ) {\r\n super(message);\r\n this.name = 'AuthError';\r\n this.timestamp = new Date();\r\n this.code = type;\r\n \r\n // Ensure proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, AuthError.prototype);\r\n \r\n // Capture stack trace if available\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, AuthError);\r\n }\r\n }\r\n\r\n /**\r\n * Convert error to JSON for logging/debugging\r\n */\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n type: this.type,\r\n code: this.code,\r\n message: this.message,\r\n timestamp: this.timestamp.toISOString(),\r\n context: this.context,\r\n originalError: this.originalError ? {\r\n name: this.originalError.name,\r\n message: this.originalError.message,\r\n code: this.originalError.code\r\n } : undefined\r\n };\r\n }\r\n\r\n /**\r\n * Check if error is of a specific type\r\n */\r\n isType(type: AuthErrorType): boolean {\r\n return this.type === type;\r\n }\r\n\r\n /**\r\n * Check if error is retryable\r\n */\r\n isRetryable(): boolean {\r\n return [\r\n AuthErrorType.NETWORK_ERROR,\r\n AuthErrorType.PROVIDER_ERROR\r\n ].includes(this.type);\r\n }\r\n}\r\n\r\n/**\r\n * Authentication state change events\r\n */\r\nexport enum AuthEvent {\r\n SIGNED_IN = 'SIGNED_IN',\r\n SIGNED_OUT = 'SIGNED_OUT',\r\n TOKEN_REFRESHED = 'TOKEN_REFRESHED',\r\n USER_UPDATED = 'USER_UPDATED'\r\n}\r\n\r\n/**\r\n * OAuth provider types\r\n */\r\nexport type OAuthProvider = 'google' | 'github' | 'facebook' | 'twitter' | 'discord' | 'apple';\r\n\r\n/**\r\n * Authentication provider interface that abstracts authentication operations\r\n * across different backends (Supabase, Firebase, etc.)\r\n */\r\nexport interface IAuthProvider {\r\n /**\r\n * Sign in with email and password\r\n * @param email User's email address\r\n * @param password User's password (required for email/password authentication)\r\n * @returns Promise resolving to the authenticated user or null\r\n * @throws AuthError when authentication fails\r\n */\r\n signIn(email: string, password?: string): Promise<CommonUser | null>;\r\n\r\n /**\r\n * Sign up with email and password\r\n * @param email User's email address\r\n * @param password User's password (required for email/password authentication)\r\n * @returns Promise resolving to the created user or null\r\n * @throws AuthError when sign up fails\r\n */\r\n signUp(email: string, password?: string): Promise<CommonUser | null>;\r\n\r\n /**\r\n * Sign in with OAuth provider\r\n * @param provider OAuth provider name\r\n * @param redirectTo Optional redirect URL after authentication\r\n * @returns Promise that resolves when OAuth flow is initiated\r\n * @throws AuthError when OAuth flow fails to initiate\r\n */\r\n signInWithOAuth(provider: OAuthProvider, redirectTo?: string): Promise<void>;\r\n\r\n /**\r\n * Sign in with magic link (passwordless authentication)\r\n * @param email User's email address\r\n * @param redirectTo Optional redirect URL after email verification\r\n * @returns Promise that resolves when magic link is sent\r\n * @throws AuthError when magic link sending fails\r\n */\r\n signInWithMagicLink(email: string, redirectTo?: string): Promise<void>;\r\n\r\n /**\r\n * Sign out the current user\r\n * @returns Promise that resolves when sign out is complete\r\n * @throws AuthError when sign out fails\r\n */\r\n signOut(): Promise<void>;\r\n\r\n /**\r\n * Send password reset email\r\n * @param email User's email address\r\n * @returns Promise that resolves when reset email is sent\r\n * @throws AuthError when password reset fails\r\n */\r\n resetPassword(email: string): Promise<void>;\r\n\r\n /**\r\n * Get the current authenticated user\r\n * @returns Promise resolving to the current user or null if not authenticated\r\n * @throws AuthError when user retrieval fails\r\n */\r\n getUser(): Promise<CommonUser | null>;\r\n\r\n /**\r\n * Listen for authentication state changes\r\n * @param callback Function called when auth state changes\r\n * @returns Object containing subscription data for cleanup\r\n */\r\n onAuthStateChange(callback: (event: AuthEvent, session: AuthSession | null) => void): { \r\n data: { subscription: any } | { unsubscribe: () => void } \r\n };\r\n\r\n /**\r\n * Validate provider configuration\r\n * @returns Promise that resolves if configuration is valid\r\n * @throws AuthError when configuration is invalid\r\n */\r\n validateConfiguration?(): Promise<void>;\r\n}\r\n\r\n\r\n","'use client'\r\n\r\nimport { createContext, ReactNode, useEffect, useState } from 'react'\r\nimport { AuthProviderFactory, AuthProviderType } from '../core/AuthProviderFactory'\r\nimport { IAuthProvider, AuthSession, AuthEvent } from '../core/IAuthProvider'\r\nimport { IAuthStorage, createAuthStorage } from '../config/storage'\r\nimport { createAuthStore } from '../store/authStore'\r\nimport { AuthStore } from '../types'\r\n\r\nexport const AuthContext = createContext<AuthStore | null>(null)\r\n\r\ninterface AuthProviderProps {\r\n children: ReactNode;\r\n providerType?: AuthProviderType; // Default to 'supabase'\r\n storage?: IAuthStorage; // Optional custom storage implementation\r\n}\r\n\r\nexport const AuthProvider = ({ children, providerType = 'supabase', storage }: AuthProviderProps) => {\r\n const [authProvider, setAuthProvider] = useState<IAuthProvider | null>(null);\r\n const [useAuthStore, setUseAuthStore] = useState<any>(null);\r\n\r\n useEffect(() => {\r\n const initializeProvider = async () => {\r\n try {\r\n const authStorage = storage || createAuthStorage();\r\n const provider = await AuthProviderFactory.getProvider({ \r\n type: providerType,\r\n validateConfig: true,\r\n useSingleton: true,\r\n storage: authStorage\r\n });\r\n setAuthProvider(provider);\r\n setUseAuthStore(createAuthStore({ authProvider: provider }));\r\n } catch (error) {\r\n console.error('Failed to initialize auth provider:', error);\r\n }\r\n };\r\n\r\n initializeProvider();\r\n }, [providerType, storage]);\r\n\r\n useEffect(() => {\r\n if (!authProvider || !useAuthStore) return;\r\n\r\n const subscriptionResult = authProvider.onAuthStateChange((event: AuthEvent, session: AuthSession | null) => {\r\n useAuthStore.getState().updateUser(session?.user || null);\r\n useAuthStore.getState().setLoading(false);\r\n });\r\n\r\n let unsubscribe: (() => void) | undefined;\r\n\r\n // Check if the subscription object has a 'data' property with a 'subscription' property\r\n if ('data' in subscriptionResult && subscriptionResult.data && 'subscription' in subscriptionResult.data && typeof subscriptionResult.data.subscription === 'object' && subscriptionResult.data.subscription !== null && 'unsubscribe' in subscriptionResult.data.subscription && typeof subscriptionResult.data.subscription.unsubscribe === 'function') {\r\n unsubscribe = subscriptionResult.data.subscription.unsubscribe as () => void;\r\n } else if ('data' in subscriptionResult && subscriptionResult.data && 'unsubscribe' in subscriptionResult.data && typeof subscriptionResult.data.unsubscribe === 'function') {\r\n // Handle the case where unsubscribe is directly under data\r\n unsubscribe = subscriptionResult.data.unsubscribe as () => void;\r\n } else if ('unsubscribe' in subscriptionResult && typeof subscriptionResult.unsubscribe === 'function') {\r\n // Handle the case where unsubscribe is directly on the result object (less likely based on IAuthProvider, but for robustness)\r\n unsubscribe = subscriptionResult.unsubscribe as () => void;\r\n }\r\n\r\n // Initial user check\r\n authProvider.getUser().then((user: any) => {\r\n useAuthStore.getState().updateUser(user);\r\n useAuthStore.getState().setLoading(false);\r\n }).catch((error: any) => {\r\n console.error('Failed to get initial user:', error);\r\n useAuthStore.getState().setLoading(false);\r\n });\r\n\r\n return () => {\r\n if (unsubscribe) {\r\n unsubscribe();\r\n }\r\n };\r\n }, [authProvider, useAuthStore]);\r\n\r\n if (!useAuthStore) {\r\n return <div>Loading authentication...</div>;\r\n }\r\n\r\n return <AuthContext.Provider value={useAuthStore.getState()}>{children}</AuthContext.Provider>\r\n}\r\n\r\n","import { useState, useContext } from 'react';\r\nimport { AuthContext } from '../components/AuthProvider';\r\nimport { AuthError, AuthErrorType, OAuthProvider } from '../core/IAuthProvider';\r\n\r\nexport interface UseAuthFormOptions {\r\n onSuccess?: () => void;\r\n onError?: (error: AuthError) => void;\r\n redirectUrl?: string;\r\n}\r\n\r\nexport interface AuthFormState {\r\n email: string;\r\n password: string;\r\n confirmPassword: string;\r\n loading: boolean;\r\n error: string | null;\r\n message: string | null;\r\n}\r\n\r\nexport interface AuthFormActions {\r\n setEmail: (email: string) => void;\r\n setPassword: (password: string) => void;\r\n setConfirmPassword: (password: string) => void;\r\n handleSignIn: () => Promise<void>;\r\n handleSignUp: () => Promise<void>;\r\n handleOAuthSignIn: (provider: OAuthProvider) => Promise<void>;\r\n handlePasswordReset: () => Promise<void>;\r\n handleMagicLink: () => Promise<void>;\r\n clearError: () => void;\r\n clearMessage: () => void;\r\n}\r\n\r\nexport const useAuthForm = (options: UseAuthFormOptions = {}): AuthFormState & AuthFormActions => {\r\n const auth = useContext(AuthContext);\r\n const [email, setEmail] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [confirmPassword, setConfirmPassword] = useState('');\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [message, setMessage] = useState<string | null>(null);\r\n\r\n if (!auth) {\r\n throw new Error('useAuthForm must be used within AuthProvider');\r\n }\r\n\r\n const clearError = () => setError(null);\r\n const clearMessage = () => setMessage(null);\r\n\r\n const handleSignIn = async () => {\r\n setLoading(true);\r\n setError(null);\r\n setMessage(null);\r\n \r\n try {\r\n await auth.signIn(email, password);\r\n options.onSuccess?.();\r\n } catch (err) {\r\n const authError = err instanceof AuthError ? err : new AuthError(AuthErrorType.PROVIDER_ERROR, (err as Error).message);\r\n setError(authError.message);\r\n options.onError?.(authError);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const handleSignUp = async () => {\r\n if (password !== confirmPassword) {\r\n setError('Passwords do not match');\r\n return;\r\n }\r\n\r\n setLoading(true);\r\n setError(null);\r\n setMessage(null);\r\n \r\n try {\r\n await auth.signUp(email, password);\r\n setMessage('Check your email to confirm your account');\r\n options.onSuccess?.();\r\n } catch (err) {\r\n const authError = err instanceof AuthError ? err : new AuthError(AuthErrorType.PROVIDER_ERROR, (err as Error).message);\r\n setError(authError.message);\r\n options.onError?.(authError);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const handleOAuthSignIn = async (provider: OAuthProvider) => {\r\n setLoading(true);\r\n setError(null);\r\n \r\n try {\r\n await auth.signInWithOAuth(provider, options.redirectUrl);\r\n options.onSuccess?.();\r\n } catch (err) {\r\n const authError = err instanceof AuthError ? err : new AuthError(AuthErrorType.PROVIDER_ERROR, (err as Error).message);\r\n setError(authError.message);\r\n options.onError?.(authError);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const handlePasswordReset = async () => {\r\n if (!email) {\r\n setError('Please enter your email address');\r\n return;\r\n }\r\n\r\n setLoading(true);\r\n setError(null);\r\n setMessage(null);\r\n \r\n try {\r\n await auth.resetPassword(email);\r\n setMessage('Password reset email sent');\r\n } catch (err) {\r\n const authError = err instanceof AuthError ? err : new AuthError(AuthErrorType.PROVIDER_ERROR, (err as Error).message);\r\n setError(authError.message);\r\n options.onError?.(authError);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const handleMagicLink = async () => {\r\n if (!email) {\r\n setError('Please enter your email address');\r\n return;\r\n }\r\n\r\n setLoading(true);\r\n setError(null);\r\n setMessage(null);\r\n \r\n try {\r\n await auth.signInWithMagicLink(email, options.redirectUrl);\r\n setMessage('Magic link sent to your email');\r\n } catch (err) {\r\n const authError = err instanceof AuthError ? err : new AuthError(AuthErrorType.PROVIDER_ERROR, (err as Error).message);\r\n setError(authError.message);\r\n options.onError?.(authError);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n return {\r\n // State\r\n email,\r\n password,\r\n confirmPassword,\r\n loading,\r\n error,\r\n message,\r\n // Actions\r\n setEmail,\r\n setPassword,\r\n setConfirmPassword,\r\n handleSignIn,\r\n handleSignUp,\r\n handleOAuthSignIn,\r\n handlePasswordReset,\r\n handleMagicLink,\r\n clearError,\r\n clearMessage,\r\n };\r\n};\r\n\r\n","import React from 'react';\r\nimport { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert } from 'react-native';\r\nimport { useAuthForm } from '../../hooks/useAuthForm';\r\nimport { OAuthProvider } from '../../core/IAuthProvider';\r\n\r\nexport interface AuthFormProps {\r\n mode?: 'signin' | 'signup' | 'reset';\r\n onSuccess?: () => void;\r\n onModeChange?: (mode: 'signin' | 'signup' | 'reset') => void;\r\n redirectUrl?: string;\r\n showOAuth?: boolean;\r\n oauthProviders?: OAuthProvider[];\r\n style?: any;\r\n}\r\n\r\nexport const AuthForm: React.FC<AuthFormProps> = ({\r\n mode = 'signin',\r\n onSuccess,\r\n onModeChange,\r\n redirectUrl,\r\n showOAuth = true,\r\n oauthProviders = ['google', 'github'],\r\n style,\r\n}) => {\r\n const {\r\n email,\r\n password,\r\n confirmPassword,\r\n loading,\r\n error,\r\n message,\r\n setEmail,\r\n setPassword,\r\n setConfirmPassword,\r\n handleSignIn,\r\n handleSignUp,\r\n handleOAuthSignIn,\r\n handlePasswordReset,\r\n handleMagicLink,\r\n clearError,\r\n clearMessage,\r\n } = useAuthForm({ onSuccess, redirectUrl });\r\n\r\n const handleSubmit = async () => {\r\n if (mode === 'signin') {\r\n await handleSignIn();\r\n } else if (mode === 'signup') {\r\n await handleSignUp();\r\n } else if (mode === 'reset') {\r\n await handlePasswordReset();\r\n }\r\n };\r\n\r\n const handleOAuthPress = async (provider: OAuthProvider) => {\r\n try {\r\n await handleOAuthSignIn(provider);\r\n } catch (err) {\r\n Alert.alert('OAuth Error', 'OAuth sign-in is not fully supported in React Native yet. Please use email/password authentication.');\r\n }\r\n };\r\n\r\n const handleMagicLinkPress = async () => {\r\n await handleMagicLink();\r\n };\r\n\r\n React.useEffect(() => {\r\n if (error) {\r\n Alert.alert('Error', error, [{ text: 'OK', onPress: clearError }]);\r\n }\r\n }, [error, clearError]);\r\n\r\n React.useEffect(() => {\r\n if (message) {\r\n Alert.alert('Success', message, [{ text: 'OK', onPress: clearMessage }]);\r\n }\r\n }, [message, clearMessage]);\r\n\r\n return (\r\n <View style={[styles.container, style]}>\r\n <Text style={styles.title}>\r\n {mode === 'signin' ? 'Sign In' : mode === 'signup' ? 'Sign Up' : 'Reset Password'}\r\n </Text>\r\n\r\n <TextInput\r\n style={styles.input}\r\n placeholder=\"Email\"\r\n value={email}\r\n onChangeText={setEmail}\r\n keyboardType=\"email-address\"\r\n autoCapitalize=\"none\"\r\n autoCorrect={false}\r\n />\r\n\r\n {mode !== 'reset' && (\r\n <TextInput\r\n style={styles.input}\r\n placeholder=\"Password\"\r\n value={password}\r\n onChangeText={setPassword}\r\n secureTextEntry\r\n autoCapitalize=\"none\"\r\n autoCorrect={false}\r\n />\r\n )}\r\n\r\n {mode === 'signup' && (\r\n <TextInput\r\n style={styles.input}\r\n placeholder=\"Confirm Password\"\r\n value={confirmPassword}\r\n onChangeText={setConfirmPassword}\r\n secureTextEntry\r\n autoCapitalize=\"none\"\r\n autoCorrect={false}\r\n />\r\n )}\r\n\r\n <TouchableOpacity\r\n style={[styles.button, loading && styles.buttonDisabled]}\r\n onPress={handleSubmit}\r\n disabled={loading}\r\n >\r\n <Text style={styles.buttonText}>\r\n {loading ? 'Loading...' : mode === 'signin' ? 'Sign In' : mode === 'signup' ? 'Sign Up' : 'Send Reset Email'}\r\n </Text>\r\n </TouchableOpacity>\r\n\r\n {mode === 'signin' && (\r\n <TouchableOpacity\r\n style={styles.linkButton}\r\n onPress={handleMagicLinkPress}\r\n disabled={loading}\r\n >\r\n <Text style={styles.linkText}>Send Magic Link</Text>\r\n </TouchableOpacity>\r\n )}\r\n\r\n {showOAuth && mode !== 'reset' && (\r\n <View style={styles.oauthContainer}>\r\n <Text style={styles.oauthTitle}>Or continue with:</Text>\r\n {oauthProviders.map((provider) => (\r\n <TouchableOpacity\r\n key={provider}\r\n style={styles.oauthButton}\r\n onPress={() => handleOAuthPress(provider)}\r\n disabled={loading}\r\n >\r\n <Text style={styles.oauthButtonText}>\r\n {provider.charAt(0).toUpperCase() + provider.slice(1)}\r\n </Text>\r\n </TouchableOpacity>\r\n ))}\r\n </View>\r\n )}\r\n\r\n <View style={styles.footer}>\r\n {mode === 'signin' && (\r\n <>\r\n <TouchableOpacity onPress={() => onModeChange?.('signup')}>\r\n <Text style={styles.linkText}>Don't have an account? Sign up</Text>\r\n </TouchableOpacity>\r\n <TouchableOpacity onPress={() => onModeChange?.('reset')}>\r\n <Text style={styles.linkText}>Forgot password?</Text>\r\n </TouchableOpacity>\r\n </>\r\n )}\r\n {mode === 'signup' && (\r\n <TouchableOpacity onPress={() => onModeChange?.('signin')}>\r\n <Text style={styles.linkText}>Already have an account? Sign in</Text>\r\n </TouchableOpacity>\r\n )}\r\n {mode === 'reset' && (\r\n <TouchableOpacity onPress={() => onModeChange?.('signin')}>\r\n <Text style={styles.linkText}>Back to sign in</Text>\r\n </TouchableOpacity>\r\n )}\r\n </View>\r\n </View>\r\n );\r\n};\r\n\r\nconst styles = StyleSheet.create({\r\n container: {\r\n padding: 20,\r\n backgroundColor: '#fff',\r\n },\r\n title: {\r\n fontSize: 24,\r\n fontWeight: 'bold',\r\n textAlign: 'center',\r\n marginBottom: 30,\r\n color: '#333',\r\n },\r\n input: {\r\n borderWidth: 1,\r\n borderColor: '#ddd',\r\n borderRadius: 8,\r\n padding: 15,\r\n marginBottom: 15,\r\n fontSize: 16,\r\n backgroundColor: '#f9f9f9',\r\n },\r\n button: {\r\n backgroundColor: '#007AFF',\r\n borderRadius: 8,\r\n padding: 15,\r\n alignItems: 'center',\r\n marginBottom: 15,\r\n },\r\n buttonDisabled: {\r\n backgroundColor: '#ccc',\r\n },\r\n buttonText: {\r\n color: '#fff',\r\n fontSize: 16,\r\n fontWeight: '600',\r\n },\r\n linkButton: {\r\n alignItems: 'center',\r\n marginBottom: 20,\r\n },\r\n linkText: {\r\n color: '#007AFF',\r\n fontSize: 14,\r\n textAlign: 'center',\r\n marginVertical: 5,\r\n },\r\n oauthContainer: {\r\n marginTop: 20,\r\n paddingTop: 20,\r\n borderTopWidth: 1,\r\n borderTopColor: '#eee',\r\n },\r\n oauthTitle: {\r\n textAlign: 'center',\r\n color: '#666',\r\n marginBottom: 15,\r\n fontSize: 14,\r\n },\r\n oauthButton: {\r\n borderWidth: 1,\r\n borderColor: '#ddd',\r\n borderRadius: 8,\r\n padding: 15,\r\n alignItems: 'center',\r\n marginBottom: 10,\r\n backgroundColor: '#f9f9f9',\r\n },\r\n oauthButtonText: {\r\n color: '#333',\r\n fontSize: 16,\r\n fontWeight: '500',\r\n },\r\n footer: {\r\n marginTop: 20,\r\n alignItems: 'center',\r\n },\r\n});\r\n\r\n","\r\n'use client'\r\nimport { useEffect, useContext } from 'react'\r\nimport { AuthContext } from '../components/AuthProvider'\r\n\r\nexport const useAuth = () => {\r\n const store = useContext(AuthContext)\r\n\r\n if (!store) {\r\n throw new Error('useAuth must be used within an AuthProvider');\r\n }\r\n\r\n useEffect(() => {\r\n // The onAuthStateChange subscription is now handled within AuthProvider.tsx\r\n // Initial user check is also handled there.\r\n // No need to re-subscribe or re-check here.\r\n\r\n // Clean up function for the effect\r\n return () => {\r\n // Any cleanup specific to this hook can go here if needed\r\n };\r\n }, [store]); // Depend on store to re-run if the store instance changes\r\n\r\n return {\r\n ...store,\r\n }\r\n}\r\n\r\n\r\n","import React from 'react';\r\nimport { View, Text, TouchableOpacity, StyleSheet, Image } from 'react-native';\r\nimport { useAuth } from '../../hooks/useAuth';\r\n\r\nexport interface AuthStatusProps {\r\n showSignOut?: boolean;\r\n showUserInfo?: boolean;\r\n onSignOut?: () => void;\r\n style?: any;\r\n}\r\n\r\nexport const AuthStatus: React.FC<AuthStatusProps> = ({\r\n showSignOut = true,\r\n showUserInfo = true,\r\n onSignOut,\r\n style,\r\n}) => {\r\n const { user, loading, signOut } = useAuth();\r\n\r\n const handleSignOut = async () => {\r\n try {\r\n await signOut();\r\n onSignOut?.();\r\n } catch (error) {\r\n console.error('Sign out error:', error);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <View style={[styles.container, style]}>\r\n <Text style={styles.loadingText}>Loading...</Text>\r\n </View>\r\n );\r\n }\r\n\r\n if (!user) {\r\n return (\r\n <View style={[styles.container, style]}>\r\n <Text style={styles.statusText}>Not signed in</Text>\r\n </View>\r\n );\r\n }\r\n\r\n return (\r\n <View style={[styles.container, style]}>\r\n {showUserInfo && (\r\n <View style={styles.userInfo}>\r\n {user.photoURL && (\r\n <Image source={{ uri: user.photoURL }} style={styles.avatar} />\r\n )}\r\n <View style={styles.userDetails}>\r\n {user.displayName && (\r\n <Text style={styles.displayName}>{user.displayName}</Text>\r\n )}\r\n <Text style={styles.email}>{user.email}</Text>\r\n </View>\r\n </View>\r\n )}\r\n \r\n {showSignOut && (\r\n <TouchableOpacity style={styles.signOutButton} onPress={handleSignOut}>\r\n <Text style={styles.signOutText}>Sign Out</Text>\r\n </TouchableOpacity>\r\n )}\r\n </View>\r\n );\r\n};\r\n\r\nconst styles = StyleSheet.create({\r\n container: {\r\n padding: 15,\r\n backgroundColor: '#f9f9f9',\r\n borderRadius: 8,\r\n margin: 10,\r\n },\r\n loadingText: {\r\n textAlign: 'center',\r\n color: '#666',\r\n fontSize: 16,\r\n },\r\n statusText: {\r\n textAlign: 'center',\r\n color: '#666',\r\n fontSize: 16,\r\n },\r\n userInfo: {\r\n flexDirection: 'row',\r\n alignItems: 'center',\r\n marginBottom: 15,\r\n },\r\n avatar: {\r\n width: 50,\r\n height: 50,\r\n borderRadius: 25,\r\n marginRight: 15,\r\n },\r\n userDetails: {\r\n flex: 1,\r\n },\r\n displayName: {\r\n fontSize: 18,\r\n fontWeight: '600',\r\n color: '#333',\r\n marginBottom: 2,\r\n },\r\n email: {\r\n fontSize: 14,\r\n color: '#666',\r\n },\r\n signOutButton: {\r\n backgroundColor: '#FF3B30',\r\n borderRadius: 6,\r\n padding: 12,\r\n alignItems: 'center',\r\n },\r\n signOutText: {\r\n color: '#fff',\r\n fontSize: 16,\r\n fontWeight: '600',\r\n },\r\n});\r\n\r\n","import { useEffect, useContext } from 'react';\r\nimport { AuthContext } from '../components/AuthProvider';\r\n\r\nexport interface UseProtectedRouteOptions {\r\n redirectTo?: string;\r\n requiredRoles?: string[];\r\n onUnauthorized?: () => void;\r\n onUnauthenticated?: () => void;\r\n}\r\n\r\nexport const useProtectedRoute = (options: UseProtectedRouteOptions = {}) => {\r\n const auth = useContext(AuthContext);\r\n\r\n useEffect(() => {\r\n if (!auth || auth.loading) return;\r\n\r\n const checkAuth = async () => {\r\n const user = await auth.getUser();\r\n \r\n if (!user) {\r\n options.onUnauthenticated?.();\r\n return;\r\n }\r\n\r\n if (options.requiredRoles && options.requiredRoles.length > 0) {\r\n const userRoles = user.roles || [];\r\n const hasRequiredRole = options.requiredRoles.some(role => userRoles.includes(role));\r\n \r\n if (!hasRequiredRole) {\r\n options.onUnauthorized?.();\r\n return;\r\n }\r\n }\r\n };\r\n\r\n checkAuth();\r\n\r\n // Listen for auth state changes\r\n const unsubscribe = auth.onAuthStateChange((event, session) => {\r\n if (!session?.user) {\r\n options.onUnauthenticated?.();\r\n }\r\n });\r\n\r\n return () => {\r\n if (typeof unsubscribe === 'function') {\r\n unsubscribe();\r\n } else if (unsubscribe && 'data' in unsubscribe && unsubscribe.data?.subscription?.unsubscribe) {\r\n unsubscribe.data.subscription.unsubscribe();\r\n }\r\n };\r\n }, [auth, options]);\r\n\r\n return {\r\n user: auth?.user,\r\n loading: auth?.loading,\r\n isAuthenticated: !!auth?.user,\r\n };\r\n};\r\n\r\n","import React from 'react';\r\nimport { View, Text, StyleSheet } from 'react-native';\r\nimport { useProtectedRoute } from '../../hooks/useProtectedRoute';\r\n\r\nexport interface ProtectedRouteProps {\r\n children: React.ReactNode;\r\n requiredRoles?: string[];\r\n fallback?: React.ReactNode;\r\n loadingComponent?: React.ReactNode;\r\n onUnauthenticated?: () => void;\r\n onUnauthorized?: () => void;\r\n}\r\n\r\nexport const ProtectedRoute: React.FC<ProtectedRouteProps> = ({\r\n children,\r\n requiredRoles,\r\n fallback,\r\n loadingComponent,\r\n onUnauthenticated,\r\n onUnauthorized,\r\n}) => {\r\n const { user, loading, isAuthenticated } = useProtectedRoute({\r\n requiredRoles,\r\n onUnauthenticated,\r\n onUnauthorized,\r\n });\r\n\r\n if (loading) {\r\n return (\r\n loadingComponent || (\r\n <View style={styles.container}>\r\n <Text style={styles.text}>Loading...</Text>\r\n </View>\r\n )\r\n );\r\n }\r\n\r\n if (!isAuthenticated) {\r\n return (\r\n fallback || (\r\n <View style={styles.container}>\r\n <Text style={styles.text}>Please sign in to access this content</Text>\r\n </View>\r\n )\r\n );\r\n }\r\n\r\n // Check role-based access\r\n if (requiredRoles && requiredRoles.length > 0) {\r\n const userRoles = user?.roles || [];\r\n const hasRequiredRole = requiredRoles.some(role => userRoles.includes(role));\r\n \r\n if (!hasRequiredRole) {\r\n return (\r\n fallback || (\r\n <View style={styles.container}>\r\n <Text style={styles.text}>You don't have permission to access this content</Text>\r\n </View>\r\n )\r\n );\r\n }\r\n }\r\n\r\n return <>{children}</>;\r\n};\r\n\r\nconst styles = StyleSheet.create({\r\n container: {\r\n flex: 1,\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n padding: 20,\r\n backgroundColor: '#f9f9f9',\r\n },\r\n text: {\r\n fontSize: 16,\r\n color: '#666',\r\n textAlign: 'center',\r\n },\r\n});\r\n\r\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React$1, { ReactNode } from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* OAuth provider types
|
|
6
|
+
*/
|
|
7
|
+
type OAuthProvider = 'google' | 'github' | 'facebook' | 'twitter' | 'discord' | 'apple';
|
|
8
|
+
|
|
9
|
+
type AuthMode = 'signIn' | 'signUp' | 'resetPassword' | 'magicLink';
|
|
10
|
+
interface AuthFormProps {
|
|
11
|
+
defaultMode?: AuthMode;
|
|
12
|
+
onSuccess?: () => void;
|
|
13
|
+
onError?: (error: Error) => void;
|
|
14
|
+
redirectTo?: string;
|
|
15
|
+
providers?: OAuthProvider[];
|
|
16
|
+
allowMagicLink?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare const AuthForm: React$1.FC<AuthFormProps>;
|
|
20
|
+
|
|
21
|
+
declare const AuthStatus: React.FC;
|
|
22
|
+
|
|
23
|
+
interface ProtectedRouteProps {
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
loginRoute?: string;
|
|
26
|
+
loadingComponent?: React.ReactNode;
|
|
27
|
+
}
|
|
28
|
+
declare const ProtectedRoute: React.FC<ProtectedRouteProps>;
|
|
29
|
+
|
|
30
|
+
interface RequirePermissionProps {
|
|
31
|
+
permission: string;
|
|
32
|
+
children: ReactNode;
|
|
33
|
+
fallback?: ReactNode;
|
|
34
|
+
}
|
|
35
|
+
declare function RequirePermission({ permission, children, fallback }: RequirePermissionProps): react_jsx_runtime.JSX.Element;
|
|
36
|
+
|
|
37
|
+
declare function TwoFactorSetup(): react_jsx_runtime.JSX.Element;
|
|
38
|
+
|
|
39
|
+
export { AuthForm, AuthStatus, ProtectedRoute, RequirePermission, TwoFactorSetup };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React$1, { ReactNode } from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* OAuth provider types
|
|
6
|
+
*/
|
|
7
|
+
type OAuthProvider = 'google' | 'github' | 'facebook' | 'twitter' | 'discord' | 'apple';
|
|
8
|
+
|
|
9
|
+
type AuthMode = 'signIn' | 'signUp' | 'resetPassword' | 'magicLink';
|
|
10
|
+
interface AuthFormProps {
|
|
11
|
+
defaultMode?: AuthMode;
|
|
12
|
+
onSuccess?: () => void;
|
|
13
|
+
onError?: (error: Error) => void;
|
|
14
|
+
redirectTo?: string;
|
|
15
|
+
providers?: OAuthProvider[];
|
|
16
|
+
allowMagicLink?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare const AuthForm: React$1.FC<AuthFormProps>;
|
|
20
|
+
|
|
21
|
+
declare const AuthStatus: React.FC;
|
|
22
|
+
|
|
23
|
+
interface ProtectedRouteProps {
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
loginRoute?: string;
|
|
26
|
+
loadingComponent?: React.ReactNode;
|
|
27
|
+
}
|
|
28
|
+
declare const ProtectedRoute: React.FC<ProtectedRouteProps>;
|
|
29
|
+
|
|
30
|
+
interface RequirePermissionProps {
|
|
31
|
+
permission: string;
|
|
32
|
+
children: ReactNode;
|
|
33
|
+
fallback?: ReactNode;
|
|
34
|
+
}
|
|
35
|
+
declare function RequirePermission({ permission, children, fallback }: RequirePermissionProps): react_jsx_runtime.JSX.Element;
|
|
36
|
+
|
|
37
|
+
declare function TwoFactorSetup(): react_jsx_runtime.JSX.Element;
|
|
38
|
+
|
|
39
|
+
export { AuthForm, AuthStatus, ProtectedRoute, RequirePermission, TwoFactorSetup };
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var navigation = require('next/navigation');
|
|
6
|
+
var authHelpersNextjs = require('@supabase/auth-helpers-nextjs');
|
|
7
|
+
|
|
8
|
+
var AuthContext = react.createContext(null);
|
|
9
|
+
var AuthForm = ({
|
|
10
|
+
defaultMode = "signIn",
|
|
11
|
+
onSuccess,
|
|
12
|
+
onError,
|
|
13
|
+
redirectTo,
|
|
14
|
+
providers = ["google", "github"],
|
|
15
|
+
allowMagicLink = true
|
|
16
|
+
}) => {
|
|
17
|
+
const [mode, setMode] = react.useState(defaultMode);
|
|
18
|
+
const [email, setEmail] = react.useState("");
|
|
19
|
+
const [password, setPassword] = react.useState("");
|
|
20
|
+
const [loading, setLoading] = react.useState(false);
|
|
21
|
+
const [error, setError] = react.useState(null);
|
|
22
|
+
const [message, setMessage] = react.useState(null);
|
|
23
|
+
const auth = react.useContext(AuthContext);
|
|
24
|
+
const handleSubmit = async (e) => {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
setError(null);
|
|
27
|
+
setMessage(null);
|
|
28
|
+
setLoading(true);
|
|
29
|
+
try {
|
|
30
|
+
switch (mode) {
|
|
31
|
+
case "signIn":
|
|
32
|
+
await (auth == null ? void 0 : auth.signIn(email, password));
|
|
33
|
+
break;
|
|
34
|
+
case "signUp":
|
|
35
|
+
await (auth == null ? void 0 : auth.signUp(email, password));
|
|
36
|
+
setMessage("Check your email to confirm your account");
|
|
37
|
+
break;
|
|
38
|
+
case "resetPassword":
|
|
39
|
+
await (auth == null ? void 0 : auth.resetPassword(email));
|
|
40
|
+
setMessage("Check your email for password reset instructions");
|
|
41
|
+
break;
|
|
42
|
+
case "magicLink":
|
|
43
|
+
await (auth == null ? void 0 : auth.signInWithMagicLink(email, redirectTo));
|
|
44
|
+
setMessage("Check your email for the magic link");
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
onSuccess == null ? void 0 : onSuccess();
|
|
48
|
+
} catch (err) {
|
|
49
|
+
const error2 = err;
|
|
50
|
+
setError(error2.message);
|
|
51
|
+
onError == null ? undefined : onError(error2);
|
|
52
|
+
} finally {
|
|
53
|
+
setLoading(false);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const handleOAuthSignIn = async (provider) => {
|
|
57
|
+
setError(null);
|
|
58
|
+
setLoading(true);
|
|
59
|
+
try {
|
|
60
|
+
await (auth == null ? void 0 : auth.signInWithOAuth(provider, redirectTo));
|
|
61
|
+
onSuccess == null ? void 0 : onSuccess();
|
|
62
|
+
} catch (err) {
|
|
63
|
+
const error2 = err;
|
|
64
|
+
setError(error2.message);
|
|
65
|
+
onError == null ? undefined : onError(error2);
|
|
66
|
+
} finally {
|
|
67
|
+
setLoading(false);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const providerDisplayNames = {
|
|
71
|
+
google: "Google",
|
|
72
|
+
github: "GitHub"
|
|
73
|
+
// Add more providers here as needed
|
|
74
|
+
};
|
|
75
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-md space-y-8", children: [
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-2xl font-bold text-center", children: [
|
|
77
|
+
mode === "signIn" && "Sign in to your account",
|
|
78
|
+
mode === "signUp" && "Create a new account",
|
|
79
|
+
mode === "resetPassword" && "Reset your password",
|
|
80
|
+
mode === "magicLink" && "Sign in with magic link"
|
|
81
|
+
] }) }),
|
|
82
|
+
/* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [
|
|
83
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
84
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "email", className: "block text-sm font-medium", children: "Email address" }),
|
|
85
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
86
|
+
"input",
|
|
87
|
+
{
|
|
88
|
+
id: "email",
|
|
89
|
+
type: "email",
|
|
90
|
+
required: true,
|
|
91
|
+
value: email,
|
|
92
|
+
onChange: (e) => setEmail(e.target.value),
|
|
93
|
+
className: "mt-1 block w-full rounded-md border border-gray-300 px-3 py-2"
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
] }),
|
|
97
|
+
(mode === "signIn" || mode === "signUp") && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
98
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "password", className: "block text-sm font-medium", children: "Password" }),
|
|
99
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
100
|
+
"input",
|
|
101
|
+
{
|
|
102
|
+
id: "password",
|
|
103
|
+
type: "password",
|
|
104
|
+
required: true,
|
|
105
|
+
value: password,
|
|
106
|
+
onChange: (e) => setPassword(e.target.value),
|
|
107
|
+
className: "mt-1 block w-full rounded-md border border-gray-300 px-3 py-2"
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
] }),
|
|
111
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-red-600", children: error }),
|
|
112
|
+
message && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-green-600", children: message }),
|
|
113
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
114
|
+
"button",
|
|
115
|
+
{
|
|
116
|
+
type: "submit",
|
|
117
|
+
disabled: loading,
|
|
118
|
+
className: "w-full py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50",
|
|
119
|
+
children: loading ? "Loading..." : mode === "signIn" ? "Sign in" : mode === "signUp" ? "Sign up" : mode === "resetPassword" ? "Reset password" : "Send magic link"
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
] }),
|
|
123
|
+
providers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6", children: [
|
|
124
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
125
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full border-t border-gray-300" }) }),
|
|
126
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex justify-center text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-2 bg-white text-gray-500", children: "Or continue with" }) })
|
|
127
|
+
] }),
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 grid grid-cols-2 gap-3", children: providers.map((provider) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
129
|
+
"button",
|
|
130
|
+
{
|
|
131
|
+
onClick: () => handleOAuthSignIn(provider),
|
|
132
|
+
className: "w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-500 hover:bg-gray-50",
|
|
133
|
+
children: providerDisplayNames[provider] || provider.charAt(0).toUpperCase() + provider.slice(1)
|
|
134
|
+
},
|
|
135
|
+
provider
|
|
136
|
+
)) })
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-center space-x-4", children: [
|
|
139
|
+
mode !== "signIn" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
140
|
+
"button",
|
|
141
|
+
{
|
|
142
|
+
type: "button",
|
|
143
|
+
onClick: () => setMode("signIn"),
|
|
144
|
+
className: "text-blue-600 hover:text-blue-500",
|
|
145
|
+
children: "Sign in"
|
|
146
|
+
}
|
|
147
|
+
),
|
|
148
|
+
mode !== "signUp" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
149
|
+
"button",
|
|
150
|
+
{
|
|
151
|
+
type: "button",
|
|
152
|
+
onClick: () => setMode("signUp"),
|
|
153
|
+
className: "text-blue-600 hover:text-blue-500",
|
|
154
|
+
children: "Sign up"
|
|
155
|
+
}
|
|
156
|
+
),
|
|
157
|
+
mode !== "resetPassword" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
158
|
+
"button",
|
|
159
|
+
{
|
|
160
|
+
type: "button",
|
|
161
|
+
onClick: () => setMode("resetPassword"),
|
|
162
|
+
className: "text-blue-600 hover:text-blue-500",
|
|
163
|
+
children: "Forgot password?"
|
|
164
|
+
}
|
|
165
|
+
),
|
|
166
|
+
allowMagicLink && mode !== "magicLink" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
167
|
+
"button",
|
|
168
|
+
{
|
|
169
|
+
type: "button",
|
|
170
|
+
onClick: () => setMode("magicLink"),
|
|
171
|
+
className: "text-blue-600 hover:text-blue-500",
|
|
172
|
+
children: "Magic link"
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
] })
|
|
176
|
+
] });
|
|
177
|
+
};
|
|
178
|
+
var AuthStatus = () => {
|
|
179
|
+
const auth = react.useContext(AuthContext);
|
|
180
|
+
if (!auth) throw new Error("AuthContext not provided");
|
|
181
|
+
const { user, signOut, loading } = auth;
|
|
182
|
+
if (loading) {
|
|
183
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading..." });
|
|
184
|
+
}
|
|
185
|
+
if (!user) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
189
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: user.email }),
|
|
190
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
191
|
+
"button",
|
|
192
|
+
{
|
|
193
|
+
onClick: () => signOut(),
|
|
194
|
+
className: "text-sm text-red-600 hover:text-red-500",
|
|
195
|
+
children: "Sign out"
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
] });
|
|
199
|
+
};
|
|
200
|
+
var ProtectedRoute = ({
|
|
201
|
+
children,
|
|
202
|
+
loginRoute = "/login",
|
|
203
|
+
loadingComponent = /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading..." })
|
|
204
|
+
}) => {
|
|
205
|
+
const auth = react.useContext(AuthContext);
|
|
206
|
+
if (!auth) throw new Error("AuthContext not provided");
|
|
207
|
+
const { user, loading } = auth;
|
|
208
|
+
const router = navigation.useRouter();
|
|
209
|
+
const pathname = navigation.usePathname();
|
|
210
|
+
react.useEffect(() => {
|
|
211
|
+
if (!loading && !user) {
|
|
212
|
+
router.replace(`${loginRoute}?returnUrl=${encodeURIComponent(pathname)}`);
|
|
213
|
+
}
|
|
214
|
+
}, [user, loading, router, pathname, loginRoute]);
|
|
215
|
+
if (loading) {
|
|
216
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: loadingComponent });
|
|
217
|
+
}
|
|
218
|
+
if (!user) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
222
|
+
};
|
|
223
|
+
function useRBAC() {
|
|
224
|
+
const auth = react.useContext(AuthContext);
|
|
225
|
+
if (!auth) throw new Error("AuthContext not provided");
|
|
226
|
+
const { user } = auth;
|
|
227
|
+
const checkPermission = (permission) => {
|
|
228
|
+
var _a, _b, _c;
|
|
229
|
+
const userRole = (_a = user == null ? undefined : user.metadata) == null ? undefined : _a.role;
|
|
230
|
+
return (_c = (_b = userRole == null ? undefined : userRole.permissions) == null ? undefined : _b.includes(permission)) != null ? _c : false;
|
|
231
|
+
};
|
|
232
|
+
const hasRole = (role) => {
|
|
233
|
+
var _a;
|
|
234
|
+
const userRole = (_a = user == null ? undefined : user.metadata) == null ? undefined : _a.role;
|
|
235
|
+
return (userRole == null ? undefined : userRole.role) === role;
|
|
236
|
+
};
|
|
237
|
+
return {
|
|
238
|
+
checkPermission,
|
|
239
|
+
hasRole
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function RequirePermission({ permission, children, fallback = null }) {
|
|
243
|
+
const { checkPermission } = useRBAC();
|
|
244
|
+
if (!checkPermission(permission)) {
|
|
245
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
|
|
246
|
+
}
|
|
247
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
248
|
+
}
|
|
249
|
+
var createClient = () => {
|
|
250
|
+
if (!process.env.NEXT_PUBLIC_SUPABASE_URL || !process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) {
|
|
251
|
+
throw new Error("Missing Supabase environment variables");
|
|
252
|
+
}
|
|
253
|
+
return authHelpersNextjs.createClientComponentClient();
|
|
254
|
+
};
|
|
255
|
+
var supabase = (() => {
|
|
256
|
+
try {
|
|
257
|
+
if (process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) {
|
|
258
|
+
return createClient();
|
|
259
|
+
}
|
|
260
|
+
} catch (error) {
|
|
261
|
+
console.warn("Supabase client not initialized: environment variables not available");
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
})();
|
|
265
|
+
|
|
266
|
+
// src/hooks/use2FA.ts
|
|
267
|
+
function use2FA() {
|
|
268
|
+
const [loading, setLoading] = react.useState(false);
|
|
269
|
+
const [error, setError] = react.useState(null);
|
|
270
|
+
const setup2FA = async () => {
|
|
271
|
+
if (!supabase) {
|
|
272
|
+
throw new Error("Supabase client not initialized. Please check your environment variables.");
|
|
273
|
+
}
|
|
274
|
+
setLoading(true);
|
|
275
|
+
setError(null);
|
|
276
|
+
try {
|
|
277
|
+
const { data, error: error2 } = await supabase.auth.mfa.enroll({
|
|
278
|
+
factorType: "totp"
|
|
279
|
+
});
|
|
280
|
+
if (error2) throw error2;
|
|
281
|
+
return data;
|
|
282
|
+
} catch (err) {
|
|
283
|
+
const error2 = err;
|
|
284
|
+
setError(error2);
|
|
285
|
+
throw error2;
|
|
286
|
+
} finally {
|
|
287
|
+
setLoading(false);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
const verify2FA = async (factorId, challengeId, code) => {
|
|
291
|
+
if (!supabase) {
|
|
292
|
+
throw new Error("Supabase client not initialized. Please check your environment variables.");
|
|
293
|
+
}
|
|
294
|
+
setLoading(true);
|
|
295
|
+
setError(null);
|
|
296
|
+
try {
|
|
297
|
+
const { data, error: error2 } = await supabase.auth.mfa.verify({
|
|
298
|
+
factorId,
|
|
299
|
+
challengeId,
|
|
300
|
+
code
|
|
301
|
+
});
|
|
302
|
+
if (error2) throw error2;
|
|
303
|
+
return data;
|
|
304
|
+
} catch (err) {
|
|
305
|
+
const error2 = err;
|
|
306
|
+
setError(error2);
|
|
307
|
+
throw error2;
|
|
308
|
+
} finally {
|
|
309
|
+
setLoading(false);
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
const unenroll2FA = async (factorId) => {
|
|
313
|
+
if (!supabase) {
|
|
314
|
+
throw new Error("Supabase client not initialized. Please check your environment variables.");
|
|
315
|
+
}
|
|
316
|
+
setLoading(true);
|
|
317
|
+
setError(null);
|
|
318
|
+
try {
|
|
319
|
+
const { data, error: error2 } = await supabase.auth.mfa.unenroll({
|
|
320
|
+
factorId
|
|
321
|
+
});
|
|
322
|
+
if (error2) throw error2;
|
|
323
|
+
return data;
|
|
324
|
+
} catch (err) {
|
|
325
|
+
const error2 = err;
|
|
326
|
+
setError(error2);
|
|
327
|
+
throw error2;
|
|
328
|
+
} finally {
|
|
329
|
+
setLoading(false);
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
return {
|
|
333
|
+
setup2FA,
|
|
334
|
+
verify2FA,
|
|
335
|
+
unenroll2FA,
|
|
336
|
+
loading,
|
|
337
|
+
error
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function TwoFactorSetup() {
|
|
341
|
+
const { setup2FA, verify2FA, loading, error } = use2FA();
|
|
342
|
+
const [qrCode, setQrCode] = react.useState("");
|
|
343
|
+
const [factorId, setFactorId] = react.useState("");
|
|
344
|
+
react.useState("");
|
|
345
|
+
const [verificationCode, setVerificationCode] = react.useState("");
|
|
346
|
+
const [setupComplete, setSetupComplete] = react.useState(false);
|
|
347
|
+
const handleSetup = async () => {
|
|
348
|
+
try {
|
|
349
|
+
const data = await setup2FA();
|
|
350
|
+
setFactorId(data.id);
|
|
351
|
+
setQrCode(data.totp.qr_code);
|
|
352
|
+
} catch (error2) {
|
|
353
|
+
console.error("Failed to setup 2FA:", error2);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
const handleVerify = async () => {
|
|
357
|
+
if (!factorId || !verificationCode) {
|
|
358
|
+
console.error("Missing factor ID or verification code");
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
const mockChallengeId = "challenge-" + Date.now();
|
|
363
|
+
await verify2FA(factorId, mockChallengeId, verificationCode);
|
|
364
|
+
setSetupComplete(true);
|
|
365
|
+
} catch (error2) {
|
|
366
|
+
console.error("Failed to verify 2FA:", error2);
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
370
|
+
!qrCode && /* @__PURE__ */ jsxRuntime.jsx(
|
|
371
|
+
"button",
|
|
372
|
+
{
|
|
373
|
+
onClick: handleSetup,
|
|
374
|
+
disabled: loading,
|
|
375
|
+
className: "px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50",
|
|
376
|
+
children: loading ? "Setting up..." : "Setup 2FA"
|
|
377
|
+
}
|
|
378
|
+
),
|
|
379
|
+
qrCode && !setupComplete && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
380
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-600", children: "Scan this QR code with your authenticator app:" }),
|
|
381
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: qrCode, alt: "2FA QR Code", className: "border rounded" }) }),
|
|
382
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
383
|
+
"input",
|
|
384
|
+
{
|
|
385
|
+
type: "text",
|
|
386
|
+
value: verificationCode,
|
|
387
|
+
onChange: (e) => setVerificationCode(e.target.value),
|
|
388
|
+
placeholder: "Enter 6-digit code from your app",
|
|
389
|
+
className: "w-full px-3 py-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500",
|
|
390
|
+
maxLength: 6
|
|
391
|
+
}
|
|
392
|
+
) }),
|
|
393
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
394
|
+
"button",
|
|
395
|
+
{
|
|
396
|
+
onClick: handleVerify,
|
|
397
|
+
disabled: loading || !verificationCode || verificationCode.length !== 6,
|
|
398
|
+
className: "w-full px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50",
|
|
399
|
+
children: loading ? "Verifying..." : "Verify & Complete Setup"
|
|
400
|
+
}
|
|
401
|
+
)
|
|
402
|
+
] }),
|
|
403
|
+
setupComplete && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 bg-green-100 border border-green-400 text-green-700 rounded", children: "\u2705 2FA setup complete! Your account is now more secure." }),
|
|
404
|
+
error && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 bg-red-100 border border-red-400 text-red-700 rounded", children: [
|
|
405
|
+
"\u274C Error: ",
|
|
406
|
+
error.message
|
|
407
|
+
] })
|
|
408
|
+
] });
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
exports.AuthForm = AuthForm;
|
|
412
|
+
exports.AuthStatus = AuthStatus;
|
|
413
|
+
exports.ProtectedRoute = ProtectedRoute;
|
|
414
|
+
exports.RequirePermission = RequirePermission;
|
|
415
|
+
exports.TwoFactorSetup = TwoFactorSetup;
|
|
416
|
+
//# sourceMappingURL=index.js.map
|
|
417
|
+
//# sourceMappingURL=index.js.map
|