Files
client-web/src/App.vue
T

54 lines
2.2 KiB
Vue
Raw Normal View History

2026-08-08 10:14:07 +08:00
<script setup lang="ts">
import { onBeforeUnmount, onMounted } from 'vue'
2026-09-02 20:49:13 +08:00
import { useAuthStore } from '@/modules/auth/public'
2026-07-30 17:59:42 +08:00
2026-08-08 10:14:07 +08:00
let readyInterval: number | null = null
2026-09-02 20:49:13 +08:00
let expectedAdminOrigin = ''
let impersonationExchangePending = false
function configuredImpersonationOrigin() {
const queryOrigin = new URLSearchParams(window.location.search).get('impersonationOrigin')
if (queryOrigin) {
try { return new URL(queryOrigin).origin } catch { return '' }
}
return String(import.meta.env.VITE_ADMIN_WEB_ORIGIN || '').trim() || window.location.origin
}
2026-08-08 10:14:07 +08:00
onMounted(() => {
2026-09-02 20:49:13 +08:00
expectedAdminOrigin = configuredImpersonationOrigin()
if (!window.opener || !expectedAdminOrigin) return
window.addEventListener('message', acceptImpersonationTicket)
const announceReady = () => window.opener?.postMessage({ source: 'chongchong-client', type: 'impersonation-ready' }, expectedAdminOrigin)
2026-08-08 10:14:07 +08:00
announceReady()
readyInterval = window.setInterval(announceReady, 300)
window.setTimeout(() => {
if (readyInterval !== null) window.clearInterval(readyInterval)
readyInterval = null
}, 10000)
})
2026-09-02 20:49:13 +08:00
async function acceptImpersonationTicket(event: MessageEvent<unknown>) {
const message = event.data as { source?: string; type?: string; code?: string } | null
if (event.source !== window.opener || event.origin !== expectedAdminOrigin || message?.source !== 'chongchong-admin' || message.type !== 'impersonation-ticket' || !message.code || impersonationExchangePending) return
impersonationExchangePending = true
if (readyInterval !== null) window.clearInterval(readyInterval)
2026-08-08 10:14:07 +08:00
readyInterval = null
2026-09-02 20:49:13 +08:00
const auth = useAuthStore()
try {
await auth.acceptImpersonationCode(message.code)
window.opener?.postMessage({ source: 'chongchong-client', type: 'impersonation-complete' }, expectedAdminOrigin)
window.location.replace('/')
} catch {
window.opener?.postMessage({ source: 'chongchong-client', type: 'impersonation-failed' }, expectedAdminOrigin)
window.location.replace('/login?impersonation=failed')
}
2026-08-08 10:14:07 +08:00
}
onBeforeUnmount(() => {
if (readyInterval !== null) window.clearInterval(readyInterval)
2026-09-02 20:49:13 +08:00
window.removeEventListener('message', acceptImpersonationTicket)
2026-08-08 10:14:07 +08:00
})
</script>
<template><RouterView /></template>