fix(mobile): prevent supabaseUrl crash on startup with fallback auth config
This commit is contained in:
parent
9b24bbc576
commit
a9c9a1ca6e
4 changed files with 35 additions and 17 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
import { createContext, useContext, useEffect, useState, useCallback } from 'react'
|
import { createContext, useContext, useEffect, useState, useCallback } from 'react'
|
||||||
import type { ReactNode } from 'react'
|
import type { ReactNode } from 'react'
|
||||||
import type { User, Session } from '@supabase/supabase-js'
|
import type { User, Session } from '@supabase/supabase-js'
|
||||||
import { supabase } from './supabase'
|
import { supabase, isSupabaseConfigured } from './supabase'
|
||||||
|
|
||||||
interface AuthContextValue {
|
interface AuthContextValue {
|
||||||
user: User | null
|
user: User | null
|
||||||
|
|
@ -14,28 +14,41 @@ interface AuthContextValue {
|
||||||
const AuthContext = createContext<AuthContextValue>({
|
const AuthContext = createContext<AuthContextValue>({
|
||||||
user: null,
|
user: null,
|
||||||
session: null,
|
session: null,
|
||||||
loading: true,
|
loading: false,
|
||||||
devBypass: () => {},
|
devBypass: () => {},
|
||||||
})
|
})
|
||||||
|
|
||||||
export function AuthProvider({ children }: { children: ReactNode }): React.ReactElement {
|
export function AuthProvider({ children }: { children: ReactNode }): React.ReactElement {
|
||||||
const [user, setUser] = useState<User | null>(null)
|
const [user, setUser] = useState<User | null>(null)
|
||||||
const [session, setSession] = useState<Session | null>(null)
|
const [session, setSession] = useState<Session | null>(null)
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
supabase.auth.getSession().then(({ data: { session: s } }) => {
|
if (!isSupabaseConfigured()) {
|
||||||
setSession(s)
|
|
||||||
setUser(s?.user ?? null)
|
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
})
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, s) => {
|
try {
|
||||||
setSession(s)
|
supabase.auth.getSession()
|
||||||
setUser(s?.user ?? null)
|
.then(({ data: { session: s } }) => {
|
||||||
})
|
setSession(s)
|
||||||
|
setUser(s?.user ?? null)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
|
||||||
return () => subscription.unsubscribe()
|
const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, s) => {
|
||||||
|
setSession(s)
|
||||||
|
setUser(s?.user ?? null)
|
||||||
|
})
|
||||||
|
|
||||||
|
return () => subscription?.unsubscribe?.()
|
||||||
|
} catch {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const devBypass = useCallback(() => {
|
const devBypass = useCallback(() => {
|
||||||
|
|
@ -53,3 +66,4 @@ export function AuthProvider({ children }: { children: ReactNode }): React.React
|
||||||
export function useAuth(): AuthContextValue {
|
export function useAuth(): AuthContextValue {
|
||||||
return useContext(AuthContext)
|
return useContext(AuthContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,16 @@ import 'react-native-url-polyfill/auto'
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||||
import { createClient, type SupabaseClient } from '@supabase/supabase-js'
|
import { createClient, type SupabaseClient } from '@supabase/supabase-js'
|
||||||
|
|
||||||
// TODO: move to env config or supabase-config.ts
|
// Fallback dummy credentials to prevent createClient crash when unconfigured
|
||||||
|
const FALLBACK_URL = 'https://auth.d3ro.chanpaca.net'
|
||||||
|
const FALLBACK_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.dummy_anon_key'
|
||||||
|
|
||||||
const SUPABASE_URL = ''
|
const SUPABASE_URL = ''
|
||||||
const SUPABASE_ANON_KEY = ''
|
const SUPABASE_ANON_KEY = ''
|
||||||
|
|
||||||
export const supabase: SupabaseClient = createClient(
|
export const supabase: SupabaseClient = createClient(
|
||||||
SUPABASE_URL,
|
SUPABASE_URL || FALLBACK_URL,
|
||||||
SUPABASE_ANON_KEY,
|
SUPABASE_ANON_KEY || FALLBACK_ANON_KEY,
|
||||||
{
|
{
|
||||||
auth: {
|
auth: {
|
||||||
storage: AsyncStorage,
|
storage: AsyncStorage,
|
||||||
|
|
@ -23,3 +26,4 @@ export const supabase: SupabaseClient = createClient(
|
||||||
export function isSupabaseConfigured(): boolean {
|
export function isSupabaseConfigured(): boolean {
|
||||||
return SUPABASE_URL.length > 0 && SUPABASE_ANON_KEY.length > 0
|
return SUPABASE_URL.length > 0 && SUPABASE_ANON_KEY.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ export const OS_CONFIGS: Record<ClientOSType, ClientOSInfo> = {
|
||||||
os: 'android',
|
os: 'android',
|
||||||
osName: 'Android',
|
osName: 'Android',
|
||||||
isMobile: true,
|
isMobile: true,
|
||||||
downloadUrl: 'https://git.chanpaca.net/attachments/5220bdb9-e8ce-4d6a-b016-dab08dd756b8',
|
downloadUrl: 'https://git.chanpaca.net/attachments/0b015367-dd8b-488c-8cc0-4db413b51792',
|
||||||
downloadFilename: 'd3ro-voice-v1.0.0-signed.apk',
|
downloadFilename: 'd3ro-voice-v1.0.0-signed.apk',
|
||||||
badgeText: 'ANDROID APK v1.0.0',
|
badgeText: 'ANDROID APK v1.0.0',
|
||||||
buttonLabelKo: 'Android용 무료 다운로드 (APK)',
|
buttonLabelKo: 'Android용 무료 다운로드 (APK)',
|
||||||
|
|
|
||||||
|
|
@ -277,7 +277,7 @@ export function Download() {
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<a
|
<a
|
||||||
href="https://git.chanpaca.net/attachments/5220bdb9-e8ce-4d6a-b016-dab08dd756b8"
|
href="https://git.chanpaca.net/attachments/0b015367-dd8b-488c-8cc0-4db413b51792"
|
||||||
download="d3ro-voice-v1.0.0-signed.apk"
|
download="d3ro-voice-v1.0.0-signed.apk"
|
||||||
className="w-full py-2.5 px-4 rounded-lg bg-surface-700 hover:bg-surface-600 border border-white/[0.08] hover:border-emerald-400/40 text-neutral-200 font-mono text-xs flex items-center justify-between transition-all"
|
className="w-full py-2.5 px-4 rounded-lg bg-surface-700 hover:bg-surface-600 border border-white/[0.08] hover:border-emerald-400/40 text-neutral-200 font-mono text-xs flex items-center justify-between transition-all"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue