🐛 Fix the authorize page

This commit is contained in:
2025-09-30 01:04:20 +08:00
parent 888d3cb5ba
commit 98a5d34f3c
6 changed files with 2895 additions and 30 deletions

View File

@@ -9,14 +9,16 @@ export const useSolarNetwork = (withoutProxy = false) => {
credentials: "include", credentials: "include",
// Add Authorization header with Bearer token // Add Authorization header with Bearer token
onRequest: ({ request, options }) => { onRequest: ({ request, options }) => {
const side = process.server ? 'SERVER' : 'CLIENT' const side = process.server ? "SERVER" : "CLIENT"
console.log(`[useSolarNetwork] onRequest for ${request} on ${side}`) console.log(`[useSolarNetwork] onRequest for ${request} on ${side}`)
// Get token from user store // Get token from user store
const userStore = useUserStore() const userStore = useUserStore()
const token = userStore.token const token = userStore.token
if (token) { if (token) {
console.log('[useSolarNetwork] Token found, adding Authorization header.') console.log(
"[useSolarNetwork] Token found, adding Authorization header."
)
if (!options.headers) { if (!options.headers) {
options.headers = new Headers() options.headers = new Headers()
} }
@@ -27,7 +29,9 @@ export const useSolarNetwork = (withoutProxy = false) => {
;(options.headers as any)["Authorization"] = `Bearer ${token}` ;(options.headers as any)["Authorization"] = `Bearer ${token}`
} }
} else { } else {
console.log('[useSolarNetwork] No token found, skipping Authorization header.') console.log(
"[useSolarNetwork] No token found, skipping Authorization header."
)
} }
// Transform request data from camelCase to snake_case // Transform request data from camelCase to snake_case
@@ -46,5 +50,5 @@ export const useSolarNetwork = (withoutProxy = false) => {
export const useSolarNetworkUrl = (withoutProxy = false) => { export const useSolarNetworkUrl = (withoutProxy = false) => {
const config = useRuntimeConfig() const config = useRuntimeConfig()
return (config.public.development && !withoutProxy) ? "/api" : config.public.apiBase return config.public.apiBase
} }

26
app/middleware/auth.ts Normal file
View File

@@ -0,0 +1,26 @@
import { useUserStore } from '~/stores/user'
export default defineNuxtRouteMiddleware(async to => {
const userStore = useUserStore()
// If the user is already authenticated, we're good.
if (userStore.isAuthenticated) {
return
}
// If we have a token, but no user object, fetch the user.
// This happens on initial load or page refresh.
if (userStore.token && !userStore.user) {
await userStore.fetchUser()
}
// If the user is still not authenticated, redirect to login.
if (!userStore.isAuthenticated) {
// Abort navigation to the original page.
if (to.path !== '/auth/login') {
const redirect = encodeURIComponent(to.fullPath)
console.log(`[AUTH] Redirecting to /auth/login?redirect=${redirect}`)
return navigateTo(`/auth/login?redirect=${redirect}`)
}
}
})

View File

@@ -154,14 +154,17 @@ function checkIfNewApp() {
isNewApp.value = false isNewApp.value = false
} }
async function handleAuthorize() { async function handleAuthorize(authorize = true) {
isAuthorizing.value = true isAuthorizing.value = true
try { try {
const data = await api<{ redirectUri?: string }>( const data = await api<{ redirectUri?: string }>(
"/id/auth/open/authorize", "/id/auth/open/authorize",
{ {
method: "POST", method: "POST",
body: new URLSearchParams(window.location.search.slice(1)) body: new URLSearchParams({
...route.query,
authorize: authorize ? "true" : "false"
})
} }
) )
@@ -176,22 +179,7 @@ async function handleAuthorize() {
} }
function handleDeny() { function handleDeny() {
// Redirect back to the client with an error handleAuthorize(false)
// Ensure redirect_uri is always a string (not an array)
const redirectUriStr = Array.isArray(route.query.redirect_uri)
? route.query.redirect_uri[0] || clientInfo.value?.homeUri || "/"
: route.query.redirect_uri || clientInfo.value?.homeUri || "/"
const redirectUri = new URL(redirectUriStr)
// Ensure state is always a string (not an array)
const state = Array.isArray(route.query.state)
? route.query.state[0] || ""
: route.query.state || ""
const params = new URLSearchParams({
error: "access_denied",
error_description: "The user denied the authorization request",
state: state
})
window.open(`${redirectUri}?${params}`, "_self")
} }
// Lifecycle // Lifecycle

View File

@@ -22,6 +22,7 @@ export const useUserStore = defineStore("user", () => {
// Actions // Actions
async function fetchUser(reload = true) { async function fetchUser(reload = true) {
if (isLoading.value) return
if (!reload && user.value) return // Skip fetching if already loaded and not forced to if (!reload && user.value) return // Skip fetching if already loaded and not forced to
isLoading.value = true isLoading.value = true

2854
bun.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -58,13 +58,5 @@ export default defineNuxtConfig({
}, },
vite: { vite: {
plugins: [tailwindcss()] plugins: [tailwindcss()]
},
nitro: {
devProxy: {
"/api": {
target: process.env.NUXT_PUBLIC_API_BASE || "https://api.solian.app",
changeOrigin: true
}
}
} }
}) })