@liujitcn/kratos-admin-core 0.0.66 → 0.0.68

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.
Files changed (43) hide show
  1. package/dist/package/declarations/src/api/base/v1/login.d.ts +1 -3
  2. package/dist/package/declarations/src/api/base/v1/secret_crypto.d.ts +9 -0
  3. package/dist/package/declarations/src/components/Dialog/PasswordVerifyDialog.vue.d.ts +3 -7
  4. package/dist/package/declarations/src/components/ProForm/components/ProFormItem.vue.d.ts +6 -6
  5. package/dist/package/declarations/src/components/ProForm/components/SecretInput.vue.d.ts +23 -0
  6. package/dist/package/declarations/src/components/ProForm/interface/index.d.ts +14 -1
  7. package/dist/package/declarations/src/locales/generated.d.ts +32 -0
  8. package/dist/package/declarations/src/rpc/base/v1/login.d.ts +2 -39
  9. package/dist/package/declarations/src/rpc/base/v1/mfa.d.ts +3 -3
  10. package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +2 -2
  11. package/dist/package/declarations/src/rpc/base/v1/secret_crypto.d.ts +37 -0
  12. package/dist/package/declarations/src/rpc/common/v1/types.d.ts +4 -4
  13. package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +3 -3
  14. package/dist/package/declarations/src/security.d.ts +1 -1
  15. package/dist/package/declarations/src/utils/secretCrypto.d.ts +19 -0
  16. package/dist/package/src/api/base/v1/login.ts +0 -12
  17. package/dist/package/src/api/base/v1/secret_crypto.ts +35 -0
  18. package/dist/package/src/components/Dialog/PasswordVerifyDialog.vue +4 -8
  19. package/dist/package/src/components/ProForm/components/ProFormItem.vue +24 -1
  20. package/dist/package/src/components/ProForm/components/SecretInput.vue +117 -0
  21. package/dist/package/src/components/ProForm/index.vue +1 -0
  22. package/dist/package/src/components/ProForm/interface/index.ts +15 -0
  23. package/dist/package/src/components/ProTable/index.vue +8 -1
  24. package/dist/package/src/locales/README.md +1 -1
  25. package/dist/package/src/locales/en-US.json +9 -1
  26. package/dist/package/src/locales/ja-JP.json +9 -1
  27. package/dist/package/src/locales/zh-CN.json +9 -1
  28. package/dist/package/src/locales/zh-TW.json +9 -1
  29. package/dist/package/src/rpc/base/v1/login.ts +2 -42
  30. package/dist/package/src/rpc/base/v1/mfa.ts +3 -3
  31. package/dist/package/src/rpc/base/v1/oauth.ts +2 -2
  32. package/dist/package/src/rpc/base/v1/secret_crypto.ts +49 -0
  33. package/dist/package/src/rpc/common/v1/types.ts +4 -4
  34. package/dist/package/src/rpc/system/admin/v1/auth.ts +3 -3
  35. package/dist/package/src/security.ts +1 -1
  36. package/dist/package/src/utils/request.ts +3 -3
  37. package/dist/package/src/utils/{passwordCrypto.ts → secretCrypto.ts} +112 -50
  38. package/dist/package/src/views/demo/components/DemoFormDialog.vue +3 -3
  39. package/dist/package/src/views/demo/table/index.vue +2 -2
  40. package/dist/package/src/views/demo/tree-grid/index.vue +1 -1
  41. package/dist/package/src/views/login/components/LoginForm.vue +2 -2
  42. package/package.json +6 -2
  43. package/dist/package/declarations/src/utils/passwordCrypto.d.ts +0 -6
@@ -1,4 +1,4 @@
1
- import type { CaptchaRequest, CaptchaResponse, LogoutRequest, LoginRequest, LoginResponse, PasswordPublicKeyRequest, PasswordPublicKeyResponse, RefreshTokenRequest, RefreshTokenResponse, VerifyCaptchaRequest, VerifyCaptchaResponse, LoginService } from "../../../rpc/base/v1/login";
1
+ import type { CaptchaRequest, CaptchaResponse, LogoutRequest, LoginRequest, LoginResponse, RefreshTokenRequest, RefreshTokenResponse, VerifyCaptchaRequest, VerifyCaptchaResponse, LoginService } from "../../../rpc/base/v1/login";
2
2
  import type { Empty } from "../../../rpc/google/protobuf/empty";
3
3
  /** 登录公共服务 */
