@pnt-team/pnt-component-frontend 0.0.96 → 0.0.99
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/lib/cjs/api/cos.d.ts +2 -2
- package/lib/cjs/api/index.d.ts +4 -4
- package/lib/cjs/api/index.js +2 -2
- package/lib/cjs/components/PntCosUploader/index.d.ts +2 -3
- package/lib/cjs/components/PntSecureBox/index.d.ts +9 -2
- package/lib/cjs/components/PntSecureBox/index.js +24 -25
- package/lib/cjs/config.d.ts +24 -2
- package/lib/cjs/hooks/useHighSecurity.d.ts +14 -3
- package/lib/cjs/hooks/useHighSecurity.js +34 -12
- package/lib/cjs/index.d.ts +2 -2
- package/lib/esm/api/cos.d.ts +2 -2
- package/lib/esm/api/index.d.ts +4 -4
- package/lib/esm/api/index.js +2 -1
- package/lib/esm/components/PntCosUploader/index.d.ts +2 -3
- package/lib/esm/components/PntSecureBox/index.d.ts +9 -2
- package/lib/esm/components/PntSecureBox/index.js +25 -15
- package/lib/esm/config.d.ts +24 -2
- package/lib/esm/config.js +11 -0
- package/lib/esm/hooks/useHighSecurity.d.ts +14 -3
- package/lib/esm/hooks/useHighSecurity.js +44 -12
- package/lib/esm/index.d.ts +2 -2
- package/lib/umd/pnt-component-frontend.min.js +1 -1
- package/package.json +1 -1
package/lib/cjs/api/cos.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PntHttpLike } from "../config";
|
|
2
2
|
/**
|
|
3
3
|
* 归一化后的 COS 临时凭证
|
|
4
4
|
* @description 各后端接口字段命名不统一(snake/camel),组件库内部统一为 camelCase
|
|
@@ -99,5 +99,5 @@ export declare const normalizeSnakeCredential: (raw: SnakeCosCredential) => Norm
|
|
|
99
99
|
* @param params 凭证获取参数
|
|
100
100
|
* @param customNormalize 可选的原始响应自定义归一化
|
|
101
101
|
*/
|
|
102
|
-
export declare const fetchCosCredential: (http:
|
|
102
|
+
export declare const fetchCosCredential: (http: PntHttpLike, params: GetCosCredentialParams, customNormalize?: NormalizeCredential) => Promise<NormalizedCosCredential>;
|
|
103
103
|
export {};
|
package/lib/cjs/api/index.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { commonEesType } from "../config";
|
|
2
|
-
import type { AxiosInstance } from 'axios';
|
|
1
|
+
import type { commonEesType, PntHttpLike } from "../config";
|
|
3
2
|
import { BusinessGameInfoHighSecurityDecryptBody, BusinessGameInfoHighSecurityDecryptResponse, BusinessSelectListBody, BusinessSelectListResponse } from './types/index';
|
|
4
3
|
/**
|
|
5
4
|
* 业务下拉选择列表
|
|
6
5
|
* @param http 由 PntProvider 注入的 axios 实例
|
|
7
6
|
* @param data 请求参数
|
|
8
7
|
*/
|
|
9
|
-
export declare const businessSelectList: (axios:
|
|
8
|
+
export declare const businessSelectList: (axios: PntHttpLike, data: BusinessSelectListBody) => Promise<commonEesType<BusinessSelectListResponse>>;
|
|
10
9
|
/**
|
|
11
10
|
* 高敏信息解锁
|
|
12
11
|
* @param http 由 PntProvider 注入的 axios 实例
|
|
13
12
|
* @param data 请求参数
|
|
13
|
+
* @param url 自定义接口 URL(可选,覆盖默认值)
|
|
14
14
|
*/
|
|
15
|
-
export declare const businessGameInfoHighSecurityDecrypt: (axios:
|
|
15
|
+
export declare const businessGameInfoHighSecurityDecrypt: (axios: PntHttpLike, data: BusinessGameInfoHighSecurityDecryptBody, url?: string) => Promise<commonEesType<BusinessGameInfoHighSecurityDecryptResponse>>;
|
package/lib/cjs/api/index.js
CHANGED
|
@@ -24,8 +24,8 @@ __export(api_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(api_exports);
|
|
26
26
|
var businessSelectList = (axios, data) => axios.post("/business/select/list?audience=/player-network", data);
|
|
27
|
-
var businessGameInfoHighSecurityDecrypt = (axios, data) => axios.post(
|
|
28
|
-
"/v3/business/game_info/high-security-decrypt?audience=/laas-pnt",
|
|
27
|
+
var businessGameInfoHighSecurityDecrypt = (axios, data, url) => axios.post(
|
|
28
|
+
url || "/v3/business/game_info/high-security-decrypt?audience=/laas-pnt",
|
|
29
29
|
data
|
|
30
30
|
);
|
|
31
31
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type CosScene, type GetCosCredentialParams, type NormalizeCredential, type NormalizedCosCredential } from "../../api/cos";
|
|
2
|
-
import { usePntConfig } from "../../config";
|
|
3
|
-
import type { AxiosInstance } from 'axios';
|
|
2
|
+
import { usePntConfig, type PntHttpLike } from "../../config";
|
|
4
3
|
/**
|
|
5
4
|
* 文件名生成策略
|
|
6
5
|
* @description 内置三种策略;如需自定义可传函数
|
|
@@ -117,7 +116,7 @@ export { normalizeSnakeCredential } from "../../api/cos";
|
|
|
117
116
|
* const { fileUrl } = await uploader.upload(file);
|
|
118
117
|
* ```
|
|
119
118
|
*/
|
|
120
|
-
export declare const createPntCosUploader: (http:
|
|
119
|
+
export declare const createPntCosUploader: (http: PntHttpLike, options: PntCosUploadOptions | (() => PntCosUploadOptions)) => PntCosUploader;
|
|
121
120
|
/**
|
|
122
121
|
* COS 直传 Service Hook
|
|
123
122
|
* @description 内置凭证获取 + COS SDK 初始化 + 文件名策略 + URL 拼接,
|
|
@@ -13,9 +13,9 @@ interface PntSecureBoxProps {
|
|
|
13
13
|
dataValue: string;
|
|
14
14
|
/**
|
|
15
15
|
* 环境标识
|
|
16
|
-
* @description 用于区分不同环境(如:dev, test, production
|
|
16
|
+
* @description 用于区分不同环境(如:dev, test, production);可缺省,默认 0
|
|
17
17
|
*/
|
|
18
|
-
env
|
|
18
|
+
env?: string | number;
|
|
19
19
|
/**
|
|
20
20
|
* 游戏 ID
|
|
21
21
|
* @description 标识具体的游戏项目
|
|
@@ -38,6 +38,13 @@ interface PntSecureBoxProps {
|
|
|
38
38
|
* @description 用于记录操作日志和权限验证
|
|
39
39
|
*/
|
|
40
40
|
pageId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* 明文是否也掩码显示
|
|
43
|
+
* @description
|
|
44
|
+
* - false(默认):非加密值直接展示原值
|
|
45
|
+
* - true:非加密值也展示 ******,点击后本地揭示(不调接口,防窥屏)
|
|
46
|
+
*/
|
|
47
|
+
maskPlain?: boolean;
|
|
41
48
|
}
|
|
42
49
|
/**
|
|
43
50
|
* 高敏信息展示统一组件
|
|
@@ -24,40 +24,39 @@ __export(PntSecureBox_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(PntSecureBox_exports);
|
|
25
25
|
var import_useHighSecurity = require("../../hooks/useHighSecurity");
|
|
26
26
|
var import_utils = require("../../utils");
|
|
27
|
+
var import_react = require("react");
|
|
27
28
|
var import_index = require("./index.scss");
|
|
28
29
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
29
30
|
var PntSecureBox = (prop) => {
|
|
30
|
-
const { dataKey, dataValue, env, gameId, renderDom, viewText, pageId } = prop;
|
|
31
|
+
const { dataKey, dataValue, env, gameId, renderDom, viewText, pageId, maskPlain } = prop;
|
|
31
32
|
const { securityData, isUnlocked, requestSecurityData } = (0, import_useHighSecurity.useHighSecurity)({
|
|
32
33
|
gameId,
|
|
33
34
|
env
|
|
34
35
|
});
|
|
36
|
+
const [plainViewed, setPlainViewed] = (0, import_react.useState)(false);
|
|
35
37
|
const isSecurity = (0, import_utils.isSecurityData)(dataValue);
|
|
36
|
-
const unlocked = isSecurity
|
|
38
|
+
const unlocked = isSecurity ? isUnlocked(dataKey) : maskPlain ? plainViewed : true;
|
|
39
|
+
const displayValue = unlocked ? isSecurity ? securityData[dataKey] || "******" : dataValue : "******";
|
|
40
|
+
const handleView = () => {
|
|
41
|
+
if (isSecurity) {
|
|
42
|
+
requestSecurityData({
|
|
43
|
+
env,
|
|
44
|
+
gameId,
|
|
45
|
+
pageId,
|
|
46
|
+
param: [
|
|
47
|
+
{
|
|
48
|
+
key: dataKey,
|
|
49
|
+
value: dataValue
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
});
|
|
53
|
+
} else if (maskPlain) {
|
|
54
|
+
setPlainViewed(true);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
37
57
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pnt-secure-box", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
38
|
-
renderDom(
|
|
39
|
-
|
|
40
|
-
),
|
|
41
|
-
isSecurity && !isUnlocked(dataKey) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
42
|
-
"span",
|
|
43
|
-
{
|
|
44
|
-
className: "view-icon",
|
|
45
|
-
onClick: () => {
|
|
46
|
-
requestSecurityData({
|
|
47
|
-
env,
|
|
48
|
-
gameId,
|
|
49
|
-
pageId,
|
|
50
|
-
param: [
|
|
51
|
-
{
|
|
52
|
-
key: dataKey,
|
|
53
|
-
value: dataValue
|
|
54
|
-
}
|
|
55
|
-
]
|
|
56
|
-
});
|
|
57
|
-
},
|
|
58
|
-
children: viewText || "View"
|
|
59
|
-
}
|
|
60
|
-
)
|
|
58
|
+
renderDom(displayValue),
|
|
59
|
+
!unlocked && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "view-icon", onClick: handleView, children: viewText || "View" })
|
|
61
60
|
] }) });
|
|
62
61
|
};
|
|
63
62
|
var PntSecureBox_default = PntSecureBox;
|
package/lib/cjs/config.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type { AxiosInstance } from 'axios';
|
|
3
2
|
/**
|
|
4
3
|
* 统一响应结构(与后端 commonEesType 对齐)
|
|
5
4
|
*/
|
|
@@ -9,12 +8,35 @@ export interface commonEesType<T> {
|
|
|
9
8
|
data: T;
|
|
10
9
|
ret?: number;
|
|
11
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* 库所需的最小 HTTP 能力(仅 post)。
|
|
13
|
+
* 用结构化类型而非直接依赖 AxiosInstance,
|
|
14
|
+
* 避免与消费方 axios 版本的类型定义强耦合(如 1.13 vs 1.20 的 query 方法差异)。
|
|
15
|
+
* 任何具备 axios 兼容 post 签名的实例均可注入。
|
|
16
|
+
*/
|
|
17
|
+
export interface PntHttpLike {
|
|
18
|
+
get<T = unknown, R = unknown>(url: string, config?: any): Promise<R>;
|
|
19
|
+
post<T = unknown, R = unknown, D = unknown>(url: string, data?: D, config?: any): Promise<R>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 高敏信息解锁接口配置(可选,全局覆盖)
|
|
23
|
+
*/
|
|
24
|
+
export interface PntHighSecurityConfig {
|
|
25
|
+
/** 解密接口 URL,覆盖默认 /v3/business/game_info/high-security-decrypt?audience=/laas-pnt */
|
|
26
|
+
decryptUrl?: string;
|
|
27
|
+
/** 成功码字段:'code'(默认)或 'ret'(account-business 现状) */
|
|
28
|
+
successCodeField?: 'code' | 'ret';
|
|
29
|
+
/** audience 覆盖(默认 /laas-pnt) */
|
|
30
|
+
audience?: string;
|
|
31
|
+
}
|
|
12
32
|
/**
|
|
13
33
|
* 组件库运行时配置:由消费方通过 PntProvider 注入
|
|
14
34
|
*/
|
|
15
35
|
export interface PntConfig {
|
|
16
36
|
/** 消费方已配置好的 axios 实例(含拦截器、鉴权、baseURL 等) */
|
|
17
|
-
http:
|
|
37
|
+
http: PntHttpLike;
|
|
38
|
+
/** 高敏信息解锁接口全局配置(可选) */
|
|
39
|
+
highSecurity?: PntHighSecurityConfig;
|
|
18
40
|
}
|
|
19
41
|
/**
|
|
20
42
|
* 配置 Provider:消费方在应用根入口包裹一次即可
|
|
@@ -1,26 +1,37 @@
|
|
|
1
|
+
import type { PntHighSecurityConfig } from "../config";
|
|
1
2
|
/** 单个解锁项 */
|
|
2
3
|
export interface HighSecurityParamItem {
|
|
3
4
|
/** 字段标识(与后端约定) */
|
|
4
5
|
key: string;
|
|
5
6
|
/** 参数密文(_high_security_: 前缀) */
|
|
6
7
|
value: string;
|
|
8
|
+
/**
|
|
9
|
+
* 缓存别名(可选)
|
|
10
|
+
* @description 当后端 key 相同但密文不同时(如两组 SDK 密钥),
|
|
11
|
+
* 用 cacheKey 区分缓存,请求体仍用 key。默认 cacheKey=key
|
|
12
|
+
*/
|
|
13
|
+
cacheKey?: string;
|
|
7
14
|
}
|
|
15
|
+
/** 单次请求的接口配置覆盖(优先级 > PntProvider 全局配置) */
|
|
16
|
+
export type HighSecurityApiConfig = PntHighSecurityConfig;
|
|
8
17
|
/** 高敏数据解锁请求参数(组件层友好命名,库内部转换为后端 snake_case) */
|
|
9
18
|
export interface HighSecurityRequestParams {
|
|
10
19
|
/** 业务 ID */
|
|
11
20
|
gameId: string | number;
|
|
12
|
-
/**
|
|
13
|
-
env
|
|
21
|
+
/** 环境标识(可缺省,默认 0;以各业务现有约定为准) */
|
|
22
|
+
env?: string | number;
|
|
14
23
|
/** 页面 ID(不传则默认取 location.pathname),用于操作日志和权限校验 */
|
|
15
24
|
pageId?: string;
|
|
16
25
|
/** 需要解锁的参数列表,支持批量 */
|
|
17
26
|
param: HighSecurityParamItem[];
|
|
27
|
+
/** 本次请求的接口配置覆盖(可选) */
|
|
28
|
+
apiConfig?: HighSecurityApiConfig;
|
|
18
29
|
}
|
|
19
30
|
/** hook 初始化 scope:传入后 securityData/isUnlocked 自动按该业务+环境过滤 */
|
|
20
31
|
export interface UseHighSecurityOptions {
|
|
21
32
|
/** 当前业务 ID */
|
|
22
33
|
gameId?: string | number;
|
|
23
|
-
/**
|
|
34
|
+
/** 当前环境(可缺省,默认 0) */
|
|
24
35
|
env?: string | number;
|
|
25
36
|
}
|
|
26
37
|
/** 清缓存过滤条件 */
|
|
@@ -77,7 +77,7 @@ var clearEntries = (filter) => {
|
|
|
77
77
|
};
|
|
78
78
|
var getDefaultPageId = () => typeof window !== "undefined" && window.location ? window.location.pathname : "";
|
|
79
79
|
var useHighSecurity = (options) => {
|
|
80
|
-
const { http } = (0, import_config.usePntConfig)();
|
|
80
|
+
const { http, highSecurity: globalHighSecurity } = (0, import_config.usePntConfig)();
|
|
81
81
|
const snapshot = (0, import_react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
82
82
|
const scopeGameId = (options == null ? void 0 : options.gameId) === void 0 ? void 0 : String(options.gameId);
|
|
83
83
|
const scopeEnv = (options == null ? void 0 : options.env) === void 0 ? void 0 : String(options.env);
|
|
@@ -107,19 +107,26 @@ var useHighSecurity = (options) => {
|
|
|
107
107
|
gameId,
|
|
108
108
|
env,
|
|
109
109
|
pageId,
|
|
110
|
-
param
|
|
110
|
+
param,
|
|
111
|
+
apiConfig
|
|
111
112
|
}) => {
|
|
112
113
|
const gid = String(gameId);
|
|
113
|
-
const eid = String(env);
|
|
114
|
+
const eid = String(env != null ? env : 0);
|
|
115
|
+
const merged = {
|
|
116
|
+
...globalHighSecurity,
|
|
117
|
+
...apiConfig
|
|
118
|
+
};
|
|
119
|
+
const successCodeField = merged.successCodeField || "code";
|
|
114
120
|
const result = new Array(
|
|
115
121
|
param.length
|
|
116
122
|
);
|
|
117
123
|
const missing = [];
|
|
118
124
|
const missingIndexes = [];
|
|
119
125
|
param.forEach((item, index) => {
|
|
120
|
-
const
|
|
126
|
+
const storeKey = item.cacheKey || item.key;
|
|
127
|
+
const cached = snapshot.get(buildCacheKey(gid, eid, storeKey));
|
|
121
128
|
if (cached !== void 0) {
|
|
122
|
-
result[index] = { key: item.key, value: cached };
|
|
129
|
+
result[index] = { key: item.key, value: cached, cacheKey: storeKey };
|
|
123
130
|
} else {
|
|
124
131
|
missing.push({ key: item.key, value: item.value });
|
|
125
132
|
missingIndexes.push(index);
|
|
@@ -132,19 +139,27 @@ var useHighSecurity = (options) => {
|
|
|
132
139
|
}
|
|
133
140
|
const body = {
|
|
134
141
|
game_id: Number(gameId),
|
|
135
|
-
env: Number(env),
|
|
142
|
+
env: Number(env != null ? env : 0),
|
|
136
143
|
page_id: pageId || getDefaultPageId(),
|
|
137
144
|
param: missing
|
|
138
145
|
};
|
|
146
|
+
let url = merged.decryptUrl;
|
|
147
|
+
if (!url) {
|
|
148
|
+
const audience = merged.audience || "/laas-pnt";
|
|
149
|
+
url = `/v3/business/game_info/high-security-decrypt?audience=${audience}`;
|
|
150
|
+
}
|
|
139
151
|
const requestKey = `${gid}:${eid}:${missing.map((item) => `${item.key}${item.value}`).join("")}`;
|
|
140
152
|
const existing = inflightRequests.get(requestKey);
|
|
141
153
|
if (existing)
|
|
142
154
|
return existing;
|
|
143
155
|
const promise = (async () => {
|
|
144
|
-
var _a;
|
|
156
|
+
var _a, _b;
|
|
145
157
|
try {
|
|
146
|
-
const res = await (0, import_api.businessGameInfoHighSecurityDecrypt)(http, body);
|
|
147
|
-
|
|
158
|
+
const res = await (0, import_api.businessGameInfoHighSecurityDecrypt)(http, body, url);
|
|
159
|
+
const successCode = Number(
|
|
160
|
+
(_a = res[successCodeField]) != null ? _a : res.code
|
|
161
|
+
);
|
|
162
|
+
if (successCode === 0 && Array.isArray(res.data)) {
|
|
148
163
|
const decrypted = res.data.map((raw) => {
|
|
149
164
|
var _a2;
|
|
150
165
|
if (raw && typeof raw === "object" && "key" in raw) {
|
|
@@ -155,7 +170,14 @@ var useHighSecurity = (options) => {
|
|
|
155
170
|
}
|
|
156
171
|
return null;
|
|
157
172
|
}).filter((item) => item !== null);
|
|
158
|
-
|
|
173
|
+
const toStore = decrypted.map((d) => {
|
|
174
|
+
const matchIdx = missingIndexes.find(
|
|
175
|
+
(i) => param[i].key === d.key
|
|
176
|
+
);
|
|
177
|
+
const storeKey = matchIdx !== void 0 ? param[matchIdx].cacheKey || d.key : d.key;
|
|
178
|
+
return { key: d.key, value: d.value, cacheKey: storeKey };
|
|
179
|
+
});
|
|
180
|
+
setEntries(gid, eid, toStore);
|
|
159
181
|
decrypted.forEach((item) => {
|
|
160
182
|
const index = missingIndexes.find(
|
|
161
183
|
(i) => param[i].key === item.key
|
|
@@ -166,7 +188,7 @@ var useHighSecurity = (options) => {
|
|
|
166
188
|
} else {
|
|
167
189
|
console.warn(
|
|
168
190
|
"[pnt-component-frontend] high-security-decrypt 解锁失败",
|
|
169
|
-
(
|
|
191
|
+
(_b = res == null ? void 0 : res.msg) != null ? _b : res[successCodeField]
|
|
170
192
|
);
|
|
171
193
|
}
|
|
172
194
|
} catch (error) {
|
|
@@ -184,7 +206,7 @@ var useHighSecurity = (options) => {
|
|
|
184
206
|
inflightRequests.set(requestKey, promise);
|
|
185
207
|
return promise;
|
|
186
208
|
},
|
|
187
|
-
[http, snapshot]
|
|
209
|
+
[http, snapshot, globalHighSecurity]
|
|
188
210
|
);
|
|
189
211
|
const clearSecurityData = (0, import_react.useCallback)((filter) => {
|
|
190
212
|
clearEntries(filter);
|
package/lib/cjs/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { PntProvider, usePntConfig, type PntConfig, type commonEesType, } from './config';
|
|
1
|
+
export { PntProvider, usePntConfig, type PntConfig, type PntHttpLike, type PntHighSecurityConfig, type commonEesType, } from './config';
|
|
2
2
|
export { default as PntImage } from './components/PntImage';
|
|
3
3
|
export { default as PntBusinessSelect } from './components/PntBusinessSelect';
|
|
4
4
|
export { default as PntSecureBox } from './components/PntSecureBox';
|
|
@@ -6,6 +6,6 @@ export { default as PntUpload } from './components/PntUpload';
|
|
|
6
6
|
export type { PntUploadErrorPhase, PntUploadProps, PntUploadTexts, } from './components/PntUpload';
|
|
7
7
|
export { createPntCosUploader, normalizeSnakeCredential, default as usePntCosUploader, type CosScene, type FileNameStrategy, type GetCosCredentialParams, type NormalizeCredential, type NormalizedCosCredential, type PntCosRequestOverrides, type PntCosUploadOptions, type PntCosUploadResult, type PntCosUploader as PntCosUploaderInstance, } from './components/PntCosUploader';
|
|
8
8
|
export { useHighSecurity } from './hooks/useHighSecurity';
|
|
9
|
-
export type { ClearSecurityDataFilter, HighSecurityParamItem, HighSecurityRequestParams, UseHighSecurityOptions, UseHighSecurityResult, } from './hooks/useHighSecurity';
|
|
9
|
+
export type { ClearSecurityDataFilter, HighSecurityApiConfig, HighSecurityParamItem, HighSecurityRequestParams, UseHighSecurityOptions, UseHighSecurityResult, } from './hooks/useHighSecurity';
|
|
10
10
|
export { isSecurityData } from './utils';
|
|
11
11
|
export { default as PntGeneralLayout } from './components/PntGeneralLayout';
|
package/lib/esm/api/cos.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PntHttpLike } from "../config";
|
|
2
2
|
/**
|
|
3
3
|
* 归一化后的 COS 临时凭证
|
|
4
4
|
* @description 各后端接口字段命名不统一(snake/camel),组件库内部统一为 camelCase
|
|
@@ -99,5 +99,5 @@ export declare const normalizeSnakeCredential: (raw: SnakeCosCredential) => Norm
|
|
|
99
99
|
* @param params 凭证获取参数
|
|
100
100
|
* @param customNormalize 可选的原始响应自定义归一化
|
|
101
101
|
*/
|
|
102
|
-
export declare const fetchCosCredential: (http:
|
|
102
|
+
export declare const fetchCosCredential: (http: PntHttpLike, params: GetCosCredentialParams, customNormalize?: NormalizeCredential) => Promise<NormalizedCosCredential>;
|
|
103
103
|
export {};
|
package/lib/esm/api/index.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { commonEesType } from "../config";
|
|
2
|
-
import type { AxiosInstance } from 'axios';
|
|
1
|
+
import type { commonEesType, PntHttpLike } from "../config";
|
|
3
2
|
import { BusinessGameInfoHighSecurityDecryptBody, BusinessGameInfoHighSecurityDecryptResponse, BusinessSelectListBody, BusinessSelectListResponse } from './types/index';
|
|
4
3
|
/**
|
|
5
4
|
* 业务下拉选择列表
|
|
6
5
|
* @param http 由 PntProvider 注入的 axios 实例
|
|
7
6
|
* @param data 请求参数
|
|
8
7
|
*/
|
|
9
|
-
export declare const businessSelectList: (axios:
|
|
8
|
+
export declare const businessSelectList: (axios: PntHttpLike, data: BusinessSelectListBody) => Promise<commonEesType<BusinessSelectListResponse>>;
|
|
10
9
|
/**
|
|
11
10
|
* 高敏信息解锁
|
|
12
11
|
* @param http 由 PntProvider 注入的 axios 实例
|
|
13
12
|
* @param data 请求参数
|
|
13
|
+
* @param url 自定义接口 URL(可选,覆盖默认值)
|
|
14
14
|
*/
|
|
15
|
-
export declare const businessGameInfoHighSecurityDecrypt: (axios:
|
|
15
|
+
export declare const businessGameInfoHighSecurityDecrypt: (axios: PntHttpLike, data: BusinessGameInfoHighSecurityDecryptBody, url?: string) => Promise<commonEesType<BusinessGameInfoHighSecurityDecryptResponse>>;
|
package/lib/esm/api/index.js
CHANGED
|
@@ -9,5 +9,6 @@ export const businessSelectList = (axios, data) => axios.post('/business/select/
|
|
|
9
9
|
* 高敏信息解锁
|
|
10
10
|
* @param http 由 PntProvider 注入的 axios 实例
|
|
11
11
|
* @param data 请求参数
|
|
12
|
+
* @param url 自定义接口 URL(可选,覆盖默认值)
|
|
12
13
|
*/
|
|
13
|
-
export const businessGameInfoHighSecurityDecrypt = (axios, data) => axios.post('/v3/business/game_info/high-security-decrypt?audience=/laas-pnt', data);
|
|
14
|
+
export const businessGameInfoHighSecurityDecrypt = (axios, data, url) => axios.post(url || '/v3/business/game_info/high-security-decrypt?audience=/laas-pnt', data);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type CosScene, type GetCosCredentialParams, type NormalizeCredential, type NormalizedCosCredential } from "../../api/cos";
|
|
2
|
-
import { usePntConfig } from "../../config";
|
|
3
|
-
import type { AxiosInstance } from 'axios';
|
|
2
|
+
import { usePntConfig, type PntHttpLike } from "../../config";
|
|
4
3
|
/**
|
|
5
4
|
* 文件名生成策略
|
|
6
5
|
* @description 内置三种策略;如需自定义可传函数
|
|
@@ -117,7 +116,7 @@ export { normalizeSnakeCredential } from "../../api/cos";
|
|
|
117
116
|
* const { fileUrl } = await uploader.upload(file);
|
|
118
117
|
* ```
|
|
119
118
|
*/
|
|
120
|
-
export declare const createPntCosUploader: (http:
|
|
119
|
+
export declare const createPntCosUploader: (http: PntHttpLike, options: PntCosUploadOptions | (() => PntCosUploadOptions)) => PntCosUploader;
|
|
121
120
|
/**
|
|
122
121
|
* COS 直传 Service Hook
|
|
123
122
|
* @description 内置凭证获取 + COS SDK 初始化 + 文件名策略 + URL 拼接,
|
|
@@ -13,9 +13,9 @@ interface PntSecureBoxProps {
|
|
|
13
13
|
dataValue: string;
|
|
14
14
|
/**
|
|
15
15
|
* 环境标识
|
|
16
|
-
* @description 用于区分不同环境(如:dev, test, production
|
|
16
|
+
* @description 用于区分不同环境(如:dev, test, production);可缺省,默认 0
|
|
17
17
|
*/
|
|
18
|
-
env
|
|
18
|
+
env?: string | number;
|
|
19
19
|
/**
|
|
20
20
|
* 游戏 ID
|
|
21
21
|
* @description 标识具体的游戏项目
|
|
@@ -38,6 +38,13 @@ interface PntSecureBoxProps {
|
|
|
38
38
|
* @description 用于记录操作日志和权限验证
|
|
39
39
|
*/
|
|
40
40
|
pageId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* 明文是否也掩码显示
|
|
43
|
+
* @description
|
|
44
|
+
* - false(默认):非加密值直接展示原值
|
|
45
|
+
* - true:非加密值也展示 ******,点击后本地揭示(不调接口,防窥屏)
|
|
46
|
+
*/
|
|
47
|
+
maskPlain?: boolean;
|
|
41
48
|
}
|
|
42
49
|
/**
|
|
43
50
|
* 高敏信息展示统一组件
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useHighSecurity } from "../../hooks/useHighSecurity";
|
|
2
2
|
import { isSecurityData } from "../../utils";
|
|
3
|
-
import React from 'react';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
4
|
import "./index.scss";
|
|
5
5
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
6
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
@@ -43,7 +43,8 @@ const PntSecureBox = prop => {
|
|
|
43
43
|
gameId,
|
|
44
44
|
renderDom,
|
|
45
45
|
viewText,
|
|
46
|
-
pageId
|
|
46
|
+
pageId,
|
|
47
|
+
maskPlain
|
|
47
48
|
} = prop;
|
|
48
49
|
|
|
49
50
|
// 通过 PntProvider 注入的 http 实例请求高敏数据,缓存按 gameId+env 隔离
|
|
@@ -55,24 +56,33 @@ const PntSecureBox = prop => {
|
|
|
55
56
|
gameId,
|
|
56
57
|
env
|
|
57
58
|
});
|
|
59
|
+
|
|
60
|
+
// 明文揭示状态(maskPlain 模式下使用,本地 state,不调接口)
|
|
61
|
+
const [plainViewed, setPlainViewed] = useState(false);
|
|
58
62
|
const isSecurity = isSecurityData(dataValue);
|
|
59
|
-
const unlocked = isSecurity
|
|
63
|
+
const unlocked = isSecurity ? isUnlocked(dataKey) : maskPlain ? plainViewed : true;
|
|
64
|
+
const displayValue = unlocked ? isSecurity ? securityData[dataKey] || '******' : dataValue : '******';
|
|
65
|
+
const handleView = () => {
|
|
66
|
+
if (isSecurity) {
|
|
67
|
+
requestSecurityData({
|
|
68
|
+
env,
|
|
69
|
+
gameId,
|
|
70
|
+
pageId,
|
|
71
|
+
param: [{
|
|
72
|
+
key: dataKey,
|
|
73
|
+
value: dataValue
|
|
74
|
+
}]
|
|
75
|
+
});
|
|
76
|
+
} else if (maskPlain) {
|
|
77
|
+
setPlainViewed(true);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
60
80
|
return /*#__PURE__*/_jsx("div", {
|
|
61
81
|
className: "pnt-secure-box",
|
|
62
82
|
children: /*#__PURE__*/_jsxs(_Fragment, {
|
|
63
|
-
children: [renderDom(
|
|
83
|
+
children: [renderDom(displayValue), !unlocked && /*#__PURE__*/_jsx("span", {
|
|
64
84
|
className: "view-icon",
|
|
65
|
-
onClick:
|
|
66
|
-
requestSecurityData({
|
|
67
|
-
env,
|
|
68
|
-
gameId,
|
|
69
|
-
pageId,
|
|
70
|
-
param: [{
|
|
71
|
-
key: dataKey,
|
|
72
|
-
value: dataValue
|
|
73
|
-
}]
|
|
74
|
-
});
|
|
75
|
-
},
|
|
85
|
+
onClick: handleView,
|
|
76
86
|
children: viewText || 'View'
|
|
77
87
|
})]
|
|
78
88
|
})
|
package/lib/esm/config.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type { AxiosInstance } from 'axios';
|
|
3
2
|
/**
|
|
4
3
|
* 统一响应结构(与后端 commonEesType 对齐)
|
|
5
4
|
*/
|
|
@@ -9,12 +8,35 @@ export interface commonEesType<T> {
|
|
|
9
8
|
data: T;
|
|
10
9
|
ret?: number;
|
|
11
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* 库所需的最小 HTTP 能力(仅 post)。
|
|
13
|
+
* 用结构化类型而非直接依赖 AxiosInstance,
|
|
14
|
+
* 避免与消费方 axios 版本的类型定义强耦合(如 1.13 vs 1.20 的 query 方法差异)。
|
|
15
|
+
* 任何具备 axios 兼容 post 签名的实例均可注入。
|
|
16
|
+
*/
|
|
17
|
+
export interface PntHttpLike {
|
|
18
|
+
get<T = unknown, R = unknown>(url: string, config?: any): Promise<R>;
|
|
19
|
+
post<T = unknown, R = unknown, D = unknown>(url: string, data?: D, config?: any): Promise<R>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 高敏信息解锁接口配置(可选,全局覆盖)
|
|
23
|
+
*/
|
|
24
|
+
export interface PntHighSecurityConfig {
|
|
25
|
+
/** 解密接口 URL,覆盖默认 /v3/business/game_info/high-security-decrypt?audience=/laas-pnt */
|
|
26
|
+
decryptUrl?: string;
|
|
27
|
+
/** 成功码字段:'code'(默认)或 'ret'(account-business 现状) */
|
|
28
|
+
successCodeField?: 'code' | 'ret';
|
|
29
|
+
/** audience 覆盖(默认 /laas-pnt) */
|
|
30
|
+
audience?: string;
|
|
31
|
+
}
|
|
12
32
|
/**
|
|
13
33
|
* 组件库运行时配置:由消费方通过 PntProvider 注入
|
|
14
34
|
*/
|
|
15
35
|
export interface PntConfig {
|
|
16
36
|
/** 消费方已配置好的 axios 实例(含拦截器、鉴权、baseURL 等) */
|
|
17
|
-
http:
|
|
37
|
+
http: PntHttpLike;
|
|
38
|
+
/** 高敏信息解锁接口全局配置(可选) */
|
|
39
|
+
highSecurity?: PntHighSecurityConfig;
|
|
18
40
|
}
|
|
19
41
|
/**
|
|
20
42
|
* 配置 Provider:消费方在应用根入口包裹一次即可
|
package/lib/esm/config.js
CHANGED
|
@@ -4,6 +4,17 @@ import { createContext, useContext } from 'react';
|
|
|
4
4
|
* 统一响应结构(与后端 commonEesType 对齐)
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* 库所需的最小 HTTP 能力(仅 post)。
|
|
9
|
+
* 用结构化类型而非直接依赖 AxiosInstance,
|
|
10
|
+
* 避免与消费方 axios 版本的类型定义强耦合(如 1.13 vs 1.20 的 query 方法差异)。
|
|
11
|
+
* 任何具备 axios 兼容 post 签名的实例均可注入。
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 高敏信息解锁接口配置(可选,全局覆盖)
|
|
16
|
+
*/
|
|
17
|
+
|
|
7
18
|
/**
|
|
8
19
|
* 组件库运行时配置:由消费方通过 PntProvider 注入
|
|
9
20
|
*/
|
|
@@ -1,26 +1,37 @@
|
|
|
1
|
+
import type { PntHighSecurityConfig } from "../config";
|
|
1
2
|
/** 单个解锁项 */
|
|
2
3
|
export interface HighSecurityParamItem {
|
|
3
4
|
/** 字段标识(与后端约定) */
|
|
4
5
|
key: string;
|
|
5
6
|
/** 参数密文(_high_security_: 前缀) */
|
|
6
7
|
value: string;
|
|
8
|
+
/**
|
|
9
|
+
* 缓存别名(可选)
|
|
10
|
+
* @description 当后端 key 相同但密文不同时(如两组 SDK 密钥),
|
|
11
|
+
* 用 cacheKey 区分缓存,请求体仍用 key。默认 cacheKey=key
|
|
12
|
+
*/
|
|
13
|
+
cacheKey?: string;
|
|
7
14
|
}
|
|
15
|
+
/** 单次请求的接口配置覆盖(优先级 > PntProvider 全局配置) */
|
|
16
|
+
export type HighSecurityApiConfig = PntHighSecurityConfig;
|
|
8
17
|
/** 高敏数据解锁请求参数(组件层友好命名,库内部转换为后端 snake_case) */
|
|
9
18
|
export interface HighSecurityRequestParams {
|
|
10
19
|
/** 业务 ID */
|
|
11
20
|
gameId: string | number;
|
|
12
|
-
/**
|
|
13
|
-
env
|
|
21
|
+
/** 环境标识(可缺省,默认 0;以各业务现有约定为准) */
|
|
22
|
+
env?: string | number;
|
|
14
23
|
/** 页面 ID(不传则默认取 location.pathname),用于操作日志和权限校验 */
|
|
15
24
|
pageId?: string;
|
|
16
25
|
/** 需要解锁的参数列表,支持批量 */
|
|
17
26
|
param: HighSecurityParamItem[];
|
|
27
|
+
/** 本次请求的接口配置覆盖(可选) */
|
|
28
|
+
apiConfig?: HighSecurityApiConfig;
|
|
18
29
|
}
|
|
19
30
|
/** hook 初始化 scope:传入后 securityData/isUnlocked 自动按该业务+环境过滤 */
|
|
20
31
|
export interface UseHighSecurityOptions {
|
|
21
32
|
/** 当前业务 ID */
|
|
22
33
|
gameId?: string | number;
|
|
23
|
-
/**
|
|
34
|
+
/** 当前环境(可缺省,默认 0) */
|
|
24
35
|
env?: string | number;
|
|
25
36
|
}
|
|
26
37
|
/** 清缓存过滤条件 */
|