🐛 Bug fixes and optimization
This commit is contained in:
		| @@ -23,7 +23,7 @@ | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { defaultUserinfo, useUserinfo } from "@/stores/userinfo" | ||||
| import { useUserinfo } from "@/stores/userinfo" | ||||
| import { computed } from "vue" | ||||
|  | ||||
| const {t} = useI18n() | ||||
| @@ -52,7 +52,7 @@ const avatar = computed(() => { | ||||
| function signOut() { | ||||
|   useCookie("__hydrogen_atk", { watch: "shallow" }).value = null | ||||
|   useCookie("__hydrogen_rtk", { watch: "shallow" }).value = null | ||||
|   id.userinfo = defaultUserinfo | ||||
|   id.userinfo = null | ||||
|   reloadNuxtApp() | ||||
| } | ||||
| </script> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   <div class="w-full max-w-[720px]"> | ||||
|     <v-expand-transition> | ||||
|       <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> | ||||
|       </v-alert> | ||||
|     </v-expand-transition> | ||||
| @@ -10,5 +10,6 @@ | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| const { t } = useI18n() | ||||
| const route = useRoute() | ||||
| </script> | ||||
|   | ||||
| @@ -40,5 +40,6 @@ | ||||
|   "securityCaption": "Guard your Solar Network account.", | ||||
|   "userActivity": "Activity", | ||||
|   "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:" | ||||
| } | ||||
|   | ||||
| @@ -40,5 +40,6 @@ | ||||
|   "securityCaption": "保护您的 Solar Network 账户。", | ||||
|   "userActivity": "活动", | ||||
|   "userActivityCaption": "此用户的最新帖子。", | ||||
|   "productArchived": "已归档" | ||||
|   "productArchived": "已归档", | ||||
|   "callbackHint": "访问该页面前,您需要先登录。登录后,我们会将把您重定向到:" | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| 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}`) | ||||
|   } | ||||
| }) | ||||
|   | ||||
| @@ -59,6 +59,21 @@ async function 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 panels: { [id: string]: Component } = { | ||||
|   | ||||
| @@ -2,18 +2,6 @@ import { defineStore } from "pinia" | ||||
| import { ref } from "vue" | ||||
| 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() { | ||||
|   return useCookie("__hydrogen_atk", { watch: "shallow" }) | ||||
| } | ||||
| @@ -31,6 +19,9 @@ export const useUserinfo = defineStore("userinfo", () => { | ||||
|   const isReady = ref(false) | ||||
|   const isLoggedIn = ref(false) | ||||
|  | ||||
|   let fetchCompleter: Completer<boolean> | null = null | ||||
|   let refreshCompleter: Completer<string> | null = null | ||||
|  | ||||
|   const lastRefreshedAt = ref<Date | null>(null) | ||||
|  | ||||
|   function setTokenSet(atk: string, rtk: string) { | ||||
| @@ -45,6 +36,12 @@ export const useUserinfo = defineStore("userinfo", () => { | ||||
|       return useAtk().value | ||||
|     } | ||||
|  | ||||
|     if (refreshCompleter != null) { | ||||
|       return await refreshCompleter.promise | ||||
|     } else { | ||||
|       refreshCompleter = new Completer<string>() | ||||
|     } | ||||
|  | ||||
|     const config = useRuntimeConfig() | ||||
|  | ||||
|     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() | ||||
|       console.log("[PASSPORT] Access token has been refreshed now.") | ||||
|       setTokenSet(out["access_token"], out["refresh_token"]) | ||||
|       refreshCompleter.complete(out["access_token"]) | ||||
|       return out["access_token"] | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async function readProfiles() { | ||||
|     if (fetchCompleter != null) { | ||||
|       await fetchCompleter.promise | ||||
|       return | ||||
|     } else { | ||||
|       fetchCompleter = new Completer<boolean>() | ||||
|     } | ||||
|  | ||||
|     if (!useLoggedInState().value) { | ||||
|       fetchCompleter.complete(true) | ||||
|       isReady.value = true | ||||
|     } | ||||
|  | ||||
|     const res = await solarFetch("/cgi/auth/users/me") | ||||
|  | ||||
|     if (res.status !== 200) { | ||||
|       fetchCompleter.complete(true) | ||||
|       isReady.value = true | ||||
|       return | ||||
|     } | ||||
| @@ -83,7 +90,21 @@ export const useUserinfo = defineStore("userinfo", () => { | ||||
|     isLoggedIn.value = true | ||||
|     isReady.value = true | ||||
|     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 | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,7 @@ | ||||
| { | ||||
|   // https://nuxt.com/docs/guide/concepts/typescript | ||||
|   "extends": "./.nuxt/tsconfig.json" | ||||
|   "extends": "./.nuxt/tsconfig.json", | ||||
|   "compilerOptions": { | ||||
|     "strictPropertyInitialization": false | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user