From 97cfa002b095d07fc04800b084a37cbbc01e50ca Mon Sep 17 00:00:00 2001 From: colin Date: Sun, 19 Jan 2025 17:15:38 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20feat:=20=E7=BB=9F=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E7=90=86=E8=AF=B7=E6=B1=82=E7=BB=93=E6=9E=9C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app-antd/src/adapter/request/index.ts | 40 +++++++++---------- .../app-antd/src/locales/langs/en-US/abp.json | 8 ++-- .../app-antd/src/locales/langs/zh-CN/abp.json | 8 ++-- .../packages/@abp/account/src/hooks/index.ts | 1 + .../@abp/account/src/hooks/useOAuthError.ts | 16 ++++++++ apps/vben5/packages/@abp/account/src/index.ts | 1 + .../packages/@abp/core/src/types/error.ts | 14 +++++++ .../packages/@abp/core/src/types/index.ts | 1 + .../applications/ApplicationModal.vue | 22 ++++++++++ .../packages/@abp/request/src/hooks/index.ts | 2 + .../@abp/request/src/hooks/useErrorFormat.ts | 28 +++++++++++++ .../request/src/hooks/useWrapperResult.ts | 35 ++++++++++++++++ 12 files changed, 147 insertions(+), 29 deletions(-) create mode 100644 apps/vben5/packages/@abp/account/src/hooks/index.ts create mode 100644 apps/vben5/packages/@abp/account/src/hooks/useOAuthError.ts create mode 100644 apps/vben5/packages/@abp/core/src/types/error.ts create mode 100644 apps/vben5/packages/@abp/request/src/hooks/useErrorFormat.ts create mode 100644 apps/vben5/packages/@abp/request/src/hooks/useWrapperResult.ts diff --git a/apps/vben5/apps/app-antd/src/adapter/request/index.ts b/apps/vben5/apps/app-antd/src/adapter/request/index.ts index f3d1b3286..855047496 100644 --- a/apps/vben5/apps/app-antd/src/adapter/request/index.ts +++ b/apps/vben5/apps/app-antd/src/adapter/request/index.ts @@ -1,4 +1,3 @@ -import { $t } from '@vben/locales'; import { preferences } from '@vben/preferences'; import { authenticateResponseInterceptor, @@ -6,8 +5,8 @@ import { } from '@vben/request'; import { useAccessStore } from '@vben/stores'; -import { useTokenApi } from '@abp/account'; -import { requestClient } from '@abp/request'; +import { useOAuthError, useTokenApi } from '@abp/account'; +import { requestClient, useWrapperResult } from '@abp/request'; import { message } from 'ant-design-vue'; import { useAuthStore } from '#/store'; @@ -38,13 +37,17 @@ export function initRequestClient() { async function doRefreshToken() { const accessStore = useAccessStore(); if (accessStore.refreshToken) { - const { accessToken, tokenType, refreshToken } = await refreshTokenApi({ - refreshToken: accessStore.refreshToken, - }); - const newToken = `${tokenType} ${accessToken}`; - accessStore.setAccessToken(newToken); - accessStore.setRefreshToken(refreshToken); - return newToken; + try { + const { accessToken, tokenType, refreshToken } = await refreshTokenApi({ + refreshToken: accessStore.refreshToken, + }); + const newToken = `${tokenType} ${accessToken}`; + accessStore.setAccessToken(newToken); + accessStore.setRefreshToken(refreshToken); + return newToken; + } catch { + console.warn('The refresh token has expired or is unavailable.'); + } } return ''; } @@ -68,17 +71,11 @@ export function initRequestClient() { // response数据解构 requestClient.addResponseInterceptor({ fulfilled: (response) => { - const { data, status, headers } = response; - - if (headers._abpwrapresult === 'true') { - const { code, result, message, details } = data; - const hasSuccess = data && Reflect.has(data, 'code') && code === '0'; - if (hasSuccess) { - return result; - } - const content = details || message; + const { data, status } = response; + const { hasWrapResult, getData } = useWrapperResult(response); - throw Object.assign({}, response, { response, message: content }); + if (hasWrapResult()) { + return getData(); } if (status >= 200 && status < 400) { @@ -107,7 +104,8 @@ export function initRequestClient() { // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; if (responseData?.error_description) { - message.error($t(`abp.oauth.${responseData.error_description}`) || msg); + const { formatError } = useOAuthError(); + message.error(formatError(responseData) || msg); return; } const errorMessage = responseData?.error ?? responseData?.message ?? ''; diff --git a/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json b/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json index 1b110751a..bf9483a03 100644 --- a/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json +++ b/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json @@ -1,10 +1,10 @@ { "title": "Abp Framework", "oauth": { - "Invalid username or password!": "Invalid username or password!", - "Invalid authenticator code!": "Invalid authenticator code!", - "The specified refresh token is no longer valid.": "The session has expired. Please log in again!", - "RequiresTwoFactor": "Requires Two Factor", + "invalidUserNameOrPassword": "Invalid username or password!!", + "invalidAuthenticatorCode": "Invalid authenticator code!", + "sessionExpired": "The session has expired. Please log in again!", + "requiresTwoFactor": "Requires Two Factor", "twoFactor": { "title": "Two Factor", "authenticator": "Authenticator", diff --git a/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json b/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json index 68d50daa0..553f0ccb6 100644 --- a/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json +++ b/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json @@ -1,10 +1,10 @@ { "title": "Abp框架", "oauth": { - "Invalid username or password!": "用户名或密码错误!", - "Invalid authenticator code!": "无效的验证器代码!", - "The specified refresh token is no longer valid.": "会话已过期,请重新登陆!", - "RequiresTwoFactor": "需要二次认证", + "invalidUserNameOrPassword": "用户名或密码错误!", + "invalidAuthenticatorCode": "无效的验证器代码!", + "sessionExpired": "会话已过期,请重新登陆!", + "requiresTwoFactor": "需要二次认证", "twoFactor": { "title": "二次认证", "authenticator": "验证方式", diff --git a/apps/vben5/packages/@abp/account/src/hooks/index.ts b/apps/vben5/packages/@abp/account/src/hooks/index.ts new file mode 100644 index 000000000..6c4512ba9 --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/hooks/index.ts @@ -0,0 +1 @@ +export * from './useOAuthError'; diff --git a/apps/vben5/packages/@abp/account/src/hooks/useOAuthError.ts b/apps/vben5/packages/@abp/account/src/hooks/useOAuthError.ts new file mode 100644 index 000000000..d40ada311 --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/hooks/useOAuthError.ts @@ -0,0 +1,16 @@ +interface OAuthError { + error: string; + error_description?: string; + error_uri?: string; +} + +export function useOAuthError() { + function formatError(error: OAuthError) { + // TODO: 解决oauth消息国际化. + return error.error_description; + } + + return { + formatError, + }; +} diff --git a/apps/vben5/packages/@abp/account/src/index.ts b/apps/vben5/packages/@abp/account/src/index.ts index 314dad0cd..14fa9fe25 100644 --- a/apps/vben5/packages/@abp/account/src/index.ts +++ b/apps/vben5/packages/@abp/account/src/index.ts @@ -1,3 +1,4 @@ export * from './api'; export * from './components'; +export * from './hooks'; export * from './types'; diff --git a/apps/vben5/packages/@abp/core/src/types/error.ts b/apps/vben5/packages/@abp/core/src/types/error.ts new file mode 100644 index 000000000..a51bf5d9e --- /dev/null +++ b/apps/vben5/packages/@abp/core/src/types/error.ts @@ -0,0 +1,14 @@ +interface RemoteServiceValidationErrorInfo { + members: string[]; + message: string; +} + +interface RemoteServiceErrorInfo { + code?: string; + data?: Record; + details?: string; + message?: string; + validationErrors?: RemoteServiceValidationErrorInfo[]; +} + +export type { RemoteServiceErrorInfo }; diff --git a/apps/vben5/packages/@abp/core/src/types/index.ts b/apps/vben5/packages/@abp/core/src/types/index.ts index efa5c216b..e31262935 100644 --- a/apps/vben5/packages/@abp/core/src/types/index.ts +++ b/apps/vben5/packages/@abp/core/src/types/index.ts @@ -1,4 +1,5 @@ export * from './dto'; +export * from './error'; export * from './features'; export * from './global'; export * from './localization'; diff --git a/apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationModal.vue b/apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationModal.vue index 81ebe64cd..01690113d 100644 --- a/apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationModal.vue +++ b/apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationModal.vue @@ -26,6 +26,7 @@ import { $t } from '@vben/locales'; import { DownOutlined } from '@ant-design/icons-vue'; import { + Checkbox, Dropdown, Form, Input, @@ -138,6 +139,9 @@ const getSupportScopes = computed((): TransferItem[] => { }; }); }); +const getPkceEnabled = computed(() => { + return formModel.value.requirements?.includes('pkce'); +}); const { discoveryApi } = useOpenIdApi(); const { cancel, createApi, getApi, updateApi } = useApplicationsApi(); @@ -266,6 +270,13 @@ function onUriDelete(uri: string) { } } } +function onPkceChange(checked: boolean) { + const requirements: string[] = []; + if (checked) { + requirements.push('pkce'); + } + formModel.value.requirements = requirements; +}