fix: supports force logout when license expired or license server lost

This commit is contained in:
NFish 2024-11-14 10:34:39 +08:00
parent 9d9400849d
commit a66e44211b
2 changed files with 119 additions and 50 deletions

View File

@ -17,6 +17,7 @@ import type {
WorkflowStartedResponse,
} from '@/types/workflow'
import { removeAccessToken } from '@/app/components/share/utils'
import { asyncRunSafe } from '@/utils'
const TIME_OUT = 100000
const ContentType = {
@ -550,55 +551,125 @@ export const ssePost = (
}
// base request
export const request = <T>(url: string, options = {}, otherOptions?: IOtherOptions) => {
return new Promise<T>((resolve, reject) => {
export const request = async<T>(url: string, options = {}, otherOptions?: IOtherOptions) => {
try {
const otherOptionsForBaseFetch = otherOptions || {}
baseFetch<T>(url, options, otherOptionsForBaseFetch).then(resolve).catch((errResp) => {
if (errResp?.status === 401) {
return refreshAccessTokenOrRelogin(TIME_OUT).then(() => {
baseFetch<T>(url, options, otherOptionsForBaseFetch).then(resolve).catch(reject)
}).catch(() => {
const {
isPublicAPI = false,
silent,
} = otherOptionsForBaseFetch
const bodyJson = errResp.json()
if (isPublicAPI) {
return bodyJson.then((data: ResponseError) => {
if (data.code === 'web_sso_auth_required')
requiredWebSSOLogin()
if (data.code === 'unauthorized') {
removeAccessToken()
globalThis.location.reload()
}
return Promise.reject(data)
})
}
const loginUrl = `${globalThis.location.origin}/signin`
bodyJson.then((data: ResponseError) => {
if (data.code === 'init_validate_failed' && IS_CE_EDITION && !silent)
Toast.notify({ type: 'error', message: data.message, duration: 4000 })
else if (data.code === 'not_init_validated' && IS_CE_EDITION)
globalThis.location.href = `${globalThis.location.origin}/init`
else if (data.code === 'not_setup' && IS_CE_EDITION)
globalThis.location.href = `${globalThis.location.origin}/install`
else if (location.pathname !== '/signin' || !IS_CE_EDITION)
globalThis.location.href = loginUrl
else if (!silent)
Toast.notify({ type: 'error', message: data.message })
}).catch(() => {
// Handle any other errors
globalThis.location.href = loginUrl
})
})
const [err, resp] = await asyncRunSafe<T>(baseFetch(url, options, otherOptionsForBaseFetch))
if (err === null)
return resp
const errResp: Response = err as any
if (errResp.status === 401) {
const [parseErr, errRespData] = await asyncRunSafe<ResponseError>(errResp.json())
const loginUrl = `${globalThis.location.origin}/signin`
if (parseErr) {
globalThis.location.href = loginUrl
return Promise.reject(err)
}
else {
reject(errResp)
// special code
const { code, message } = errRespData
// webapp sso
if (code === 'web_sso_auth_required') {
requiredWebSSOLogin()
return Promise.reject(err)
}
})
})
// force logout
if (code === 'unauthorized_and_force_logout') {
removeAccessToken()
globalThis.location.reload()
return Promise.reject(err)
}
const {
isPublicAPI = false,
silent,
} = otherOptionsForBaseFetch
if (isPublicAPI && code === 'unauthorized') {
removeAccessToken()
globalThis.location.reload()
return Promise.reject(err)
}
if (code === 'init_validate_failed' && IS_CE_EDITION && !silent) {
Toast.notify({ type: 'error', message, duration: 4000 })
return Promise.reject(err)
}
if (code === 'not_init_validated' && IS_CE_EDITION) {
globalThis.location.href = `${globalThis.location.origin}/init`
return Promise.reject(err)
}
if (code === 'not_setup' && IS_CE_EDITION) {
globalThis.location.href = `${globalThis.location.origin}/install`
return Promise.reject(err)
}
// refresh token
const [refreshErr] = await asyncRunSafe(refreshAccessTokenOrRelogin(TIME_OUT))
if (refreshErr === null)
return baseFetch<T>(url, options, otherOptionsForBaseFetch)
if (location.pathname !== '/signin' || !IS_CE_EDITION) {
globalThis.location.href = loginUrl
return Promise.reject(err)
}
if (!silent) {
Toast.notify({ type: 'error', message })
return Promise.reject(err)
}
globalThis.location.href = loginUrl
return Promise.reject(err)
}
else {
return Promise.reject(err)
}
}
catch (error) {
console.error(error)
return Promise.reject(error)
}
// return new Promise<T>((resolve, reject) => {
// baseFetch<T>(url, options, otherOptionsForBaseFetch).then(resolve).catch((errResp) => {
// if (errResp?.status === 401) {
// return refreshAccessTokenOrRelogin(TIME_OUT).then(() => {
// baseFetch<T>(url, options, otherOptionsForBaseFetch).then(resolve).catch(reject)
// }).catch(() => {
// const {
// isPublicAPI = false,
// silent,
// } = otherOptionsForBaseFetch
// const bodyJson = errResp.json()
// if (isPublicAPI) {
// return bodyJson.then((data: ResponseError) => {
// if (data.code === 'web_sso_auth_required')
// requiredWebSSOLogin()
// if (data.code === 'unauthorized') {
// removeAccessToken()
// globalThis.location.reload()
// }
// return Promise.reject(data)
// })
// }
// const loginUrl = `${globalThis.location.origin}/signin`
// bodyJson.then((data: ResponseError) => {
// if (data.code === 'init_validate_failed' && IS_CE_EDITION && !silent)
// Toast.notify({ type: 'error', message: data.message, duration: 4000 })
// else if (data.code === 'not_init_validated' && IS_CE_EDITION)
// globalThis.location.href = `${globalThis.location.origin}/init`
// else if (data.code === 'not_setup' && IS_CE_EDITION)
// globalThis.location.href = `${globalThis.location.origin}/install`
// else if (location.pathname !== '/signin' || !IS_CE_EDITION)
// globalThis.location.href = loginUrl
// else if (!silent)
// Toast.notify({ type: 'error', message: data.message })
// }).catch(() => {
// // Handle any other errors
// globalThis.location.href = loginUrl
// })
// })
// }
// else {
// reject(errResp)
// }
// })
// })
}
// request methods

View File

@ -8,10 +8,8 @@ export async function asyncRunSafe<T = any>(fn: Promise<T>): Promise<[Error] | [
try {
return [null, await fn]
}
catch (e) {
if (e instanceof Error)
return [e]
return [new Error('unknown error')]
catch (e: any) {
return [e || new Error('unknown error')]
}
}