import type { ApiError } from '@/api/core/handlers'
|
import type { MiniLoginResponse, MiniOfficialLoginResponse } from '@/types/auth'
|
import { fetchMiniMe, fetchOfficialOAuthUrl, loginByOfficialCode } from '@/api/auth'
|
import { normalizeLoginProfile, normalizeMeProfile } from '@/types/auth'
|
import { useMiniAuthStore } from '@/store/auth'
|
|
export const MINI_PHONE_AUTH_REQUIRED = 10008
|
|
export function getApiErrorCode(error: unknown) {
|
return typeof error === 'object' && error != null && 'code' in error
|
? Number((error as ApiError).code)
|
: NaN
|
}
|
|
function getCurrentH5UrlWithoutOAuthParams() {
|
// #ifdef H5
|
const url = new URL(window.location.href)
|
url.searchParams.delete('code')
|
url.searchParams.delete('state')
|
if (url.hash.includes('?')) {
|
const [hashPath, hashQuery = ''] = url.hash.split('?')
|
const hashParams = new URLSearchParams(hashQuery)
|
hashParams.delete('code')
|
hashParams.delete('state')
|
const nextHashQuery = hashParams.toString()
|
url.hash = nextHashQuery ? `${hashPath}?${nextHashQuery}` : hashPath
|
}
|
return url.toString()
|
// #endif
|
// #ifndef H5
|
return ''
|
// #endif
|
}
|
|
export function clearOfficialOAuthQuery() {
|
// #ifdef H5
|
const url = new URL(window.location.href)
|
let changed = url.searchParams.has('code') || url.searchParams.has('state')
|
if (url.hash.includes('?')) {
|
const [hashPath, hashQuery = ''] = url.hash.split('?')
|
const hashParams = new URLSearchParams(hashQuery)
|
if (hashParams.has('code') || hashParams.has('state')) {
|
changed = true
|
}
|
hashParams.delete('code')
|
hashParams.delete('state')
|
const nextHashQuery = hashParams.toString()
|
url.hash = nextHashQuery ? `${hashPath}?${nextHashQuery}` : hashPath
|
}
|
if (!changed) {
|
return
|
}
|
url.searchParams.delete('code')
|
url.searchParams.delete('state')
|
window.history.replaceState({}, document.title, url.toString())
|
// #endif
|
}
|
|
export async function startOfficialOAuthLogin() {
|
// #ifdef H5
|
const redirectUri = getCurrentH5UrlWithoutOAuthParams()
|
const state = `${Date.now()}`
|
const response = await fetchOfficialOAuthUrl({ redirectUri, state })
|
window.location.href = response.url
|
return
|
// #endif
|
// #ifndef H5
|
throw new Error('当前环境暂不支持公众号授权登录')
|
// #endif
|
}
|
|
export async function handleOfficialOAuthCallback(): Promise<MiniOfficialLoginResponse | null> {
|
// #ifdef H5
|
const url = new URL(window.location.href)
|
let code = url.searchParams.get('code')
|
if (!code && url.hash.includes('?')) {
|
const hashQuery = url.hash.split('?')[1] || ''
|
code = new URLSearchParams(hashQuery).get('code')
|
}
|
if (!code) {
|
return null
|
}
|
return await loginByOfficialCode({ code })
|
// #endif
|
// #ifndef H5
|
return null
|
// #endif
|
}
|
|
export async function finishMiniLogin(loginData: MiniLoginResponse) {
|
const authStore = useMiniAuthStore()
|
authStore.setSession({
|
token: loginData.token,
|
profile: normalizeLoginProfile(loginData),
|
})
|
|
try {
|
const profile = await fetchMiniMe(loginData.token)
|
authStore.setProfile(normalizeMeProfile(profile))
|
}
|
catch (error) {
|
console.warn('load mini profile failed after login', error)
|
}
|
}
|