From 93b72efc313e03f343699a271ab9d68d5fb00ad0 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 7 Nov 2024 14:02:22 +0800 Subject: [PATCH 1/9] feat: Show warning tip on Login Page when License is expired. --- web/app/signin/normalForm.tsx | 18 ++++++++++++++++-- web/i18n/en-US/login.ts | 2 ++ web/i18n/zh-Hans/login.ts | 2 ++ web/types/feature.ts | 8 ++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/web/app/signin/normalForm.tsx b/web/app/signin/normalForm.tsx index f4f46c68ba6543..032c10a3016b99 100644 --- a/web/app/signin/normalForm.tsx +++ b/web/app/signin/normalForm.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import Link from 'next/link' import { useRouter, useSearchParams } from 'next/navigation' -import { RiDoorLockLine } from '@remixicon/react' +import { RiContractLine, RiDoorLockLine, RiErrorWarningFill } from '@remixicon/react' import Loading from '../components/base/loading' import MailAndCodeAuth from './components/mail-and-code-auth' import MailAndPasswordAuth from './components/mail-and-password-auth' @@ -10,7 +10,7 @@ import SocialAuth from './components/social-auth' import SSOAuth from './components/sso-auth' import cn from '@/utils/classnames' import { getSystemFeatures, invitationCheck } from '@/service/common' -import { defaultSystemFeatures } from '@/types/feature' +import { LicenseStatus, defaultSystemFeatures } from '@/types/feature' import Toast from '@/app/components/base/toast' import { IS_CE_EDITION } from '@/config' @@ -83,6 +83,20 @@ const NormalForm = () => { } + if (systemFeatures.license_status === LicenseStatus.EXPIRED) { + return
+
+
+
+ + +
+

{t('login.licenseExpired')}

+

{t('login.licenseExpiredTip')}

+
+
+
+ } return ( <> diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index b47d7bd69a8dd7..b14bd1e2a0aec2 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -98,6 +98,8 @@ const translation = { back: 'Back', noLoginMethod: 'Authentication method not configured', noLoginMethodTip: 'Please contact the system admin to add an authentication method.', + licenseExpired: 'License Expired', + licenseExpiredTip: 'Your organization\'s Dify Enterprise license has expired.Please contact your administrator to continue using Dify.', } export default translation diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 40697701da8858..02959a2987b85a 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -99,6 +99,8 @@ const translation = { back: '返回', noLoginMethod: '未配置身份认证方式', noLoginMethodTip: '请联系系统管理员添加身份认证方式', + licenseExpired: '许可证已过期', + licenseExpiredTip: '您的组织的 Dify 企业许可证已过期。请联系您的管理员续订继续使用 Dify。', } export default translation diff --git a/web/types/feature.ts b/web/types/feature.ts index 0d9b2ec18d2b9f..aaba147540eba2 100644 --- a/web/types/feature.ts +++ b/web/types/feature.ts @@ -4,6 +4,12 @@ export enum SSOProtocol { OAuth2 = 'oauth2', } +export enum LicenseStatus { + NONE = 'none', + ACTIVE = 'active', + EXPIRED = 'expired', +} + export type SystemFeatures = { sso_enforced_for_signin: boolean sso_enforced_for_signin_protocol: SSOProtocol | '' @@ -15,6 +21,7 @@ export type SystemFeatures = { enable_social_oauth_login: boolean is_allow_create_workspace: boolean is_allow_register: boolean + license_status: LicenseStatus } export const defaultSystemFeatures: SystemFeatures = { @@ -28,4 +35,5 @@ export const defaultSystemFeatures: SystemFeatures = { enable_social_oauth_login: false, is_allow_create_workspace: false, is_allow_register: false, + license_status: LicenseStatus.NONE, } From b3e0a5c078a410b6be212b801b94f38bbdbb03e4 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 7 Nov 2024 14:09:29 +0800 Subject: [PATCH 2/9] fix: update i18n & show warning tip on Login page when License is Inactive --- web/app/signin/normalForm.tsx | 14 ++++++++++++++ web/i18n/en-US/login.ts | 4 +++- web/i18n/zh-Hans/login.ts | 4 +++- web/types/feature.ts | 1 + 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/web/app/signin/normalForm.tsx b/web/app/signin/normalForm.tsx index 032c10a3016b99..b6a8b24584ebe1 100644 --- a/web/app/signin/normalForm.tsx +++ b/web/app/signin/normalForm.tsx @@ -97,6 +97,20 @@ const NormalForm = () => { } + if (systemFeatures.license_status === LicenseStatus.NONE) { + return
+
+
+
+ + +
+

{t('login.licenseInactive')}

+

{t('login.licenseInactiveTip')}

+
+
+
+ } return ( <> diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index b14bd1e2a0aec2..3c7c6e3433ffc6 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -99,7 +99,9 @@ const translation = { noLoginMethod: 'Authentication method not configured', noLoginMethodTip: 'Please contact the system admin to add an authentication method.', licenseExpired: 'License Expired', - licenseExpiredTip: 'Your organization\'s Dify Enterprise license has expired.Please contact your administrator to continue using Dify.', + licenseExpiredTip: 'The Dify Enterprise license for your workspace has expired. Please contact your administrator to continue using Dify.', + licenseInactive: 'License Inactive', + licenseInactiveTip: 'Your organization\'s Dify Enterprise license Inactive.Please contact your administrator to continue using Dify.', } export default translation diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 02959a2987b85a..7113e714f3e573 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -100,7 +100,9 @@ const translation = { noLoginMethod: '未配置身份认证方式', noLoginMethodTip: '请联系系统管理员添加身份认证方式', licenseExpired: '许可证已过期', - licenseExpiredTip: '您的组织的 Dify 企业许可证已过期。请联系您的管理员续订继续使用 Dify。', + licenseExpiredTip: '您所在空间的 Dify Enterprise 许可证已过期,请联系管理员以继续使用 Dify。', + licenseInactive: '许可证未激活', + licenseInactiveTip: '您的组织的 Dify 企业许可证未激活。请联系您的管理员激活后继续使用 Dify。', } export default translation diff --git a/web/types/feature.ts b/web/types/feature.ts index aaba147540eba2..fe1cf22a9d51bb 100644 --- a/web/types/feature.ts +++ b/web/types/feature.ts @@ -7,6 +7,7 @@ export enum SSOProtocol { export enum LicenseStatus { NONE = 'none', ACTIVE = 'active', + INACTIVE = 'inactive', EXPIRED = 'expired', } From 4129595369d0da7742161e215455a075ebd63010 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 7 Nov 2024 15:56:57 +0800 Subject: [PATCH 3/9] feat: Display License status in navbar when Active or Expiring --- web/app/components/header/index.tsx | 2 ++ .../components/header/license-env/index.tsx | 29 +++++++++++++++++++ web/app/signin/normalForm.tsx | 4 +-- web/context/app-context.tsx | 2 +- web/i18n/en-US/common.ts | 4 +++ web/i18n/en-US/login.ts | 2 +- web/i18n/zh-Hans/common.ts | 4 +++ web/i18n/zh-Hans/login.ts | 2 +- web/types/feature.ts | 16 ++++++++-- 9 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 web/app/components/header/license-env/index.tsx diff --git a/web/app/components/header/index.tsx b/web/app/components/header/index.tsx index 2b020b81e73419..3757d552df9a7a 100644 --- a/web/app/components/header/index.tsx +++ b/web/app/components/header/index.tsx @@ -12,6 +12,7 @@ import EnvNav from './env-nav' import ExploreNav from './explore-nav' import ToolsNav from './tools-nav' import GithubStar from './github-star' +import LicenseNav from './license-env' import { WorkspaceProvider } from '@/context/workspace-context' import { useAppContext } from '@/context/app-context' import LogoSite from '@/app/components/base/logo/logo-site' @@ -79,6 +80,7 @@ const Header = () => { )}
+ {enableBilling && (
diff --git a/web/app/components/header/license-env/index.tsx b/web/app/components/header/license-env/index.tsx new file mode 100644 index 00000000000000..800d86d2b801d8 --- /dev/null +++ b/web/app/components/header/license-env/index.tsx @@ -0,0 +1,29 @@ +'use client' + +import AppContext from '@/context/app-context' +import { LicenseStatus } from '@/types/feature' +import { useTranslation } from 'react-i18next' +import { useContextSelector } from 'use-context-selector' +import dayjs from 'dayjs' + +const LicenseNav = () => { + const { t } = useTranslation() + const systemFeatures = useContextSelector(AppContext, s => s.systemFeatures) + + if (systemFeatures.license?.status === LicenseStatus.EXPIRING) { + const expiredAt = systemFeatures.license?.expired_at + const count = dayjs(expiredAt).diff(dayjs(), 'days') + return
+ {count <= 1 && {t('common.license.expiring', { count })}} + {count > 1 && {t('common.license.expiring_plural', { count })}} +
+ } + if (systemFeatures.license.status === LicenseStatus.ACTIVE) { + return
+ Enterprise +
+ } + return null +} + +export default LicenseNav diff --git a/web/app/signin/normalForm.tsx b/web/app/signin/normalForm.tsx index b6a8b24584ebe1..605adeec03b6d0 100644 --- a/web/app/signin/normalForm.tsx +++ b/web/app/signin/normalForm.tsx @@ -83,7 +83,7 @@ const NormalForm = () => {
} - if (systemFeatures.license_status === LicenseStatus.EXPIRED) { + if (systemFeatures.license?.status === LicenseStatus.EXPIRED) { return
@@ -97,7 +97,7 @@ const NormalForm = () => {
} - if (systemFeatures.license_status === LicenseStatus.NONE) { + if (systemFeatures.license?.status === LicenseStatus.INACTIVE) { return
diff --git a/web/context/app-context.tsx b/web/context/app-context.tsx index 78ac1c98481dac..fe797663e79e7c 100644 --- a/web/context/app-context.tsx +++ b/web/context/app-context.tsx @@ -144,7 +144,7 @@ export const AppContextProvider: FC = ({ children }) => theme, setTheme: handleSetTheme, apps: appList.data, - systemFeatures, + systemFeatures: { ...systemFeatures, ...defaultSystemFeatures }, mutateApps, userProfile, mutateUserProfile, diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 3390280e8a7242..f9d815be2c4e78 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -591,6 +591,10 @@ const translation = { created: 'Tag created successfully', failed: 'Tag creation failed', }, + license: { + expiring: 'Expiring in one day', + expiring_plural: 'Expiring in {{count}} days', + }, } export default translation diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index 3c7c6e3433ffc6..cbe21458ff0e32 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -101,7 +101,7 @@ const translation = { licenseExpired: 'License Expired', licenseExpiredTip: 'The Dify Enterprise license for your workspace has expired. Please contact your administrator to continue using Dify.', licenseInactive: 'License Inactive', - licenseInactiveTip: 'Your organization\'s Dify Enterprise license Inactive.Please contact your administrator to continue using Dify.', + licenseInactiveTip: 'The Dify Enterprise license for your workspace is inactive. Please contact your administrator to continue using Dify.', } export default translation diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 58d56a83315e0e..207beaab8cce4a 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -591,6 +591,10 @@ const translation = { created: '标签创建成功', failed: '标签创建失败', }, + license: { + expiring: '许可证还有 1 天到期', + expiring_plural: '许可证还有 {{count}} 天到期', + }, } export default translation diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 7113e714f3e573..4d77b8e4031ba1 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -102,7 +102,7 @@ const translation = { licenseExpired: '许可证已过期', licenseExpiredTip: '您所在空间的 Dify Enterprise 许可证已过期,请联系管理员以继续使用 Dify。', licenseInactive: '许可证未激活', - licenseInactiveTip: '您的组织的 Dify 企业许可证未激活。请联系您的管理员激活后继续使用 Dify。', + licenseInactiveTip: '您所在空间的 Dify Enterprise 许可证尚未激活,请联系管理员以继续使用 Dify。', } export default translation diff --git a/web/types/feature.ts b/web/types/feature.ts index fe1cf22a9d51bb..47e8e1aad1df79 100644 --- a/web/types/feature.ts +++ b/web/types/feature.ts @@ -6,9 +6,16 @@ export enum SSOProtocol { export enum LicenseStatus { NONE = 'none', - ACTIVE = 'active', INACTIVE = 'inactive', + ACTIVE = 'active', + EXPIRING = 'expiring', EXPIRED = 'expired', + LOST = 'lost', +} + +type License = { + status: LicenseStatus + expired_at: string | null } export type SystemFeatures = { @@ -22,7 +29,7 @@ export type SystemFeatures = { enable_social_oauth_login: boolean is_allow_create_workspace: boolean is_allow_register: boolean - license_status: LicenseStatus + license: License } export const defaultSystemFeatures: SystemFeatures = { @@ -36,5 +43,8 @@ export const defaultSystemFeatures: SystemFeatures = { enable_social_oauth_login: false, is_allow_create_workspace: false, is_allow_register: false, - license_status: LicenseStatus.NONE, + license: { + status: LicenseStatus.NONE, + expired_at: '', + }, } From eb97a573647e739df1d707f2234a856097790ecb Mon Sep 17 00:00:00 2001 From: NFish Date: Wed, 13 Nov 2024 13:56:14 +0800 Subject: [PATCH 4/9] fix: error merge systemFeatures, it may cause error --- web/context/app-context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/context/app-context.tsx b/web/context/app-context.tsx index fe797663e79e7c..369fe5af19b3b7 100644 --- a/web/context/app-context.tsx +++ b/web/context/app-context.tsx @@ -144,7 +144,7 @@ export const AppContextProvider: FC = ({ children }) => theme, setTheme: handleSetTheme, apps: appList.data, - systemFeatures: { ...systemFeatures, ...defaultSystemFeatures }, + systemFeatures: { ...defaultSystemFeatures, ...systemFeatures }, mutateApps, userProfile, mutateUserProfile, From 9d9400849d104cbd1656fc4ef4158da35f3a2bba Mon Sep 17 00:00:00 2001 From: NFish Date: Wed, 13 Nov 2024 16:11:57 +0800 Subject: [PATCH 5/9] feat: supports license lost status --- web/app/signin/normalForm.tsx | 14 ++++++++++++++ web/i18n/en-US/login.ts | 2 ++ web/i18n/zh-Hans/login.ts | 2 ++ 3 files changed, 18 insertions(+) diff --git a/web/app/signin/normalForm.tsx b/web/app/signin/normalForm.tsx index 605adeec03b6d0..783d8ac507886c 100644 --- a/web/app/signin/normalForm.tsx +++ b/web/app/signin/normalForm.tsx @@ -83,6 +83,20 @@ const NormalForm = () => {
} + if (systemFeatures.license?.status === LicenseStatus.LOST) { + return
+
+
+
+ + +
+

{t('login.licenseLost')}

+

{t('login.licenseLostTip')}

+
+
+
+ } if (systemFeatures.license?.status === LicenseStatus.EXPIRED) { return
diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index cbe21458ff0e32..da7318bb996561 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -100,6 +100,8 @@ const translation = { noLoginMethodTip: 'Please contact the system admin to add an authentication method.', licenseExpired: 'License Expired', licenseExpiredTip: 'The Dify Enterprise license for your workspace has expired. Please contact your administrator to continue using Dify.', + licenseLost: 'License Lost', + licenseLostTip: 'The Dify Enterprise license server for your workspace lost. Please contact your administrator to continue using Dify.', licenseInactive: 'License Inactive', licenseInactiveTip: 'The Dify Enterprise license for your workspace is inactive. Please contact your administrator to continue using Dify.', } diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 4d77b8e4031ba1..4f73723c97b447 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -101,6 +101,8 @@ const translation = { noLoginMethodTip: '请联系系统管理员添加身份认证方式', licenseExpired: '许可证已过期', licenseExpiredTip: '您所在空间的 Dify Enterprise 许可证已过期,请联系管理员以继续使用 Dify。', + licenseLost: '认证服务器丢失', + licenseLostTip: '您所在空间的 Dify Enterprise 认证服务器已丢失,请联系管理员以继续使用 Dify。', licenseInactive: '许可证未激活', licenseInactiveTip: '您所在空间的 Dify Enterprise 许可证尚未激活,请联系管理员以继续使用 Dify。', } From 5ff8a7f600f796905a0adb278542fd7921d7c372 Mon Sep 17 00:00:00 2001 From: Garfield Dai Date: Wed, 13 Nov 2024 18:23:08 +0800 Subject: [PATCH 6/9] update --- web/i18n/en-US/login.ts | 2 +- web/i18n/zh-Hans/login.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index da7318bb996561..5ff7b80b4e105c 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -101,7 +101,7 @@ const translation = { licenseExpired: 'License Expired', licenseExpiredTip: 'The Dify Enterprise license for your workspace has expired. Please contact your administrator to continue using Dify.', licenseLost: 'License Lost', - licenseLostTip: 'The Dify Enterprise license server for your workspace lost. Please contact your administrator to continue using Dify.', + licenseLostTip: 'Failed to connect Dify license server. Please contact your administrator to continue using Dify.', licenseInactive: 'License Inactive', licenseInactiveTip: 'The Dify Enterprise license for your workspace is inactive. Please contact your administrator to continue using Dify.', } diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 4f73723c97b447..7f64c954b1554e 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -101,8 +101,8 @@ const translation = { noLoginMethodTip: '请联系系统管理员添加身份认证方式', licenseExpired: '许可证已过期', licenseExpiredTip: '您所在空间的 Dify Enterprise 许可证已过期,请联系管理员以继续使用 Dify。', - licenseLost: '认证服务器丢失', - licenseLostTip: '您所在空间的 Dify Enterprise 认证服务器已丢失,请联系管理员以继续使用 Dify。', + licenseLost: '许可证丢失', + licenseLostTip: '无法连接 Dify 许可证服务器,请联系管理员以继续使用 Dify。', licenseInactive: '许可证未激活', licenseInactiveTip: '您所在空间的 Dify Enterprise 许可证尚未激活,请联系管理员以继续使用 Dify。', } From a66e44211b03b45ff028b1d7e8a2a03ff6e86a6d Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 14 Nov 2024 10:34:39 +0800 Subject: [PATCH 7/9] fix: supports force logout when license expired or license server lost --- web/service/base.ts | 161 +++++++++++++++++++++++++++++++------------- web/utils/index.ts | 6 +- 2 files changed, 118 insertions(+), 49 deletions(-) diff --git a/web/service/base.ts b/web/service/base.ts index 6cb732c55da3c4..6bb5979d7065b6 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -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 = (url: string, options = {}, otherOptions?: IOtherOptions) => { - return new Promise((resolve, reject) => { +export const request = async(url: string, options = {}, otherOptions?: IOtherOptions) => { + try { const otherOptionsForBaseFetch = otherOptions || {} - baseFetch(url, options, otherOptionsForBaseFetch).then(resolve).catch((errResp) => { - if (errResp?.status === 401) { - return refreshAccessTokenOrRelogin(TIME_OUT).then(() => { - baseFetch(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() - } + const [err, resp] = await asyncRunSafe(baseFetch(url, options, otherOptionsForBaseFetch)) + if (err === null) + return resp + const errResp: Response = err as any + if (errResp.status === 401) { + const [parseErr, errRespData] = await asyncRunSafe(errResp.json()) + const loginUrl = `${globalThis.location.origin}/signin` + if (parseErr) { + globalThis.location.href = loginUrl + return Promise.reject(err) + } + // 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) + } - 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 - }) - }) + // refresh token + const [refreshErr] = await asyncRunSafe(refreshAccessTokenOrRelogin(TIME_OUT)) + if (refreshErr === null) + return baseFetch(url, options, otherOptionsForBaseFetch) + if (location.pathname !== '/signin' || !IS_CE_EDITION) { + globalThis.location.href = loginUrl + return Promise.reject(err) } - else { - reject(errResp) + 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((resolve, reject) => { + // baseFetch(url, options, otherOptionsForBaseFetch).then(resolve).catch((errResp) => { + // if (errResp?.status === 401) { + // return refreshAccessTokenOrRelogin(TIME_OUT).then(() => { + // baseFetch(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 diff --git a/web/utils/index.ts b/web/utils/index.ts index 7aa6fef0a88c09..cabad6c35c766b 100644 --- a/web/utils/index.ts +++ b/web/utils/index.ts @@ -8,10 +8,8 @@ export async function asyncRunSafe(fn: Promise): 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')] } } From 09010ed83620680d6a8766bb3cadb39cd563ba4c Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 14 Nov 2024 13:59:24 +0800 Subject: [PATCH 8/9] fix: page always reload if error code is unauthorized_and_force_logout --- web/service/base.ts | 52 +++------------------------------------------ 1 file changed, 3 insertions(+), 49 deletions(-) diff --git a/web/service/base.ts b/web/service/base.ts index 6bb5979d7065b6..de09e9d268a590 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -561,6 +561,7 @@ export const request = async(url: string, options = {}, otherOptions?: IOther if (errResp.status === 401) { const [parseErr, errRespData] = await asyncRunSafe(errResp.json()) const loginUrl = `${globalThis.location.origin}/signin` + console.log(parseErr, errRespData) if (parseErr) { globalThis.location.href = loginUrl return Promise.reject(err) @@ -572,9 +573,9 @@ export const request = async(url: string, options = {}, otherOptions?: IOther requiredWebSSOLogin() return Promise.reject(err) } - // force logout if (code === 'unauthorized_and_force_logout') { - removeAccessToken() + localStorage.removeItem('console_token') + localStorage.removeItem('refresh_token') globalThis.location.reload() return Promise.reject(err) } @@ -623,53 +624,6 @@ export const request = async(url: string, options = {}, otherOptions?: IOther console.error(error) return Promise.reject(error) } - // return new Promise((resolve, reject) => { - // baseFetch(url, options, otherOptionsForBaseFetch).then(resolve).catch((errResp) => { - // if (errResp?.status === 401) { - // return refreshAccessTokenOrRelogin(TIME_OUT).then(() => { - // baseFetch(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 From a1ac8c2d2e84e46817bf62d08d58fce47c507b02 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 14 Nov 2024 17:48:33 +0800 Subject: [PATCH 9/9] fix: remove console.log --- web/service/base.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/web/service/base.ts b/web/service/base.ts index de09e9d268a590..9ee3033d8e2f3f 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -561,7 +561,6 @@ export const request = async(url: string, options = {}, otherOptions?: IOther if (errResp.status === 401) { const [parseErr, errRespData] = await asyncRunSafe(errResp.json()) const loginUrl = `${globalThis.location.origin}/signin` - console.log(parseErr, errRespData) if (parseErr) { globalThis.location.href = loginUrl return Promise.reject(err)