diff --git a/src/api/auth.ts b/src/api/auth.ts index 12cd8bb..3e2d6c2 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -17,6 +17,9 @@ const ACCESS_CODES_KEY = 'kt-admin-access-codes' const USER_INFO_KEY = 'kt-admin-user-info' const LOGIN_REDIRECT_MARK_KEY = 'kt-admin-login-redirect-at' const LOGIN_REDIRECT_COOLDOWN = 10 * 1000 +const AUTH_TRANSFER_TOKEN_KEY = 'ktAccessToken' +const AUTH_TRANSFER_CODES_KEY = 'ktAccessCodes' +const AUTH_TRANSFER_USER_KEY = 'ktUserInfo' let refreshPromise: Promise | null = null let redirectingToAdminLogin = false @@ -77,6 +80,48 @@ export function persistAuthData({ } } +function parseAuthTransferJson(value: string | null) { + if (!value) return undefined + + try { + return JSON.parse(value) as T + } catch { + return undefined + } +} + +function removeAuthTransferParams(url: URL) { + url.searchParams.delete(AUTH_TRANSFER_TOKEN_KEY) + url.searchParams.delete(AUTH_TRANSFER_CODES_KEY) + url.searchParams.delete(AUTH_TRANSFER_USER_KEY) + window.history.replaceState( + window.history.state, + document.title, + `${url.pathname}${url.search}${url.hash}`, + ) +} + +export function consumeAdminAuthRedirect() { + const url = new URL(window.location.href) + const accessToken = url.searchParams.get(AUTH_TRANSFER_TOKEN_KEY) + + if (!accessToken) return null + + persistAuthData({ + accessCodes: parseAuthTransferJson( + url.searchParams.get(AUTH_TRANSFER_CODES_KEY), + ), + accessToken, + userInfo: parseAuthTransferJson( + url.searchParams.get(AUTH_TRANSFER_USER_KEY), + ), + }) + clearAdminLoginRedirectMark() + removeAuthTransferParams(url) + + return accessToken +} + function buildAdminLoginUrl(redirect: string) { const loginUrl = new URL(getAdminLogin()) diff --git a/src/api/request.ts b/src/api/request.ts index 7f4050e..9f6855e 100644 --- a/src/api/request.ts +++ b/src/api/request.ts @@ -2,6 +2,7 @@ import axios, { type AxiosRequestConfig } from 'axios' import { clearAdminLoginRedirectMark, clearPersistedAuth, + consumeAdminAuthRedirect, getStoredAccessToken, redirectToAdminLogin, refreshPersistedAuth, @@ -38,7 +39,7 @@ export function getApiUrl(url: string) { } request.interceptors.request.use(async (config) => { - const accessToken = getStoredAccessToken() + const accessToken = consumeAdminAuthRedirect() || getStoredAccessToken() if (accessToken) { config.headers.Authorization = `Bearer ${accessToken}` diff --git a/test/main.ts b/test/main.ts index beaf428..c8e6a5f 100644 --- a/test/main.ts +++ b/test/main.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/prefer-ts-expect-error */ import { createApp, h, ref, watchEffect } from 'vue' import { type OutputModes, Repl, useStore, useVueImportMap } from '../src' +import { consumeAdminAuthRedirect } from '../src/api/auth' import PlaygroundHeader from '../src/PlaygroundHeader.vue' // @ts-ignore import MonacoEditor from '../src/editor/MonacoEditor.vue' @@ -9,6 +10,7 @@ import CodeMirrorEditor from '../src/editor/CodeMirrorEditor.vue' const window = globalThis.window as any window.process = { env: {} } +consumeAdminAuthRedirect() const App = { setup() {