@autional/shared 0.1.0-rc.38 → 0.1.0-rc.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/generated/api.ts
CHANGED
|
@@ -5660,15 +5660,6 @@ export async function authOauthAccounts() {
|
|
|
5660
5660
|
return res.data;
|
|
5661
5661
|
}
|
|
5662
5662
|
|
|
5663
|
-
/**
|
|
5664
|
-
* 绑定OAuth账号
|
|
5665
|
-
* 为当前用户绑定第三方OAuth账号
|
|
5666
|
-
*/
|
|
5667
|
-
export async function authOauthBindPost(data: BindOAuthRequest) {
|
|
5668
|
-
const res = await api.post(`/identity/api/v1/auth/oauth/bind`, data);
|
|
5669
|
-
return res.data;
|
|
5670
|
-
}
|
|
5671
|
-
|
|
5672
5663
|
/**
|
|
5673
5664
|
* 获取OAuth提供商列表
|
|
5674
5665
|
* 获取系统支持的所有OAuth登录提供者列表
|
|
@@ -6010,24 +6001,6 @@ export async function authSendVerificationEmailPost(data: SendVerificationEmailR
|
|
|
6010
6001
|
return res.data;
|
|
6011
6002
|
}
|
|
6012
6003
|
|
|
6013
|
-
/**
|
|
6014
|
-
* 企业SSO回调
|
|
6015
|
-
* 接收企业身份提供商的回调信息,验证state并交换本地访问令牌
|
|
6016
|
-
*/
|
|
6017
|
-
export async function authSsoCallbackPost(data: SSOCallbackRequest) {
|
|
6018
|
-
const res = await api.post(`/identity/api/v1/auth/sso/callback`, data);
|
|
6019
|
-
return res.data;
|
|
6020
|
-
}
|
|
6021
|
-
|
|
6022
|
-
/**
|
|
6023
|
-
* 启动企业SSO登录
|
|
6024
|
-
* 根据指定的SSO提供商(SAML或OIDC)生成授权URL与state参数,通过PKCE和CSRF state保护,引导用户跳转至企业身份提供商进行认证。参考:SAML 2.0 Core §3.4、OpenID Connect Core 1.0 §3、RFC 7636 (PKCE)。
|
|
6025
|
-
*/
|
|
6026
|
-
export async function authSsoInitiatePost(data: SSOInitiateRequest) {
|
|
6027
|
-
const res = await api.post(`/identity/api/v1/auth/sso/initiate`, data);
|
|
6028
|
-
return res.data;
|
|
6029
|
-
}
|
|
6030
|
-
|
|
6031
6004
|
/**
|
|
6032
6005
|
* 票据签名登录
|
|
6033
6006
|
* 使用后台生成的一次性票据完成登录,票据验证成功后立即失效(一次性使用),返回JWT令牌。适用于跨系统SSO和管理员代登录场景。参考:RFC 6749 §1.5。
|
|
@@ -7976,15 +7949,6 @@ export async function oauthAuthorizePost(data: Record<string, unknown>) {
|
|
|
7976
7949
|
return res.data;
|
|
7977
7950
|
}
|
|
7978
7951
|
|
|
7979
|
-
/**
|
|
7980
|
-
* 绑定 OAuth 账号
|
|
7981
|
-
* 将当前用户的 Autional 账号与第三方 OAuth 提供商账号绑定。需 JWT 认证,请求体中的 user_id 必须与 JWT subject 一致。
|
|
7982
|
-
*/
|
|
7983
|
-
export async function oauthBindPost(data: BindOAuthRequest) {
|
|
7984
|
-
const res = await api.post(`/oauth/api/v1/oauth/bind`, data);
|
|
7985
|
-
return res.data;
|
|
7986
|
-
}
|
|
7987
|
-
|
|
7988
7952
|
/**
|
|
7989
7953
|
* 获取客户端公开信息
|
|
7990
7954
|
* 根据 client_id 返回客户端的非敏感公开信息(名称、Logo、Scopes、TenantID)。用于 consent 授权页面展示。
|
package/src/generated/queries.ts
CHANGED
|
@@ -8047,17 +8047,6 @@ export function usePostAuthMfaVerify_challenge() {
|
|
|
8047
8047
|
});
|
|
8048
8048
|
}
|
|
8049
8049
|
|
|
8050
|
-
/** 绑定OAuth账号 */
|
|
8051
|
-
export function usePostAuthOauthBind() {
|
|
8052
|
-
const qc = useQueryClient();
|
|
8053
|
-
return useMutation({
|
|
8054
|
-
mutationFn: (data: any) => api.authOauthBindPost(data),
|
|
8055
|
-
onSuccess: () => {
|
|
8056
|
-
qc.invalidateQueries({ queryKey: ['identity-service'] });
|
|
8057
|
-
},
|
|
8058
|
-
});
|
|
8059
|
-
}
|
|
8060
|
-
|
|
8061
8050
|
/** 解绑OAuth账号 */
|
|
8062
8051
|
export function usePostAuthOauthUnbind() {
|
|
8063
8052
|
const qc = useQueryClient();
|
|
@@ -8355,28 +8344,6 @@ export function usePostAuthSend_verification_email() {
|
|
|
8355
8344
|
});
|
|
8356
8345
|
}
|
|
8357
8346
|
|
|
8358
|
-
/** 企业SSO回调 */
|
|
8359
|
-
export function usePostAuthSsoCallback() {
|
|
8360
|
-
const qc = useQueryClient();
|
|
8361
|
-
return useMutation({
|
|
8362
|
-
mutationFn: (data: any) => api.authSsoCallbackPost(data),
|
|
8363
|
-
onSuccess: () => {
|
|
8364
|
-
qc.invalidateQueries({ queryKey: ['identity-service'] });
|
|
8365
|
-
},
|
|
8366
|
-
});
|
|
8367
|
-
}
|
|
8368
|
-
|
|
8369
|
-
/** 启动企业SSO登录 */
|
|
8370
|
-
export function usePostAuthSsoInitiate() {
|
|
8371
|
-
const qc = useQueryClient();
|
|
8372
|
-
return useMutation({
|
|
8373
|
-
mutationFn: (data: any) => api.authSsoInitiatePost(data),
|
|
8374
|
-
onSuccess: () => {
|
|
8375
|
-
qc.invalidateQueries({ queryKey: ['identity-service'] });
|
|
8376
|
-
},
|
|
8377
|
-
});
|
|
8378
|
-
}
|
|
8379
|
-
|
|
8380
8347
|
/** 票据签名登录 */
|
|
8381
8348
|
export function usePostAuthTicketSignin() {
|
|
8382
8349
|
const qc = useQueryClient();
|
|
@@ -9703,17 +9670,6 @@ export function usePostOauthAuthorize() {
|
|
|
9703
9670
|
});
|
|
9704
9671
|
}
|
|
9705
9672
|
|
|
9706
|
-
/** 绑定 OAuth 账号 */
|
|
9707
|
-
export function usePostOauthBind() {
|
|
9708
|
-
const qc = useQueryClient();
|
|
9709
|
-
return useMutation({
|
|
9710
|
-
mutationFn: (data: any) => api.oauthBindPost(data),
|
|
9711
|
-
onSuccess: () => {
|
|
9712
|
-
qc.invalidateQueries({ queryKey: ['oauth-service'] });
|
|
9713
|
-
},
|
|
9714
|
-
});
|
|
9715
|
-
}
|
|
9716
|
-
|
|
9717
9673
|
/** 撤销授权同意 */
|
|
9718
9674
|
export function useDeleteOauthConsentsByConsents() {
|
|
9719
9675
|
const qc = useQueryClient();
|
package/src/generated/types.ts
CHANGED
|
@@ -4,19 +4,36 @@ import { extractApiError, extractApiErrorMessage } from '../error';
|
|
|
4
4
|
// UP-17-B 回归锁(AC-401):extractApiError message 键链。
|
|
5
5
|
// 后端 Problem 契约(service-core/base/dto/problem.go)为 title 必填 / detail / code / i18n_key,无 message;
|
|
6
6
|
// 只认 message 会把 Problem 类错误整类退化为 defaultMsg。
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// U380 回归锁:detail 优先于 title,对齐 Problem.GetMessage()(Detail 非空优先)。
|
|
8
|
+
describe('extractApiError message 键链(UP-17-B / AC-401 / U380)', () => {
|
|
9
|
+
it('detail 优先:Problem 契约(title/detail/code)→ 取 detail', () => {
|
|
9
10
|
const err = {
|
|
10
|
-
response: { data: { code: 403, title: '
|
|
11
|
+
response: { data: { code: 403, title: 'Platform Access Denied', detail: '需要平台角色' } },
|
|
11
12
|
};
|
|
12
13
|
const out = extractApiError(err, 'fallback');
|
|
13
|
-
expect(out.message).toBe('
|
|
14
|
+
expect(out.message).toBe('需要平台角色');
|
|
14
15
|
expect(out.code).toBe(403);
|
|
15
16
|
});
|
|
16
17
|
|
|
17
|
-
it('
|
|
18
|
-
const err = { response: { data: {
|
|
19
|
-
expect(extractApiError(err, 'fallback').message).toBe('
|
|
18
|
+
it('title 兜底:无 message/detail 时取 title', () => {
|
|
19
|
+
const err = { response: { data: { title: 'Invalid Request' } } };
|
|
20
|
+
expect(extractApiError(err, 'fallback').message).toBe('Invalid Request');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('U380:英文 title + 中文 detail → 中文 detail 胜出', () => {
|
|
24
|
+
const err = {
|
|
25
|
+
response: {
|
|
26
|
+
data: {
|
|
27
|
+
code: 61040050,
|
|
28
|
+
title: 'push challenge not found',
|
|
29
|
+
detail: '推送挑战未找到',
|
|
30
|
+
i18n_key: 'error.push_challenge_not_found',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
const out = extractApiError(err, 'fallback');
|
|
35
|
+
expect(out.message).toBe('推送挑战未找到');
|
|
36
|
+
expect(out.i18nKey).toBe('error.push_challenge_not_found');
|
|
20
37
|
});
|
|
21
38
|
|
|
22
39
|
it('皆无回落 err.message,再皆无回落 defaultMsg', () => {
|
|
@@ -52,8 +69,8 @@ describe('extractApiError i18n_key 透出(AUTH-46)', () => {
|
|
|
52
69
|
};
|
|
53
70
|
const out = extractApiError(err, 'fallback');
|
|
54
71
|
expect(out.i18nKey).toBe('error.oauth_state_missing');
|
|
55
|
-
// message
|
|
56
|
-
expect(out.message).toBe('
|
|
72
|
+
// U380:键链为 message → detail → title
|
|
73
|
+
expect(out.message).toBe('state not found');
|
|
57
74
|
});
|
|
58
75
|
|
|
59
76
|
it('响应拦截器深 camel 后(i18nKey)同样识别', () => {
|
package/src/utils/error.ts
CHANGED
|
@@ -17,13 +17,15 @@ export function extractApiErrorMessage(err: unknown, defaultMsg: string): string
|
|
|
17
17
|
|
|
18
18
|
export function extractApiError(err: unknown, defaultMsg: string): ExtractedApiError {
|
|
19
19
|
// UP-17-B:后端 Problem 契约(service-core/base/dto/problem.go)字段为 title(必填)/ detail / code / i18n_key,
|
|
20
|
-
// **没有 message** —— 只认 message 会把整类后端错误退化成 defaultMsg
|
|
20
|
+
// **没有 message** —— 只认 message 会把整类后端错误退化成 defaultMsg。
|
|
21
|
+
// U380:键链 message → detail → title,对齐 Problem.GetMessage()(Detail 非空优先),
|
|
22
|
+
// 避免英文 title 压过本地化 detail。
|
|
21
23
|
// 继续用 `||`(而非 `??`):空串语义按「缺省」处理,与既有实现一致。
|
|
22
24
|
// AUTH-46:附加透出 i18n_key(响应拦截器深 camel 后为 i18nKey,两者都认)。
|
|
23
25
|
const data = (err as any)?.response?.data;
|
|
24
26
|
return {
|
|
25
27
|
code: data?.code || 'UNKNOWN',
|
|
26
|
-
message: data?.message || data?.
|
|
28
|
+
message: data?.message || data?.detail || data?.title || (err as any)?.message || defaultMsg,
|
|
27
29
|
i18nKey: data?.i18n_key || data?.i18nKey || undefined,
|
|
28
30
|
};
|
|
29
31
|
}
|