优化
This commit is contained in:
+31
-11
@@ -1,32 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, onMounted } from 'vue'
|
||||
import { useAuthStore } from '@/modules/auth/public'
|
||||
|
||||
let readyInterval: number | null = null
|
||||
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
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const configuredAdminOrigin = String(import.meta.env.VITE_ADMIN_WEB_ORIGIN || '').trim()
|
||||
const targetOrigin = configuredAdminOrigin || window.location.origin
|
||||
const announceReady = () => window.opener?.postMessage({ source: 'chongchong-client', type: 'impersonation-ready' }, targetOrigin)
|
||||
expectedAdminOrigin = configuredImpersonationOrigin()
|
||||
if (!window.opener || !expectedAdminOrigin) return
|
||||
window.addEventListener('message', acceptImpersonationTicket)
|
||||
const announceReady = () => window.opener?.postMessage({ source: 'chongchong-client', type: 'impersonation-ready' }, expectedAdminOrigin)
|
||||
announceReady()
|
||||
readyInterval = window.setInterval(announceReady, 300)
|
||||
window.setTimeout(() => {
|
||||
if (readyInterval !== null) window.clearInterval(readyInterval)
|
||||
readyInterval = null
|
||||
}, 10000)
|
||||
window.addEventListener('message', stopReadyAnnouncement)
|
||||
})
|
||||
|
||||
function stopReadyAnnouncement(event: MessageEvent<unknown>) {
|
||||
const configuredAdminOrigin = String(import.meta.env.VITE_ADMIN_WEB_ORIGIN || '').trim()
|
||||
const expectedAdminOrigin = configuredAdminOrigin || window.location.origin
|
||||
const message = event.data as { source?: string; type?: string } | null
|
||||
if (event.source !== window.opener || event.origin !== expectedAdminOrigin || message?.source !== 'chongchong-admin' || message.type !== 'impersonation-ticket' || readyInterval === null) return
|
||||
window.clearInterval(readyInterval)
|
||||
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)
|
||||
readyInterval = null
|
||||
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')
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (readyInterval !== null) window.clearInterval(readyInterval)
|
||||
window.removeEventListener('message', stopReadyAnnouncement)
|
||||
window.removeEventListener('message', acceptImpersonationTicket)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user