4
4
  export declare class LoginServiceImpl implements LoginService {
@@ -6,8 +6,6 @@ export declare class LoginServiceImpl implements LoginService {
6
6
  Captcha(request: CaptchaRequest): Promise<CaptchaResponse>;
7
7
  /** 验证码预校验 */
8
8
  VerifyCaptcha(request: VerifyCaptchaRequest): Promise<VerifyCaptchaResponse>;
9
- /** 获取密码临时公钥 */
10
- PasswordPublicKey(request: PasswordPublicKeyRequest): Promise<PasswordPublicKeyResponse>;
11
9
  /** 登录 */
12
10
  Login(request: LoginRequest): Promise<LoginResponse>;
13
11
  /** 登出 */
@@ -0,0 +1,9 @@
1
+ import type { GetSecretPublicKeyRequest, GetSecretPublicKeyResponse, RevealSecretFieldRequest, RevealSecretFieldResponse, SecretCryptoService } from "../../../rpc/base/v1/secret_crypto";
2
+ /** 敏感字段加密公共服务 */
3
+ export declare class SecretCryptoServiceImpl implements SecretCryptoService {
4
+ /** 获取敏感字段临时公钥 */
5
+ GetSecretPublicKey(request: GetSecretPublicKeyRequest): Promise<GetSecretPublicKeyResponse>;
6
+ /** 查看密钥字段明文 */
7
+ RevealSecretField(request: RevealSecretFieldRequest): Promise<RevealSecretFieldResponse>;
8
+ }
9
+ export declare const defSecretCryptoService: SecretCryptoServiceImpl;
@@ -1,6 +1,5 @@
1
1
  import type { ProFormLabelPosition } from "../../components/ProForm/interface";
2
- import type { PasswordCryptoScene } from "../../utils/passwordCrypto";
3
- import type { PasswordCrypto } from "../../rpc/common/v1/types";
2
+ import type { SecretCrypto } from "../../rpc/common/v1/types";
4
3
  /** 通用密码验证弹窗属性。 */
5
4
  interface PasswordVerifyDialogProps {
6
5
  /** 弹窗显示状态。 */
@@ -23,8 +22,6 @@ interface PasswordVerifyDialogProps {
23
22
  cancelText?: string;
24
23
  /** 外部业务提交状态。 */
25
24
  confirmLoading?: boolean;
26
- /** 密码加密场景。 */
27
- scene?: PasswordCryptoScene;
28
25
  /** 是否关闭时销毁内容。 */
29
26
  destroyOnClose?: boolean;
30
27
  /** 是否允许点击遮罩关闭。 */
@@ -37,13 +34,13 @@ interface PasswordVerifyDialogProps {
37
34
  labelPosition?: ProFormLabelPosition;
38
35
  }
39
36
  declare const __VLS_export: import("vue").DefineComponent<PasswordVerifyDialogProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
40
- confirm: (password: PasswordCrypto) => any;
37
+ confirm: (password: SecretCrypto) => any;
41
38
  close: () => any;
42
39
  "update:modelValue": (value: boolean) => any;
43
40
  closed: () => any;
44
41
  cancel: () => any;
45
42
  }, string, import("vue").PublicProps, Readonly<PasswordVerifyDialogProps> & Readonly<{
46
- onConfirm?: ((password: PasswordCrypto) => any) | undefined;
43
+ onConfirm?: ((password: SecretCrypto) => any) | undefined;
47
44
  onClose?: (() => any) | undefined;
48
45
  "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
49
46
  onClosed?: (() => any) | undefined;
@@ -63,7 +60,6 @@ declare const __VLS_export: import("vue").DefineComponent<PasswordVerifyDialogPr
63
60
  labelPosition: ProFormLabelPosition;
64
61
  passwordLabel: string;
65
62
  passwordPlaceholder: string;
66
- scene: PasswordCryptoScene;
67
63
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
68
64
  declare const _default: typeof __VLS_export;
69
65
  export default _default;
@@ -4,23 +4,23 @@ interface ProFormItemProps {
4
4
  field: ProFormField;
5
5
  model: Record<string, any>;
6
6
  }
7
- declare var __VLS_10: string, __VLS_11: {
7
+ declare var __VLS_16: string, __VLS_17: {
8
8
  field: ProFormField;
9
9
  model: Record<string, any>;
10
- }, __VLS_145: string, __VLS_146: {
10
+ }, __VLS_157: string, __VLS_158: {
11
11
  option: import("element-plus").TransferDataItem;
12
12
  field: ProFormField;
13
13
  model: Record<string, any>;
14
- }, __VLS_191: string, __VLS_192: {
14
+ }, __VLS_203: string, __VLS_204: {
15
15
  field: ProFormField;
16
16
  model: Record<string, any>;
17
17
  };
18
18
  type __VLS_Slots = {} & {
19
- [K in NonNullable<typeof __VLS_10>]?: (props: typeof __VLS_11) => any;
19
+ [K in NonNullable<typeof __VLS_16>]?: (props: typeof __VLS_17) => any;
20
20
  } & {
21
- [K in NonNullable<typeof __VLS_145>]?: (props: typeof __VLS_146) => any;
21
+ [K in NonNullable<typeof __VLS_157>]?: (props: typeof __VLS_158) => any;
22
22
  } & {
23
- [K in NonNullable<typeof __VLS_191>]?: (props: typeof __VLS_192) => any;
23
+ [K in NonNullable<typeof __VLS_203>]?: (props: typeof __VLS_204) => any;
24
24
  };
25
25
  declare const __VLS_base: import("vue").DefineComponent<ProFormItemProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ProFormItemProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
26
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -0,0 +1,23 @@
1
+ import type { ProFormSecretConfig } from "../../../components/ProForm/interface";
2
+ /** SecretInput 组件属性。 */
3
+ interface SecretInputProps {
4
+ /** 字段值。 */
5
+ modelValue?: string;
6
+ /** 查看配置:声明后眼睛点击时按需拉取明文。 */
7
+ secret?: boolean | ProFormSecretConfig;
8
+ /** 查看的资源标识。 */
9
+ resource?: string;
10
+ /** 查看的字段名。 */
11
+ fieldName?: string;
12
+ /** 记录ID。 */
13
+ recordId?: number;
14
+ /** 是否已配置密钥。 */
15
+ configured?: boolean;
16
+ }
17
+ declare const __VLS_export: import("vue").DefineComponent<SecretInputProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
18
+ "update:modelValue": (value: string) => any;
19
+ }, string, import("vue").PublicProps, Readonly<SecretInputProps> & Readonly<{
20
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
21
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
+ declare const _default: typeof __VLS_export;
23
+ export default _default;
@@ -1,7 +1,7 @@
1
1
  import type { FormItemRule } from "element-plus";
2
2
  import type { Component } from "vue";
3
3
  /** ProForm 支持的字段组件类型。 */
4
- export type ProFormComponentType = "input" | "password" | "textarea" | "yaml-editor" | "input-number" | "color-picker" | "segmented" | "switch" | "checkbox" | "select" | "tenant-select" | "dict" | "radio-group" | "checkbox-group" | "tree-select" | "date-picker" | "cron-expression" | "transfer" | "image-upload" | "images-upload" | "file-upload" | "files-upload" | "rich-text" | "dynamic-list" | "kv-list" | "slot";
4
+ export type ProFormComponentType = "input" | "password" | "textarea" | "yaml-editor" | "input-number" | "color-picker" | "segmented" | "switch" | "checkbox" | "select" | "cascader" | "tenant-select" | "dict" | "radio-group" | "checkbox-group" | "tree-select" | "date-picker" | "cron-expression" | "transfer" | "image-upload" | "images-upload" | "file-upload" | "files-upload" | "rich-text" | "dynamic-list" | "kv-list" | "slot";
5
5
  /** ProForm 标签布局方向。 */
6
6
  export type ProFormLabelPosition = "left" | "right" | "top";
7
7
  /** ProForm 选择型字段选项。 */
@@ -15,6 +15,17 @@ export interface ProFormOption {
15
15
  /** Element Plus 懒加载树节点是否为叶子节点。 */
16
16
  isLeaf?: boolean;
17
17
  }
18
+ /** secret 字段的查看配置:声明后输入框眼睛点击时按需拉取明文。 */
19
+ export interface ProFormSecretConfig {
20
+ /** 查看明文的资源标识。 */
21
+ resource: string;
22
+ /** 查看明文的字段名。 */
23
+ field: string;
24
+ /** 记录ID字段名,默认 "id"。 */
25
+ idProp?: string;
26
+ /** 已配置标记字段名,默认 `${field}_configured`。 */
27
+ configuredProp?: string;
28
+ }
18
29
  /** ProForm 字段配置。 */
19
30
  export interface ProFormField {
20
31
  /** 字段绑定路径,支持点路径访问嵌套对象。 */
@@ -39,6 +50,8 @@ export interface ProFormField {
39
50
  suffixSlotName?: string;
40
51
  /** 标题提示文案。 */
41
52
  labelTooltip?: string;
53
+ /** 提交时是否加密为 SecretCrypto 结构;配置对象时输入框眼睛支持按需查看明文。 */
54
+ secret?: boolean | ProFormSecretConfig;
42
55
  /** 字段校验规则。 */
43
56
  rules?: FormItemRule[];
44
57
  /** 字段是否显示。 */
@@ -481,6 +481,14 @@ export declare const LOCALE_MESSAGES: {
481
481
  "core.demo.detail.timeline.updated": string;
482
482
  "core.demo.detail.timeline.enabled": string;
483
483
  "core.demo.detail.timeline.disabled": string;
484
+ "core.password.reveal_unsupported": string;
485
+ "core.password.reveal_failed": string;
486
+ "core.demo.table.tag_item": string;
487
+ "core.demo.table.money_unit": string;
488
+ "core.demo.form.tenant.main": string;
489
+ "core.demo.form.tenant.sub": string;
490
+ "core.demo.form.leader_title": string;
491
+ "core.demo.tree.new_dir": string;
484
492
  };
485
493
  readonly "en-US": {
486
494
  "common.action.back": string;
@@ -960,6 +968,14 @@ export declare const LOCALE_MESSAGES: {
960
968
  "core.demo.detail.timeline.updated": string;
961
969
  "core.demo.detail.timeline.enabled": string;
962
970
  "core.demo.detail.timeline.disabled": string;
971
+ "core.password.reveal_unsupported": string;
972
+ "core.password.reveal_failed": string;
973
+ "core.demo.table.tag_item": string;
974
+ "core.demo.table.money_unit": string;
975
+ "core.demo.form.tenant.main": string;
976
+ "core.demo.form.tenant.sub": string;
977
+ "core.demo.form.leader_title": string;
978
+ "core.demo.tree.new_dir": string;
963
979
  };
964
980
  readonly "ja-JP": {
965
981
  "common.action.back": string;
@@ -1439,6 +1455,14 @@ export declare const LOCALE_MESSAGES: {
1439
1455
  "core.demo.detail.timeline.updated": string;
1440
1456
  "core.demo.detail.timeline.enabled": string;
1441
1457
  "core.demo.detail.timeline.disabled": string;
1458
+ "core.password.reveal_unsupported": string;
1459
+ "core.password.reveal_failed": string;
1460
+ "core.demo.table.tag_item": string;
1461
+ "core.demo.table.money_unit": string;
1462
+ "core.demo.form.tenant.main": string;
1463
+ "core.demo.form.tenant.sub": string;
1464
+ "core.demo.form.leader_title": string;
1465
+ "core.demo.tree.new_dir": string;
1442
1466
  };
1443
1467
  readonly "zh-TW": {
1444
1468
  "common.action.back": string;
@@ -1918,6 +1942,14 @@ export declare const LOCALE_MESSAGES: {
1918
1942
  "core.demo.detail.timeline.updated": string;
1919
1943
  "core.demo.detail.timeline.enabled": string;
1920
1944
  "core.demo.detail.timeline.disabled": string;
1945
+ "core.password.reveal_unsupported": string;
1946
+ "core.password.reveal_failed": string;
1947
+ "core.demo.table.tag_item": string;
1948
+ "core.demo.table.money_unit": string;
1949
+ "core.demo.form.tenant.main": string;
1950
+ "core.demo.form.tenant.sub": string;
1951
+ "core.demo.form.leader_title": string;
1952
+ "core.demo.tree.new_dir": string;
1921
1953
  };
1922
1954
  };
1923
1955
  export type GeneratedLocale = keyof typeof LOCALE_MESSAGES;
@@ -1,22 +1,5 @@
1
- import type { PasswordCrypto } from "../../common/v1/types";
1
+ import type { SecretCrypto } from "../../common/v1/types";
2
2
  import type { Empty } from "../../google/protobuf/empty";
3
- /** 密码加密场景枚举。 */
4
- export declare enum PasswordCryptoScene {
5
- /** PASSWORD_CRYPTO_SCENE_UNSPECIFIED - 未指定密码加密场景。 */
6
- PASSWORD_CRYPTO_SCENE_UNSPECIFIED = 0,
7
- /** PASSWORD_CRYPTO_SCENE_LOGIN - 登录密码加密场景。 */
8
- PASSWORD_CRYPTO_SCENE_LOGIN = 1,
9
- /** PASSWORD_CRYPTO_SCENE_CREATE_BASE_USER - 新增后台用户密码加密场景。 */
10
- PASSWORD_CRYPTO_SCENE_CREATE_BASE_USER = 2,
11
- /** PASSWORD_CRYPTO_SCENE_RESET_BASE_USER_PASSWORD - 重置后台用户密码加密场景。 */
12
- PASSWORD_CRYPTO_SCENE_RESET_BASE_USER_PASSWORD = 3,
13
- /** PASSWORD_CRYPTO_SCENE_UPDATE_USER_PASSWORD - 个人修改密码加密场景。 */
14
- PASSWORD_CRYPTO_SCENE_UPDATE_USER_PASSWORD = 4,
15
- /** PASSWORD_CRYPTO_SCENE_MFA - 多因素认证敏感操作场景。 */
16
- PASSWORD_CRYPTO_SCENE_MFA = 5,
17
- /** PASSWORD_CRYPTO_SCENE_CONFIGURE_PASSWORD_POLICY - 密码策略初始化密码配置场景。 */
18
- PASSWORD_CRYPTO_SCENE_CONFIGURE_PASSWORD_POLICY = 6
19
- }
20
3
  /**
21
4
  * LoginStatus 表示登录请求当前所处的认证阶段。
22
5
  * 只有 AUTHENTICATED 或 PASSWORD_CHANGE_REQUIRED 才会携带正式访问令牌,MFA 状态必须继续完成挑战。
@@ -38,11 +21,6 @@ export interface CaptchaRequest {
38
21
  /** 验证码类型,random 表示随机选择当前支持的验证码类型 */
39
22
  type: string;
40
23
  }
41
- /** 密码临时公钥获取条件 */
42
- export interface PasswordPublicKeyRequest {
43
- /** 使用场景 */
44
- scene: PasswordCryptoScene;
45
- }
46
24
  /** 登出请求条件 */
47
25
  export interface LogoutRequest {
48
26
  }
@@ -69,19 +47,6 @@ export interface VerifyCaptchaResponse {
69
47
  /** 有效时间,单位秒 */
70
48
  expires_in: number;
71
49
  }
72
- /** 密码临时公钥响应 */
73
- export interface PasswordPublicKeyResponse {
74
- /** 临时密钥ID */
75
- key_id: string;
76
- /** 临时公钥 */
77
- public_key: string;
78
- /** 加密算法 */
79
- algorithm: string;
80
- /** 随机值 */
81
- nonce: string;
82
- /** 有效时间,单位秒 */
83
- expires_in: number;
84
- }
85
50
  /** 刷新令牌请求参数 */
86
51
  export interface RefreshTokenRequest {
87
52
  /** 更新令牌;未填写时由服务端从HttpOnly Cookie读取。 */
@@ -105,7 +70,7 @@ export interface LoginRequest {
105
70
  /** 用户名,必选项。 */
106
71
  user_name: string;
107
72
  /** 用户的密码,必选项。 */
108
- password: PasswordCrypto | undefined;
73
+ password: SecretCrypto | undefined;
109
74
  /** 验证码 */
110
75
  captcha_code: string;
111
76
  /** 验证码Id */
@@ -142,8 +107,6 @@ export interface LoginService {
142
107
  Captcha(request: CaptchaRequest): Promise<CaptchaResponse>;
143
108
  /** 验证码预校验 */
144
109
  VerifyCaptcha(request: VerifyCaptchaRequest): Promise<VerifyCaptchaResponse>;
145
- /** 获取密码临时公钥 */
146
- PasswordPublicKey(request: PasswordPublicKeyRequest): Promise<PasswordPublicKeyResponse>;
147
110
  /** 登出 */
148
111
  Logout(request: LogoutRequest): Promise<Empty>;
149
112
  /** 刷新认证令牌 */
@@ -1,4 +1,4 @@
1
- import type { PasswordCrypto } from "../../common/v1/types";
1
+ import type { SecretCrypto } from "../../common/v1/types";
2
2
  import type { Empty } from "../../google/protobuf/empty";
3
3
  import type { LoginResponse } from "./login";
4
4
  /** 多因素认证校验请求。 */
@@ -63,7 +63,7 @@ export interface MfaStatusResponse {
63
63
  /** 开始绑定多因素认证请求。 */
64
64
  export interface BeginMfaSetupRequest {
65
65
  /** 当前登录密码 */
66
- password: PasswordCrypto | undefined;
66
+ password: SecretCrypto | undefined;
67
67
  /** 强制绑定场景下的临时票据 */
68
68
  setup_ticket: string;
69
69
  }
@@ -111,7 +111,7 @@ export interface BeginMfaDisableResponse {
111
111
  /** 禁用多因素认证请求。 */
112
112
  export interface DisableMfaRequest {
113
113
  /** 当前登录密码 */
114
- password: PasswordCrypto | undefined;
114
+ password: SecretCrypto | undefined;
115
115
  /** TOTP 动态口令 */
116
116
  code: string;
117
117
  /** WebAuthn 禁用挑战 ID */
@@ -1,4 +1,4 @@
1
- import type { PasswordCrypto } from "../../common/v1/types";
1
+ import type { SecretCrypto } from "../../common/v1/types";
2
2
  import type { Empty } from "../../google/protobuf/empty";
3
3
  import type { LoginStatus } from "./login";
4
4
  /** 个人中心三方账号绑定列表查询条件 */
@@ -59,7 +59,7 @@ export interface BindOauthSessionRequest {
59
59
  /** 用户名 */
60
60
  user_name: string;
61
61
  /** 用户密码 */
62
- password: PasswordCrypto | undefined;
62
+ password: SecretCrypto | undefined;
63
63
  /** 验证码 */
64
64
  captcha_code: string;
65
65
  /** 验证码Id */
@@ -0,0 +1,37 @@
1
+ /** 敏感字段临时公钥获取条件 */
2
+ export interface GetSecretPublicKeyRequest {
3
+ }
4
+ /** 敏感字段临时公钥响应 */
5
+ export interface GetSecretPublicKeyResponse {
6
+ /** 临时密钥ID */
7
+ key_id: string;
8
+ /** 临时公钥 */
9
+ public_key: string;
10
+ /** 加密算法 */
11
+ algorithm: string;
12
+ /** 随机值 */
13
+ nonce: string;
14
+ /** 有效时间,单位秒 */
15
+ expires_in: number;
16
+ }
17
+ /** 密钥字段查看条件 */
18
+ export interface RevealSecretFieldRequest {
19
+ /** 资源标识,如 ai_provider、base_oauth_provider、base_message_provider */
20
+ resource: string;
21
+ /** 记录ID */
22
+ id: number;
23
+ /** 字段名,如 api_key、client_secret */
24
+ field: string;
25
+ }
26
+ /** 密钥字段查看响应 */
27
+ export interface RevealSecretFieldResponse {
28
+ /** 密钥明文 */
29
+ text: string;
30
+ }
31
+ /** 敏感字段加密公共服务 */
32
+ export interface SecretCryptoService {
33
+ /** 获取敏感字段临时公钥,同一次提交的多个密文字段共用该公钥 */
34
+ GetSecretPublicKey(request: GetSecretPublicKeyRequest): Promise<GetSecretPublicKeyResponse>;
35
+ /** 查看密钥字段明文,仅允许查询注册过的密钥字段 */
36
+ RevealSecretField(request: RevealSecretFieldRequest): Promise<RevealSecretFieldResponse>;
37
+ }
@@ -43,8 +43,8 @@ export interface BytesValues {
43
43
  /** 值列表。 */
44
44
  value: Uint8Array[];
45
45
  }
46
- /** 密码密文。 */
47
- export interface PasswordCrypto {
46
+ /** 敏感字段密文,密码与各类密钥字段统一使用。 */
47
+ export interface SecretCrypto {
48
48
  /** 临时密钥ID */
49
49
  key_id: string;
50
50
  /** 随机值 */
@@ -55,6 +55,6 @@ export interface PasswordCrypto {
55
55
  encrypted_key: string;
56
56
  /** 初始化向量 */
57
57
  iv: string;
58
- /** 密码加密数据 */
59
- ciphertext: string;
58
+ /** 传输时为密文,服务端解密后回填明文 */
59
+ text: string;
60
60
  }
@@ -1,4 +1,4 @@
1
- import type { PasswordCrypto, StringValues } from "../../../common/v1/types";
1
+ import type { SecretCrypto, StringValues } from "../../../common/v1/types";
2
2
  import type { Empty } from "../../../google/protobuf/empty";
3
3
  import type { BaseUserIDType } from "../../common/v1/common";
4
4
  import type { BaseMenuType } from "./common";
@@ -151,9 +151,9 @@ export interface RouteParams {
151
151
  /** 用户密码表单 */
152
152
  export interface UserPasswordForm {
153
153
  /** 原密码 */
154
- old_pwd: PasswordCrypto | undefined;
154
+ old_pwd: SecretCrypto | undefined;
155
155
  /** 新密码 */
156
- new_pwd: PasswordCrypto | undefined;
156
+ new_pwd: SecretCrypto | undefined;
157
157
  }
158
158
  /** 用户手机号表单 */
159
159
  export interface UserPhoneForm {
@@ -1,5 +1,5 @@
1
1
  export * from "./utils/oauthProvider";
2
- export * from "./utils/passwordCrypto";
2
+ export * from "./utils/secretCrypto";
3
3
  export * from "./utils/passwordStrength";
4
4
  export * from "./utils/webauthn";
5
5
  export * from "./utils/clipboard";
@@ -0,0 +1,19 @@
1
+ import type { GetSecretPublicKeyResponse } from "../rpc/base/v1/secret_crypto";
2
+ import type { SecretCrypto } from "../rpc/common/v1/types";
3
+ import type { ProFormField } from "../components/ProForm/interface";
4
+ /** 获取敏感字段一次性临时公钥,同一次提交的多个密文字段共用该公钥。 */
5
+ export declare function fetchSecretPublicKey(): Promise<GetSecretPublicKeyResponse>;
6
+ /** encodeSecretFields 在提交前把声明 secret 的字段统一加密为 SecretCrypto,返回模型浅克隆且不改动原表单。 */
7
+ export declare function encodeSecretFields(fields: ProFormField[], model: Record<string, any>): Promise<Record<string, any>>;
8
+ /** 使用已获取的临时公钥加密单个敏感值,供一次取钥加密多个字段的场景复用。 */
9
+ export declare function encryptWithPublicKey(publicKey: GetSecretPublicKeyResponse, value: string): Promise<SecretCrypto>;
10
+ /** 加密单个敏感字段值,自动获取一次性临时公钥。 */
11
+ export declare function encryptSecret(value: string): Promise<SecretCrypto>;
12
+ /** SecretRevealHandler 按资源标识与字段名查看密钥明文的实现。 */
13
+ export type SecretRevealHandler = (resource: string, id: number, field: string) => Promise<string>;
14
+ /** registerSecretRevealHandler 注册密钥明文查看实现,由业务模块在启动时注入。 */
15
+ export declare function registerSecretRevealHandler(handler: SecretRevealHandler): void;
16
+ /** revealSecret 查看注册过的密钥字段明文。 */
17
+ export declare function revealSecret(resource: string, id: number, field: string): Promise<string>;
18
+ /** 加密密码字段:去除首尾空白且不允许为空。 */
19
+ export declare function encryptPassword(value: string): Promise<SecretCrypto>;
@@ -5,8 +5,6 @@ import type {
5
5
  LogoutRequest,
6
6
  LoginRequest,
7
7
  LoginResponse,
8
- PasswordPublicKeyRequest,
9
- PasswordPublicKeyResponse,
10
8
  RefreshTokenRequest,
11
9
  RefreshTokenResponse,
12
10
  VerifyCaptchaRequest,
@@ -17,7 +15,6 @@ import type { Empty } from "../../../rpc/google/protobuf/empty";
17
15
 
18
16
  const CAPTCHA_URL = "/v1/base/captcha";
19
17
  const CAPTCHA_VERIFY_URL = "/v1/base/captcha/verify";
20
- const PASSWORD_PUBLIC_KEY_URL = "/v1/base/password-public-key";
21
18
  const SESSION_URL = "/v1/base/session";
22
19
  const TOKEN_URL = "/v1/base/token";
23
20
 
@@ -41,15 +38,6 @@ export class LoginServiceImpl implements LoginService {
41
38
  headers: { Authorization: "no-auth" }
42
39
  });
43
40
  }
44
- /** 获取密码临时公钥 */
45
- PasswordPublicKey(request: PasswordPublicKeyRequest): Promise<PasswordPublicKeyResponse> {
46
- return service<PasswordPublicKeyRequest, PasswordPublicKeyResponse>({
47
- url: `${PASSWORD_PUBLIC_KEY_URL}`,
48
- method: "get",
49
- params: request,
50
- headers: { Authorization: "no-auth" }
51
- });
52
- }
53
41
  /** 登录 */
54
42
  Login(request: LoginRequest): Promise<LoginResponse> {
55
43
  return service<LoginRequest, LoginResponse>({
@@ -0,0 +1,35 @@
1
+ import service from "../../../utils/request";
2
+ import type {
3
+ GetSecretPublicKeyRequest,
4
+ GetSecretPublicKeyResponse,
5
+ RevealSecretFieldRequest,
6
+ RevealSecretFieldResponse,
7
+ SecretCryptoService
8
+ } from "../../../rpc/base/v1/secret_crypto";
9
+
10
+ const SECRET_PUBLIC_KEY_URL = "/v1/base/secret-public-key";
11
+ const SECRET_FIELD_REVEAL_URL = "/v1/base/secret-field/reveal";
12
+
13
+ /** 敏感字段加密公共服务 */
14
+ export class SecretCryptoServiceImpl implements SecretCryptoService {
15
+ /** 获取敏感字段临时公钥 */
16
+ GetSecretPublicKey(request: GetSecretPublicKeyRequest): Promise<GetSecretPublicKeyResponse> {
17
+ return service<GetSecretPublicKeyRequest, GetSecretPublicKeyResponse>({
18
+ url: `${SECRET_PUBLIC_KEY_URL}`,
19
+ method: "get",
20
+ params: request,
21
+ headers: { Authorization: "no-auth" }
22
+ });
23
+ }
24
+
25
+ /** 查看密钥字段明文 */
26
+ RevealSecretField(request: RevealSecretFieldRequest): Promise<RevealSecretFieldResponse> {
27
+ return service<RevealSecretFieldRequest, RevealSecretFieldResponse>({
28
+ url: `${SECRET_FIELD_REVEAL_URL}`,
29
+ method: "post",
30
+ data: request
31
+ });
32
+ }
33
+ }
34
+
35
+ export const defSecretCryptoService = new SecretCryptoServiceImpl();
@@ -36,9 +36,8 @@ import ProDialog from "../../components/Dialog/ProDialog.vue";
36
36
  import ProForm from "../../components/ProForm/index.vue";
37
37
  import type { ProFormField, ProFormInstance, ProFormLabelPosition } from "../../components/ProForm/interface";
38
38
  import { useLocaleStore } from "../../locales";
39
- import { PASSWORD_CRYPTO_SCENE, encryptPassword } from "../../utils/passwordCrypto";
40
- import type { PasswordCryptoScene } from "../../utils/passwordCrypto";
41
- import type { PasswordCrypto } from "../../rpc/common/v1/types";
39
+ import { encryptPassword } from "../../utils/secretCrypto";
40
+ import type { SecretCrypto } from "../../rpc/common/v1/types";
42
41
 
43
42
  const { t } = useLocaleStore();
44
43
 
@@ -64,8 +63,6 @@ interface PasswordVerifyDialogProps {
64
63
  cancelText?: string;
65
64
  /** 外部业务提交状态。 */
66
65
  confirmLoading?: boolean;
67
- /** 密码加密场景。 */
68
- scene?: PasswordCryptoScene;
69
66
  /** 是否关闭时销毁内容。 */
70
67
  destroyOnClose?: boolean;
71
68
  /** 是否允许点击遮罩关闭。 */
@@ -88,7 +85,6 @@ const props = withDefaults(defineProps<PasswordVerifyDialogProps>(), {
88
85
  confirmText: "",
89
86
  cancelText: "",
90
87
  confirmLoading: false,
91
- scene: PASSWORD_CRYPTO_SCENE.PASSWORD_CRYPTO_SCENE_MFA,
92
88
  destroyOnClose: false,
93
89
  closeOnClickModal: false,
94
90
  closeOnPressEscape: true,
@@ -98,7 +94,7 @@ const props = withDefaults(defineProps<PasswordVerifyDialogProps>(), {
98
94
 
99
95
  const emit = defineEmits<{
100
96
  "update:modelValue": [value: boolean];
101
- confirm: [password: PasswordCrypto];
97
+ confirm: [password: SecretCrypto];
102
98
  cancel: [];
103
99
  close: [];
104
100
  closed: [];
@@ -142,7 +138,7 @@ async function handleConfirm() {
142
138
  if (!(await formRef.value?.validate())) return;
143
139
  encrypting.value = true;
144
140
  try {
145
- const password = await encryptPassword(form.password, props.scene);
141
+ const password = await encryptPassword(form.password);
146
142
  emit("confirm", password);
147
143
  } finally {
148
144
  encrypting.value = false;
@@ -1,5 +1,11 @@
1
1
  <template>
2
- <el-input v-if="field.component === 'input'" v-model.trim="fieldValue" v-bind="fieldProps">
2
+ <SecretInput
3
+ v-if="field.component === 'input' && field.secret"
4
+ v-model="fieldValue"
5
+ v-bind="secretInputProps"
6
+ />
7
+
8
+ <el-input v-else-if="field.component === 'input'" v-model.trim="fieldValue" v-bind="fieldProps">
3
9
  <template v-if="field.suffixSlotName" #append>
4
10
  <slot :name="field.suffixSlotName" :field="field" :model="model" />
5
11
  </template>
@@ -45,6 +51,8 @@
45
51
  </el-option>
46
52
  </el-select>
47
53
 
54
+ <el-cascader v-else-if="field.component === 'cascader'" v-model="fieldValue" :options="fieldOptions" v-bind="fieldProps" />
55
+
48
56
  <TenantSelect v-else-if="field.component === 'tenant-select'" v-model="fieldValue" v-bind="fieldProps" />
49
57
 
50
58
  <el-radio-group v-else-if="field.component === 'radio-group'" v-model="fieldValue" v-bind="fieldProps">
@@ -102,6 +110,7 @@ import type { UploadUserFile } from "element-plus";
102
110
  import type { ProFormField, ProFormOption } from "../../../components/ProForm/interface";
103
111
  import Dict from "../../../components/Dict/index.vue";
104
112
  import TenantSelect from "../../../components/TenantSelect/index.vue";
113
+ import SecretInput from "../../../components/ProForm/components/SecretInput.vue";
105
114
 
106
115
  // 非基础表单控件按需加载,避免 ProForm 基础包携带上传、富文本、Cron 等重组件。
107
116
  const CronExpression = defineAsyncComponent(() => import("../../../components/CronExpression/index.vue"));
@@ -128,6 +137,20 @@ const fieldProps = computed(() => {
128
137
  return typeof props.field.props === "function" ? props.field.props(props.model) : props.field.props;
129
138
  });
130
139
 
140
+ /** 解析 secret 输入参数:透传输入参数并注入查看所需的资源信息。 */
141
+ const secretInputProps = computed(() => {
142
+ const { showPassword: _ignored, ...rest } = (fieldProps.value ?? {}) as Record<string, any>;
143
+ const config = typeof props.field.secret === "object" ? props.field.secret : null;
144
+ return {
145
+ ...rest,
146
+ secret: props.field.secret,
147
+ resource: config?.resource ?? "",
148
+ fieldName: config?.field ?? "",
149
+ recordId: config ? Number(props.model[config.idProp ?? "id"] ?? 0) : 0,
150
+ configured: config ? Boolean(props.model[config.configuredProp ?? `${config.field}_configured`]) : false
151
+ };
152
+ });
153
+
131
154
  /** 解析字段选项参数,支持静态数组和函数。 */
132
155
  const fieldOptions = computed<ProFormOption[]>(() => {
133
156
  if (!props.field.options) return [];