🐛 Bug fixes and optimization

This commit is contained in:
LittleSheep 2024-08-13 18:26:36 +08:00
parent 223f97038c
commit baf529e838
8 changed files with 63 additions and 21 deletions

View File

@ -23,7 +23,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defaultUserinfo, useUserinfo } from "@/stores/userinfo" import { useUserinfo } from "@/stores/userinfo"
import { computed } from "vue" import { computed } from "vue"
const {t} = useI18n() const {t} = useI18n()
@ -52,7 +52,7 @@ const avatar = computed(() => {
function signOut() { function signOut() {
useCookie("__hydrogen_atk", { watch: "shallow" }).value = null useCookie("__hydrogen_atk", { watch: "shallow" }).value = null
useCookie("__hydrogen_rtk", { watch: "shallow" }).value = null useCookie("__hydrogen_rtk", { watch: "shallow" }).value = null
id.userinfo = defaultUserinfo id.userinfo = null
reloadNuxtApp() reloadNuxtApp()
} }
</script> </script>

View File

@ -2,7 +2,7 @@
<div class="w-full max-w-[720px]"> <div class="w-full max-w-[720px]">
<v-expand-transition> <v-expand-transition>
<v-alert v-show="route.query['redirect_uri']" variant="tonal" type="info" class="text-xs"> <v-alert v-show="route.query['redirect_uri']" variant="tonal" type="info" class="text-xs">
You need to sign in before access that page. After you signed in, we will redirect you to: <br /> {{ t("callbackHint") }} <br />
<span class="font-mono">{{ route.query["redirect_uri"] }}</span> <span class="font-mono">{{ route.query["redirect_uri"] }}</span>
</v-alert> </v-alert>
</v-expand-transition> </v-expand-transition>
@ -10,5 +10,6 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const { t } = useI18n()
const route = useRoute() const route = useRoute()
</script> </script>

View File

@ -40,5 +40,6 @@
"securityCaption": "Guard your Solar Network account.", "securityCaption": "Guard your Solar Network account.",
"userActivity": "Activity", "userActivity": "Activity",
"userActivityCaption": "Recent posts of this user.", "userActivityCaption": "Recent posts of this user.",
"productArchived": "Archived" "productArchived": "Archived",
"callbackHint": "You need to sign in before access that page. After you signed in, you will be redirected to:"
} }

View File

@ -40,5 +40,6 @@
"securityCaption": "保护您的 Solar Network 账户。", "securityCaption": "保护您的 Solar Network 账户。",
"userActivity": "活动", "userActivity": "活动",
"userActivityCaption": "此用户的最新帖子。", "userActivityCaption": "此用户的最新帖子。",
"productArchived": "已归档" "productArchived": "已归档",
"callbackHint": "访问该页面前,您需要先登录。登录后,我们会将把您重定向到:"
} }

View File

@ -1,7 +1,7 @@
export default defineNuxtRouteMiddleware((to, from) => { export default defineNuxtRouteMiddleware((to, from) => {
const id = useUserinfo(); const state = useLoggedInState()
if (!id.isLoggedIn) { if (!state.value) {
return navigateTo(`/auth/sign-in?redirect_uri=${to.fullPath}`) return navigateTo(`/auth/sign-in?redirect_uri=${to.fullPath}`)
} }
}) })

View File

@ -59,6 +59,21 @@ async function pickUpTicket() {
onMounted(() => pickUpTicket()) onMounted(() => pickUpTicket())
const id = useUserinfo()
const router = useRouter()
watch(id, (value) => {
if (value.isLoggedIn) {
if (route.query["close"]) {
window.close()
} else if (route.query["redirect_uri"]) {
window.open((route.query["redirect_uri"] as string) ?? "/", "_self")
} else {
router.push("/users/me")
}
}
}, { deep: true, immediate: true })
const panel = ref("authenticate") const panel = ref("authenticate")
const panels: { [id: string]: Component } = { const panels: { [id: string]: Component } = {

View File

@ -2,18 +2,6 @@ import { defineStore } from "pinia"
import { ref } from "vue" import { ref } from "vue"
import { solarFetch } from "~/utils/request" import { solarFetch } from "~/utils/request"
export interface Userinfo {
isLoggedIn: boolean
displayName: string
data: any
}
export const defaultUserinfo: Userinfo = {
isLoggedIn: false,
displayName: "Citizen",
data: null,
}
export function useAtk() { export function useAtk() {
return useCookie("__hydrogen_atk", { watch: "shallow" }) return useCookie("__hydrogen_atk", { watch: "shallow" })
} }
@ -31,6 +19,9 @@ export const useUserinfo = defineStore("userinfo", () => {
const isReady = ref(false) const isReady = ref(false)
const isLoggedIn = ref(false) const isLoggedIn = ref(false)
let fetchCompleter: Completer<boolean> | null = null
let refreshCompleter: Completer<string> | null = null
const lastRefreshedAt = ref<Date | null>(null) const lastRefreshedAt = ref<Date | null>(null)
function setTokenSet(atk: string, rtk: string) { function setTokenSet(atk: string, rtk: string) {
@ -45,6 +36,12 @@ export const useUserinfo = defineStore("userinfo", () => {
return useAtk().value return useAtk().value
} }
if (refreshCompleter != null) {
return await refreshCompleter.promise
} else {
refreshCompleter = new Completer<string>()
}
const config = useRuntimeConfig() const config = useRuntimeConfig()
const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/auth/token`, { const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/auth/token`, {
@ -62,18 +59,28 @@ export const useUserinfo = defineStore("userinfo", () => {
const out = await res.json() const out = await res.json()
console.log("[PASSPORT] Access token has been refreshed now.") console.log("[PASSPORT] Access token has been refreshed now.")
setTokenSet(out["access_token"], out["refresh_token"]) setTokenSet(out["access_token"], out["refresh_token"])
refreshCompleter.complete(out["access_token"])
return out["access_token"] return out["access_token"]
} }
} }
async function readProfiles() { async function readProfiles() {
if (fetchCompleter != null) {
await fetchCompleter.promise
return
} else {
fetchCompleter = new Completer<boolean>()
}
if (!useLoggedInState().value) { if (!useLoggedInState().value) {
fetchCompleter.complete(true)
isReady.value = true isReady.value = true
} }
const res = await solarFetch("/cgi/auth/users/me") const res = await solarFetch("/cgi/auth/users/me")
if (res.status !== 200) { if (res.status !== 200) {
fetchCompleter.complete(true)
isReady.value = true isReady.value = true
return return
} }
@ -83,7 +90,21 @@ export const useUserinfo = defineStore("userinfo", () => {
isLoggedIn.value = true isLoggedIn.value = true
isReady.value = true isReady.value = true
userinfo.value = data userinfo.value = data
fetchCompleter.complete(true)
} }
return { userinfo, lastRefreshedAt, isLoggedIn, isReady, setTokenSet, getAtk, readProfiles } return { userinfo, lastRefreshedAt, isLoggedIn, isReady, fetchCompleter, setTokenSet, getAtk, readProfiles }
}) })
export class Completer<T> {
public readonly promise: Promise<T>
public complete: (value: (PromiseLike<T> | T)) => void
private reject: (reason?: any) => void
public constructor() {
this.promise = new Promise<T>((resolve, reject) => {
this.complete = resolve
this.reject = reject
})
}
}

View File

@ -1,4 +1,7 @@
{ {
// https://nuxt.com/docs/guide/concepts/typescript // https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json" "extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"strictPropertyInitialization": false
}
} }