🐛 Bug fixes and optimization
This commit is contained in:
parent
223f97038c
commit
baf529e838
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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:"
|
||||||
}
|
}
|
||||||
|
@ -40,5 +40,6 @@
|
|||||||
"securityCaption": "保护您的 Solar Network 账户。",
|
"securityCaption": "保护您的 Solar Network 账户。",
|
||||||
"userActivity": "活动",
|
"userActivity": "活动",
|
||||||
"userActivityCaption": "此用户的最新帖子。",
|
"userActivityCaption": "此用户的最新帖子。",
|
||||||
"productArchived": "已归档"
|
"productArchived": "已归档",
|
||||||
|
"callbackHint": "访问该页面前,您需要先登录。登录后,我们会将把您重定向到:"
|
||||||
}
|
}
|
||||||
|
@ -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}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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 } = {
|
||||||
|
@ -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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user