fix: pwa, firebase and auth initial load issues
This commit is contained in:
@@ -14,7 +14,10 @@ export const useAchievements = () => {
|
|||||||
const loadAchievements = async () => {
|
const loadAchievements = async () => {
|
||||||
pending.value = true
|
pending.value = true
|
||||||
try {
|
try {
|
||||||
const data = await $fetch<{ achievements: Achievement[], stats: { total: number, completedTasks: number } }>('/api/achievements')
|
const auth = useAuth()
|
||||||
|
const data = await $fetch<{ achievements: Achievement[], stats: { total: number, completedTasks: number } }>('/api/achievements', {
|
||||||
|
headers: { Authorization: `Bearer ${auth.token.value}` }
|
||||||
|
})
|
||||||
achievements.value = data.achievements || []
|
achievements.value = data.achievements || []
|
||||||
stats.value = data.stats || { total: 0, completedTasks: 0 }
|
stats.value = data.stats || { total: 0, completedTasks: 0 }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -51,10 +51,21 @@ export const useAuth = () => {
|
|||||||
const initAuth = () => {
|
const initAuth = () => {
|
||||||
const auth = getAuth()
|
const auth = getAuth()
|
||||||
onAuthStateChanged(auth, async (firebaseUser) => {
|
onAuthStateChanged(auth, async (firebaseUser) => {
|
||||||
if (firebaseUser) {
|
// If user is authenticated in Firebase but we lost our backend token, try to restore
|
||||||
const idToken = await firebaseUser.getIdToken()
|
if (firebaseUser && !token.value) {
|
||||||
if (idToken !== token.value) {
|
try {
|
||||||
token.value = idToken
|
const idToken = await firebaseUser.getIdToken()
|
||||||
|
const res = await $fetch<{ token: string; user: User }>('/api/auth/google', {
|
||||||
|
method: 'POST',
|
||||||
|
body: { idToken }
|
||||||
|
})
|
||||||
|
token.value = res.token
|
||||||
|
|
||||||
|
if (useRoute().path === '/login') {
|
||||||
|
navigateTo('/')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to restore backend auth from Firebase', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -87,9 +87,9 @@ const createNewCanvas = () => {
|
|||||||
|
|
||||||
// Redirect to specific canvas if ID is provided
|
// Redirect to specific canvas if ID is provided
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (auth.user) {
|
if (auth.isAuthenticated.value) {
|
||||||
// Load user's canvases
|
// Load user's canvases
|
||||||
console.log('Loading canvases for user:', auth.user.email)
|
console.log('Loading canvases for user:', auth.user.value?.email)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+22
-5
@@ -119,10 +119,19 @@ definePageMeta({
|
|||||||
|
|
||||||
const auth = useAuth()
|
const auth = useAuth()
|
||||||
const user = computed(() => auth.user)
|
const user = computed(() => auth.user)
|
||||||
const authFetch = (url, opts = {}) => $fetch(url, {
|
const authFetch = async (url, opts = {}) => {
|
||||||
...opts,
|
try {
|
||||||
headers: { Authorization: `Bearer ${auth.token.value}`, ...opts.headers }
|
return await $fetch(url, {
|
||||||
})
|
...opts,
|
||||||
|
headers: { Authorization: `Bearer ${auth.token.value}`, ...opts.headers }
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response?.status === 401) {
|
||||||
|
auth.logout()
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const canvases = ref([])
|
const canvases = ref([])
|
||||||
const userGroups = ref([])
|
const userGroups = ref([])
|
||||||
@@ -287,5 +296,13 @@ const getGroupName = (groupId) => {
|
|||||||
return group?.name || 'Unknown Group'
|
return group?.name || 'Unknown Group'
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(loadData)
|
onMounted(() => {
|
||||||
|
if (auth.isAuthenticated.value) {
|
||||||
|
loadData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => auth.isAuthenticated.value, (isAuth) => {
|
||||||
|
if (isAuth) loadData()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+22
-5
@@ -170,10 +170,19 @@ definePageMeta({
|
|||||||
|
|
||||||
const auth = useAuth()
|
const auth = useAuth()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const authFetch = (url, opts = {}) => $fetch(url, {
|
const authFetch = async (url, opts = {}) => {
|
||||||
...opts,
|
try {
|
||||||
headers: { Authorization: `Bearer ${auth.token.value}`, ...opts.headers }
|
return await $fetch(url, {
|
||||||
})
|
...opts,
|
||||||
|
headers: { Authorization: `Bearer ${auth.token.value}`, ...opts.headers }
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response?.status === 401) {
|
||||||
|
auth.logout()
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const profileId = computed(() => route.params.id || auth.user.value?.id)
|
const profileId = computed(() => route.params.id || auth.user.value?.id)
|
||||||
const currentUserId = computed(() => auth.user.value?.id || '')
|
const currentUserId = computed(() => auth.user.value?.id || '')
|
||||||
@@ -329,6 +338,14 @@ const followButtonClass = computed(() => {
|
|||||||
: 'bg-blue-600 hover:bg-blue-500 text-white'
|
: 'bg-blue-600 hover:bg-blue-500 text-white'
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(loadProfile)
|
onMounted(() => {
|
||||||
|
if (auth.isAuthenticated.value) {
|
||||||
|
loadProfile()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => auth.isAuthenticated.value, (isAuth) => {
|
||||||
|
if (isAuth) loadProfile()
|
||||||
|
})
|
||||||
watch(profileId, loadProfile)
|
watch(profileId, loadProfile)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ export default defineNuxtConfig({
|
|||||||
pwa: {
|
pwa: {
|
||||||
registerType: 'autoUpdate',
|
registerType: 'autoUpdate',
|
||||||
workbox: {
|
workbox: {
|
||||||
navigateFallback: '/',
|
|
||||||
globPatterns: ['**/*.{js,css,html,png,svg,ico}'],
|
globPatterns: ['**/*.{js,css,html,png,svg,ico}'],
|
||||||
},
|
},
|
||||||
client: {
|
client: {
|
||||||
|
|||||||
@@ -77,11 +77,11 @@ services:
|
|||||||
GITEA_MINDMAP_REPO: ${GITEA_MINDMAP_REPO:-MMAVTEX}
|
GITEA_MINDMAP_REPO: ${GITEA_MINDMAP_REPO:-MMAVTEX}
|
||||||
GITEA_PROJECT_REPO: ${GITEA_PROJECT_REPO:-XFlow}
|
GITEA_PROJECT_REPO: ${GITEA_PROJECT_REPO:-XFlow}
|
||||||
DATABASE_URL: postgresql://xflow:${XFLOW_DB_PASSWORD:-xflow_pass}@postgres:5432/xflow
|
DATABASE_URL: postgresql://xflow:${XFLOW_DB_PASSWORD:-xflow_pass}@postgres:5432/xflow
|
||||||
NUXT_PUBLIC_FIREBASE_API_KEY: ${NUXT_PUBLIC_FIREBASE_API_KEY}
|
NUXT_PUBLIC_FIREBASE_API_KEY: ${NUXT_PUBLIC_FIREBASE_API_KEY:-${FIREBASE_API_KEY}}
|
||||||
NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN}
|
NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN:-${FIREBASE_AUTH_DOMAIN}}
|
||||||
NUXT_PUBLIC_FIREBASE_PROJECT_ID: ${NUXT_PUBLIC_FIREBASE_PROJECT_ID}
|
NUXT_PUBLIC_FIREBASE_PROJECT_ID: ${NUXT_PUBLIC_FIREBASE_PROJECT_ID:-${FIREBASE_PROJECT_ID}}
|
||||||
NUXT_PUBLIC_FIREBASE_APP_ID: ${NUXT_PUBLIC_FIREBASE_APP_ID}
|
NUXT_PUBLIC_FIREBASE_APP_ID: ${NUXT_PUBLIC_FIREBASE_APP_ID:-${FIREBASE_APP_ID}}
|
||||||
NUXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: ${NUXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID}
|
NUXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: ${NUXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID:-${FIREBASE_MESSAGING_SENDER_ID}}
|
||||||
volumes:
|
volumes:
|
||||||
- /opt/xflow/.output:/app/.output
|
- /opt/xflow/.output:/app/.output
|
||||||
- /opt/xflow/prisma:/app/prisma:ro
|
- /opt/xflow/prisma:/app/prisma:ro
|
||||||
|
|||||||
@@ -156,3 +156,5 @@
|
|||||||
{ "id": "e16", "fromNode": "solution", "fromSide": "right", "toNode": "arch", "toSide": "left" }
|
{ "id": "e16", "fromNode": "solution", "fromSide": "right", "toNode": "arch", "toSide": "left" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user