@heybox/hb-sdk 0.7.3 → 0.7.4-alpha.4
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/CHANGELOG.md +48 -1
- package/README.md +5 -0
- package/dist/cli-chunks/{build-0sZ873iU.cjs → build-BqGFRLe-.cjs} +2 -2
- package/dist/cli-chunks/{context-DNQEI7m7.cjs → context-DTr3hRTv.cjs} +6 -19
- package/dist/cli-chunks/{create-BkE71M2U.cjs → create-OkiiiH4I.cjs} +1 -1
- package/dist/cli-chunks/{dev-_tBlQ2WO.cjs → dev-j7W9R7ew.cjs} +798 -139
- package/dist/cli-chunks/{doctor-B1wk8IpC.cjs → doctor-BO0vkDny.cjs} +1 -1
- package/dist/cli-chunks/{index-BbDsxI94.cjs → index-CZuvk1Rg.cjs} +1 -1
- package/dist/cli-chunks/{index-CIucOD2H.cjs → index-CyEqCbeu.cjs} +24 -21
- package/dist/cli-chunks/{login-CnjEKlFT.cjs → login-CuAGltGs.cjs} +2 -2
- package/dist/cli-chunks/{project-vite-ESaxoAE1.cjs → project-vite-BUY9DgYo.cjs} +1 -1
- package/dist/cli-chunks/{remote-BaGzge7R.cjs → remote-tPMcxgpi.cjs} +4 -4
- package/dist/cli-chunks/{session-C9KHqijL.cjs → session-BUjFX2U2.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/devtools/{mock-host → browser-dev-host}/index.html +3 -7
- package/dist/devtools/browser-dev-host/main.js +9835 -0
- package/dist/index.cjs.js +40 -118
- package/dist/index.esm.js +40 -118
- package/dist/protocol.cjs.js +71 -346
- package/dist/protocol.esm.js +72 -342
- package/dist/vite.cjs.js +1 -4
- package/dist/vite.esm.js +1 -4
- package/package.json +26 -9
- package/skill/SKILL.md +5 -5
- package/skill/references/api-protocol.md +102 -114
- package/skill/references/api-root.md +1 -1
- package/skill/references/cli.md +4 -2
- package/skill/references/recipes.md +2 -0
- package/skill/references/safety-boundaries.md +1 -0
- package/skill/scripts/sync-references.mjs +5 -1
- package/skill/skill.json +4 -4
- package/types/core/network-sanitize.d.ts +1 -1
- package/types/modules/auth/index.d.ts +3 -1
- package/types/modules/user/types.d.ts +2 -53
- package/types/protocol/capabilities.d.ts +2 -352
- package/types/protocol/constants.d.ts +1 -14
- package/types/protocol/dev-session.d.ts +3 -3
- package/types/protocol/guards.d.ts +1 -8
- package/types/protocol/runtime-permissions.d.ts +2 -41
- package/types/protocol/types.d.ts +3 -150
- package/types/protocol.d.ts +8 -23
- package/dist/devtools/mock-host/main.js +0 -7751
- package/types/protocol/network-policy.d.ts +0 -10
- package/types/protocol/trusted-user-gesture.d.ts +0 -6
package/dist/protocol.cjs.js
CHANGED
|
@@ -1,293 +1,32 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
/** 小程序沙盒通信命名空间,父容器与 iframe 内 SDK 必须保持一致。 */
|
|
4
|
-
const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
|
|
5
|
-
/** 小程序沙盒通信协议版本。 */
|
|
6
|
-
const MINI_PROGRAM_MESSAGE_VERSION = 2;
|
|
7
|
-
/** 父容器注入到小程序 URL 上的通信 nonce 参数名。 */
|
|
8
|
-
const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
|
|
9
|
-
/** SDK 初始化时发给父容器的握手方法名。 */
|
|
10
|
-
const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
|
|
11
|
-
/** Runtime 主动探测 SDK 当前文档地址的内部方法名。 */
|
|
12
|
-
const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
|
|
13
|
-
/** SDK 向 Runtime 报告当前文档地址的内部方法名。 */
|
|
14
|
-
const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
|
|
15
|
-
/** SDK 向 Runtime 报告 CSP 违规的内部方法名。 */
|
|
16
|
-
const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 判断未知数据是否符合小程序 bridge 消息信封。
|
|
20
|
-
*
|
|
21
|
-
* @param value 待判断的未知数据。
|
|
22
|
-
* @returns 当数据满足小程序 bridge 消息基础结构时返回 `true`。
|
|
23
|
-
*/
|
|
24
|
-
function isMiniProgramBridgeMessage(value) {
|
|
25
|
-
if (!value || typeof value !== 'object') {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
const message = value;
|
|
29
|
-
return (message.namespace === MINI_PROGRAM_MESSAGE_NAMESPACE &&
|
|
30
|
-
(message.version === 1 || message.version === 2) &&
|
|
31
|
-
typeof message.nonce === 'string' &&
|
|
32
|
-
typeof message.type === 'string');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function readBrowserEnvironment() {
|
|
36
|
-
try {
|
|
37
|
-
return {
|
|
38
|
-
activeElement: globalThis.document?.activeElement ?? null,
|
|
39
|
-
userActivation: globalThis.navigator?.userActivation,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
return { activeElement: null };
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/** 按当前浏览器消息、用户激活和目标 iframe 焦点生成请求级可信手势快照。 */
|
|
47
|
-
function computeTrustedIframeUserGesture(event, iframe, environment = readBrowserEnvironment()) {
|
|
48
|
-
return (event.isTrusted === true
|
|
49
|
-
&& environment.userActivation?.isActive === true
|
|
50
|
-
&& environment.activeElement === iframe);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const MANAGED_RUNTIME_PERMISSION_KEYS = new Set(['network.request']);
|
|
54
|
-
/**
|
|
55
|
-
* 判断 permission key 是否由 Runtime 权限快照管理。
|
|
56
|
-
*
|
|
57
|
-
* @param key 待判断的 permission key。
|
|
58
|
-
* @returns 该 key 需要读取 Runtime 权限快照时返回 `true`。
|
|
59
|
-
*/
|
|
60
|
-
function isManagedMiniProgramRuntimePermissionKey(key) {
|
|
61
|
-
return MANAGED_RUNTIME_PERMISSION_KEYS.has(key);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* 解析服务端权限快照;格式不完整时整份快照失效并 fail closed。
|
|
65
|
-
*
|
|
66
|
-
* @param snapshot 待校验的服务端权限快照。
|
|
67
|
-
* @returns 解析状态和通过校验的受管权限。
|
|
68
|
-
*/
|
|
69
|
-
function parseMiniProgramRuntimePermissions(snapshot) {
|
|
70
|
-
if (!isRecord(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
|
|
71
|
-
return { valid: false, permissions: {} };
|
|
72
|
-
}
|
|
73
|
-
if (snapshot.revision !== undefined && (typeof snapshot.revision !== 'number' || !Number.isInteger(snapshot.revision) || snapshot.revision < 0)) {
|
|
74
|
-
return { valid: false, permissions: {} };
|
|
75
|
-
}
|
|
76
|
-
const seenKeys = new Set();
|
|
77
|
-
const permissions = {};
|
|
78
|
-
for (const rawEntry of snapshot.entries) {
|
|
79
|
-
if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
|
|
80
|
-
return { valid: false, permissions: {} };
|
|
81
|
-
}
|
|
82
|
-
const key = rawEntry.key.trim();
|
|
83
|
-
if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled') || !isRecord(rawEntry.config)) {
|
|
84
|
-
return { valid: false, permissions: {} };
|
|
85
|
-
}
|
|
86
|
-
seenKeys.add(key);
|
|
87
|
-
if (!isManagedMiniProgramRuntimePermissionKey(key)) {
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (key === 'network.request' && typeof rawEntry.config.useOfficialDomain !== 'boolean') {
|
|
91
|
-
return { valid: false, permissions: {} };
|
|
92
|
-
}
|
|
93
|
-
permissions[key] = {
|
|
94
|
-
key,
|
|
95
|
-
status: rawEntry.status,
|
|
96
|
-
config: { useOfficialDomain: rawEntry.config.useOfficialDomain },
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
return { valid: true, permissions };
|
|
100
|
-
}
|
|
101
|
-
function isRecord(value) {
|
|
102
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const OFFICIAL_MINI_PROGRAM_NETWORK_ROOT_DOMAINS = [
|
|
106
|
-
'xiaoheihe.cn',
|
|
107
|
-
'max-c.com',
|
|
108
|
-
'debugmode.cn',
|
|
109
|
-
'maxjia.com',
|
|
110
|
-
];
|
|
111
|
-
/** Runtime / Host 在 `network.request` 分发前拒绝的小程序服务端私有路径前缀。 */
|
|
112
|
-
const MINI_PROGRAM_NETWORK_PROTECTED_PATHS = [
|
|
113
|
-
'/user_miniprogram/runtime/auth',
|
|
114
|
-
'/user_miniprogram/openapi/v1',
|
|
115
|
-
];
|
|
116
|
-
const NETWORK_REQUEST_PATHNAME_MAX_DECODE_ROUNDS = 4;
|
|
117
|
-
/** 使用 URL 解析后的 hostname 判断黑盒官方根域及其子域。 */
|
|
118
|
-
function isOfficialMiniProgramNetworkUrl(value) {
|
|
119
|
-
try {
|
|
120
|
-
const url = new URL(value);
|
|
121
|
-
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
const hostname = url.hostname.toLowerCase().replace(/\.$/, '');
|
|
125
|
-
return OFFICIAL_MINI_PROGRAM_NETWORK_ROOT_DOMAINS.some(rootDomain => hostname === rootDomain || hostname.endsWith(`.${rootDomain}`));
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* 规范化并判断 pathname 是否命中 Runtime Auth / OpenAPI 保护前缀。
|
|
133
|
-
* 解码失败或仍可继续解码时视为不安全路径。
|
|
134
|
-
*/
|
|
135
|
-
function isProtectedMiniProgramNetworkPath(pathname) {
|
|
136
|
-
const normalized = normalizeMiniProgramNetworkPathname(pathname);
|
|
137
|
-
if (normalized === null) {
|
|
138
|
-
return true;
|
|
139
|
-
}
|
|
140
|
-
return MINI_PROGRAM_NETWORK_PROTECTED_PATHS.some(prefix => normalized === prefix || normalized.startsWith(`${prefix}/`));
|
|
141
|
-
}
|
|
142
|
-
function normalizeMiniProgramNetworkPathname(pathname) {
|
|
143
|
-
let decoded = pathname;
|
|
144
|
-
for (let round = 0; round < NETWORK_REQUEST_PATHNAME_MAX_DECODE_ROUNDS; round += 1) {
|
|
145
|
-
let next;
|
|
146
|
-
try {
|
|
147
|
-
next = decodeURIComponent(decoded);
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
return null;
|
|
151
|
-
}
|
|
152
|
-
if (next === decoded) {
|
|
153
|
-
return normalizeDecodedNetworkPathname(decoded);
|
|
154
|
-
}
|
|
155
|
-
decoded = next;
|
|
156
|
-
}
|
|
157
|
-
try {
|
|
158
|
-
if (decodeURIComponent(decoded) !== decoded) {
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
return normalizeDecodedNetworkPathname(decoded);
|
|
166
|
-
}
|
|
167
|
-
function normalizeDecodedNetworkPathname(decoded) {
|
|
168
|
-
const segments = [];
|
|
169
|
-
for (const segment of decoded.replace(/\\/g, '/').split('/')) {
|
|
170
|
-
if (!segment || segment === '.') {
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
if (segment === '..') {
|
|
174
|
-
segments.pop();
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
segments.push(segment);
|
|
178
|
-
}
|
|
179
|
-
return `/${segments.join('/')}`;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* 登录授权能力方法名。
|
|
184
|
-
*
|
|
185
|
-
* @remarks
|
|
186
|
-
* 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
|
|
187
|
-
*/
|
|
188
3
|
const AUTH_LOGIN_METHOD = 'auth.login';
|
|
189
|
-
/** 读取当前登录态、授权状态和已获准披露资料的 bridge method 标识。 */
|
|
190
4
|
const USER_GET_INFO_METHOD = 'user.getInfo';
|
|
191
|
-
/** 撤销当前用户授予本小程序授权的 bridge method 标识。 */
|
|
192
5
|
const USER_REVOKE_AUTHORIZATION_METHOD = 'user.revokeAuthorization';
|
|
193
|
-
/** 读取当前已登录用户 Steam 游戏库的 bridge method 标识。 */
|
|
194
6
|
const USER_GET_STEAM_GAME_LIST_METHOD = 'user.getSteamGameList';
|
|
195
|
-
/**
|
|
196
|
-
* 展示分享面板能力方法名。
|
|
197
|
-
*
|
|
198
|
-
* @remarks
|
|
199
|
-
* 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
|
|
200
|
-
*/
|
|
201
7
|
const SHARE_SHOW_SHARE_MENU_METHOD = 'share.showShareMenu';
|
|
202
|
-
/**
|
|
203
|
-
* 截图分享能力方法名。
|
|
204
|
-
*
|
|
205
|
-
* @remarks
|
|
206
|
-
* 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
|
|
207
|
-
*/
|
|
208
8
|
const SHARE_SCREENSHOT_METHOD = 'share.screenshot';
|
|
209
|
-
/**
|
|
210
|
-
* 视口窗口信息能力方法名。
|
|
211
|
-
*
|
|
212
|
-
* @remarks
|
|
213
|
-
* 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
|
|
214
|
-
*/
|
|
215
9
|
const VIEWPORT_GET_WINDOW_INFO_METHOD = 'viewport.getWindowInfo';
|
|
216
|
-
/**
|
|
217
|
-
* 设置导航栏样式能力方法名。
|
|
218
|
-
*
|
|
219
|
-
* @remarks
|
|
220
|
-
* 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
|
|
221
|
-
*/
|
|
222
10
|
const VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = 'viewport.setNavigationBarStyle';
|
|
223
|
-
/**
|
|
224
|
-
* 读取小程序隔离 storage 能力方法名。
|
|
225
|
-
*
|
|
226
|
-
* @remarks
|
|
227
|
-
* 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
|
|
228
|
-
*/
|
|
229
11
|
const STORAGE_GET_STORAGE_METHOD = 'storage.getStorage';
|
|
230
|
-
/**
|
|
231
|
-
* 写入小程序隔离 storage 能力方法名。
|
|
232
|
-
*
|
|
233
|
-
* @remarks
|
|
234
|
-
* 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
|
|
235
|
-
*/
|
|
236
12
|
const STORAGE_SET_STORAGE_METHOD = 'storage.setStorage';
|
|
237
|
-
/**
|
|
238
|
-
* 发起网络请求能力方法名。
|
|
239
|
-
*
|
|
240
|
-
* @remarks
|
|
241
|
-
* 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
|
|
242
|
-
*/
|
|
243
13
|
const NETWORK_REQUEST_METHOD = 'network.request';
|
|
244
|
-
/** 展示 toast 能力方法名。 */
|
|
245
14
|
const UI_SHOW_TOAST_METHOD = 'ui.showToast';
|
|
246
|
-
/** 展示全局 loading 能力方法名。 */
|
|
247
15
|
const UI_SHOW_LOADING_METHOD = 'ui.showLoading';
|
|
248
|
-
/** 隐藏全局 loading 能力方法名。 */
|
|
249
16
|
const UI_HIDE_LOADING_METHOD = 'ui.hideLoading';
|
|
250
|
-
/** 震动反馈能力方法名。 */
|
|
251
17
|
const DEVICE_VIBRATE_METHOD = 'device.vibrate';
|
|
252
|
-
/** 写入文本剪贴板能力方法名。 */
|
|
253
18
|
const DEVICE_SET_CLIPBOARD_METHOD = 'device.setClipboard';
|
|
254
|
-
/** 关闭当前小程序容器能力方法名。 */
|
|
255
19
|
const NAVIGATION_CLOSE_METHOD = 'navigation.close';
|
|
256
|
-
/** 重载当前小程序容器能力方法名。 */
|
|
257
20
|
const NAVIGATION_RELOAD_METHOD = 'navigation.reload';
|
|
258
|
-
/** 打开黑盒 App 页面能力方法名。 */
|
|
259
21
|
const NAVIGATION_OPEN_APP_PAGE_METHOD = 'navigation.openAppPage';
|
|
260
|
-
/** 提交当前用户排行榜分数能力方法名。 */
|
|
261
22
|
const CLOUD_LEADERBOARD_SUBMIT_METHOD = 'cloud.leaderboard.submit';
|
|
262
|
-
/** 读取排行榜列表能力方法名。 */
|
|
263
23
|
const CLOUD_LEADERBOARD_GET_LIST_METHOD = 'cloud.leaderboard.getList';
|
|
264
|
-
/** 读取当前用户排行榜记录能力方法名。 */
|
|
265
24
|
const CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.getCurrentUserEntry';
|
|
266
|
-
/** 删除当前用户排行榜记录能力方法名。 */
|
|
267
25
|
const CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.deleteCurrentUserEntry';
|
|
268
|
-
/** 读取排行榜基础信息能力方法名。 */
|
|
269
26
|
const CLOUD_LEADERBOARD_GET_INFO_METHOD = 'cloud.leaderboard.getInfo';
|
|
270
|
-
/**
|
|
271
|
-
* 小程序开放能力目录。
|
|
272
|
-
*
|
|
273
|
-
* @remarks
|
|
274
|
-
* 新增 bridge method 时应先更新这里,再分别补齐 SDK 模块、runtime handler 与测试。
|
|
275
|
-
*/
|
|
276
27
|
const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
277
|
-
{
|
|
278
|
-
|
|
279
|
-
module: 'auth',
|
|
280
|
-
capability: AUTH_LOGIN_METHOD,
|
|
281
|
-
permission: 'auth.login',
|
|
282
|
-
risk: 'medium',
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
method: USER_GET_INFO_METHOD,
|
|
286
|
-
module: 'user',
|
|
287
|
-
capability: USER_GET_INFO_METHOD,
|
|
288
|
-
permission: 'user.getInfo',
|
|
289
|
-
risk: 'medium',
|
|
290
|
-
},
|
|
28
|
+
{ method: AUTH_LOGIN_METHOD, module: 'auth', capability: AUTH_LOGIN_METHOD, permission: 'auth.login', risk: 'medium' },
|
|
29
|
+
{ method: USER_GET_INFO_METHOD, module: 'user', capability: USER_GET_INFO_METHOD, permission: 'user.getInfo', risk: 'medium' },
|
|
291
30
|
{
|
|
292
31
|
method: USER_REVOKE_AUTHORIZATION_METHOD,
|
|
293
32
|
module: 'user',
|
|
@@ -302,20 +41,8 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
|
302
41
|
permission: 'user.platformAccount.steam',
|
|
303
42
|
risk: 'high',
|
|
304
43
|
},
|
|
305
|
-
{
|
|
306
|
-
|
|
307
|
-
module: 'share',
|
|
308
|
-
capability: SHARE_SHOW_SHARE_MENU_METHOD,
|
|
309
|
-
permission: 'share.basic',
|
|
310
|
-
risk: 'low',
|
|
311
|
-
},
|
|
312
|
-
{
|
|
313
|
-
method: SHARE_SCREENSHOT_METHOD,
|
|
314
|
-
module: 'share',
|
|
315
|
-
capability: SHARE_SCREENSHOT_METHOD,
|
|
316
|
-
permission: 'share.screenshot',
|
|
317
|
-
risk: 'medium',
|
|
318
|
-
},
|
|
44
|
+
{ method: SHARE_SHOW_SHARE_MENU_METHOD, module: 'share', capability: SHARE_SHOW_SHARE_MENU_METHOD, permission: 'share.basic', risk: 'low' },
|
|
45
|
+
{ method: SHARE_SCREENSHOT_METHOD, module: 'share', capability: SHARE_SCREENSHOT_METHOD, permission: 'share.screenshot', risk: 'medium' },
|
|
319
46
|
{
|
|
320
47
|
method: VIEWPORT_GET_WINDOW_INFO_METHOD,
|
|
321
48
|
module: 'viewport',
|
|
@@ -330,55 +57,13 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
|
330
57
|
permission: 'viewport.navigationBarStyle',
|
|
331
58
|
risk: 'low',
|
|
332
59
|
},
|
|
333
|
-
{
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
method: STORAGE_SET_STORAGE_METHOD,
|
|
342
|
-
module: 'storage',
|
|
343
|
-
capability: STORAGE_SET_STORAGE_METHOD,
|
|
344
|
-
permission: 'storage.write',
|
|
345
|
-
risk: 'medium',
|
|
346
|
-
},
|
|
347
|
-
{
|
|
348
|
-
method: NETWORK_REQUEST_METHOD,
|
|
349
|
-
module: 'network',
|
|
350
|
-
capability: NETWORK_REQUEST_METHOD,
|
|
351
|
-
permission: 'network.request',
|
|
352
|
-
risk: 'high',
|
|
353
|
-
},
|
|
354
|
-
{
|
|
355
|
-
method: UI_SHOW_TOAST_METHOD,
|
|
356
|
-
module: 'ui',
|
|
357
|
-
capability: UI_SHOW_TOAST_METHOD,
|
|
358
|
-
permission: 'ui.toast',
|
|
359
|
-
risk: 'low',
|
|
360
|
-
},
|
|
361
|
-
{
|
|
362
|
-
method: UI_SHOW_LOADING_METHOD,
|
|
363
|
-
module: 'ui',
|
|
364
|
-
capability: UI_SHOW_LOADING_METHOD,
|
|
365
|
-
permission: 'ui.loading',
|
|
366
|
-
risk: 'low',
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
method: UI_HIDE_LOADING_METHOD,
|
|
370
|
-
module: 'ui',
|
|
371
|
-
capability: UI_HIDE_LOADING_METHOD,
|
|
372
|
-
permission: 'ui.loading',
|
|
373
|
-
risk: 'low',
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
method: DEVICE_VIBRATE_METHOD,
|
|
377
|
-
module: 'device',
|
|
378
|
-
capability: DEVICE_VIBRATE_METHOD,
|
|
379
|
-
permission: 'device.vibrate',
|
|
380
|
-
risk: 'low',
|
|
381
|
-
},
|
|
60
|
+
{ method: STORAGE_GET_STORAGE_METHOD, module: 'storage', capability: STORAGE_GET_STORAGE_METHOD, permission: 'storage.read', risk: 'low' },
|
|
61
|
+
{ method: STORAGE_SET_STORAGE_METHOD, module: 'storage', capability: STORAGE_SET_STORAGE_METHOD, permission: 'storage.write', risk: 'medium' },
|
|
62
|
+
{ method: NETWORK_REQUEST_METHOD, module: 'network', capability: NETWORK_REQUEST_METHOD, permission: 'network.request', risk: 'high' },
|
|
63
|
+
{ method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, permission: 'ui.toast', risk: 'low' },
|
|
64
|
+
{ method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
|
|
65
|
+
{ method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
|
|
66
|
+
{ method: DEVICE_VIBRATE_METHOD, module: 'device', capability: DEVICE_VIBRATE_METHOD, permission: 'device.vibrate', risk: 'low' },
|
|
382
67
|
{
|
|
383
68
|
method: DEVICE_SET_CLIPBOARD_METHOD,
|
|
384
69
|
module: 'device',
|
|
@@ -386,20 +71,8 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
|
386
71
|
permission: 'device.clipboard.write',
|
|
387
72
|
risk: 'medium',
|
|
388
73
|
},
|
|
389
|
-
{
|
|
390
|
-
|
|
391
|
-
module: 'navigation',
|
|
392
|
-
capability: NAVIGATION_CLOSE_METHOD,
|
|
393
|
-
permission: 'navigation.close',
|
|
394
|
-
risk: 'medium',
|
|
395
|
-
},
|
|
396
|
-
{
|
|
397
|
-
method: NAVIGATION_RELOAD_METHOD,
|
|
398
|
-
module: 'navigation',
|
|
399
|
-
capability: NAVIGATION_RELOAD_METHOD,
|
|
400
|
-
permission: 'navigation.reload',
|
|
401
|
-
risk: 'medium',
|
|
402
|
-
},
|
|
74
|
+
{ method: NAVIGATION_CLOSE_METHOD, module: 'navigation', capability: NAVIGATION_CLOSE_METHOD, permission: 'navigation.close', risk: 'medium' },
|
|
75
|
+
{ method: NAVIGATION_RELOAD_METHOD, module: 'navigation', capability: NAVIGATION_RELOAD_METHOD, permission: 'navigation.reload', risk: 'medium' },
|
|
403
76
|
{
|
|
404
77
|
method: NAVIGATION_OPEN_APP_PAGE_METHOD,
|
|
405
78
|
module: 'navigation',
|
|
@@ -444,9 +117,66 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
|
444
117
|
},
|
|
445
118
|
];
|
|
446
119
|
|
|
447
|
-
|
|
120
|
+
const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
|
|
121
|
+
const MINI_PROGRAM_MESSAGE_VERSION = 2;
|
|
122
|
+
const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
|
|
123
|
+
const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
|
|
124
|
+
const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
|
|
125
|
+
const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
|
|
126
|
+
const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
|
|
127
|
+
|
|
128
|
+
function isMiniProgramBridgeMessage(value) {
|
|
129
|
+
if (!value || typeof value !== 'object')
|
|
130
|
+
return false;
|
|
131
|
+
const message = value;
|
|
132
|
+
return (message.namespace === MINI_PROGRAM_MESSAGE_NAMESPACE &&
|
|
133
|
+
(message.version === 1 || message.version === 2) &&
|
|
134
|
+
typeof message.nonce === 'string' &&
|
|
135
|
+
typeof message.type === 'string');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** 当前用户信息与登录能力支持的完整 scope 目录。 */
|
|
448
139
|
const USER_INFO_AUTHORIZATION_SCOPES = ['identity', 'profile'];
|
|
449
140
|
|
|
141
|
+
const MANAGED_RUNTIME_PERMISSION_KEYS = new Set(['network.request']);
|
|
142
|
+
function isManagedMiniProgramRuntimePermissionKey(key) {
|
|
143
|
+
return MANAGED_RUNTIME_PERMISSION_KEYS.has(key);
|
|
144
|
+
}
|
|
145
|
+
function parseMiniProgramRuntimePermissions(snapshot) {
|
|
146
|
+
if (!isRecord(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
|
|
147
|
+
return { valid: false, permissions: {} };
|
|
148
|
+
}
|
|
149
|
+
if (snapshot.revision !== undefined && (typeof snapshot.revision !== 'number' || !Number.isInteger(snapshot.revision) || snapshot.revision < 0)) {
|
|
150
|
+
return { valid: false, permissions: {} };
|
|
151
|
+
}
|
|
152
|
+
const seenKeys = new Set();
|
|
153
|
+
const permissions = {};
|
|
154
|
+
for (const rawEntry of snapshot.entries) {
|
|
155
|
+
if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
|
|
156
|
+
return { valid: false, permissions: {} };
|
|
157
|
+
}
|
|
158
|
+
const key = rawEntry.key.trim();
|
|
159
|
+
if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled') || !isRecord(rawEntry.config)) {
|
|
160
|
+
return { valid: false, permissions: {} };
|
|
161
|
+
}
|
|
162
|
+
seenKeys.add(key);
|
|
163
|
+
if (!isManagedMiniProgramRuntimePermissionKey(key))
|
|
164
|
+
continue;
|
|
165
|
+
if (key === 'network.request' && typeof rawEntry.config.useOfficialDomain !== 'boolean') {
|
|
166
|
+
return { valid: false, permissions: {} };
|
|
167
|
+
}
|
|
168
|
+
permissions[key] = {
|
|
169
|
+
key,
|
|
170
|
+
status: rawEntry.status,
|
|
171
|
+
config: { useOfficialDomain: rawEntry.config.useOfficialDomain },
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return { valid: true, permissions };
|
|
175
|
+
}
|
|
176
|
+
function isRecord(value) {
|
|
177
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
178
|
+
}
|
|
179
|
+
|
|
450
180
|
exports.AUTH_LOGIN_METHOD = AUTH_LOGIN_METHOD;
|
|
451
181
|
exports.CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD = CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD;
|
|
452
182
|
exports.CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD = CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD;
|
|
@@ -458,7 +188,6 @@ exports.DEVICE_VIBRATE_METHOD = DEVICE_VIBRATE_METHOD;
|
|
|
458
188
|
exports.MINI_PROGRAM_BRIDGE_NONCE_PARAM = MINI_PROGRAM_BRIDGE_NONCE_PARAM;
|
|
459
189
|
exports.MINI_PROGRAM_MESSAGE_NAMESPACE = MINI_PROGRAM_MESSAGE_NAMESPACE;
|
|
460
190
|
exports.MINI_PROGRAM_MESSAGE_VERSION = MINI_PROGRAM_MESSAGE_VERSION;
|
|
461
|
-
exports.MINI_PROGRAM_NETWORK_PROTECTED_PATHS = MINI_PROGRAM_NETWORK_PROTECTED_PATHS;
|
|
462
191
|
exports.MINI_PROGRAM_PROTOCOL_CAPABILITIES = MINI_PROGRAM_PROTOCOL_CAPABILITIES;
|
|
463
192
|
exports.NAVIGATION_CLOSE_METHOD = NAVIGATION_CLOSE_METHOD;
|
|
464
193
|
exports.NAVIGATION_OPEN_APP_PAGE_METHOD = NAVIGATION_OPEN_APP_PAGE_METHOD;
|
|
@@ -481,10 +210,6 @@ exports.USER_INFO_AUTHORIZATION_SCOPES = USER_INFO_AUTHORIZATION_SCOPES;
|
|
|
481
210
|
exports.USER_REVOKE_AUTHORIZATION_METHOD = USER_REVOKE_AUTHORIZATION_METHOD;
|
|
482
211
|
exports.VIEWPORT_GET_WINDOW_INFO_METHOD = VIEWPORT_GET_WINDOW_INFO_METHOD;
|
|
483
212
|
exports.VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD;
|
|
484
|
-
exports.computeTrustedIframeUserGesture = computeTrustedIframeUserGesture;
|
|
485
213
|
exports.isManagedMiniProgramRuntimePermissionKey = isManagedMiniProgramRuntimePermissionKey;
|
|
486
214
|
exports.isMiniProgramBridgeMessage = isMiniProgramBridgeMessage;
|
|
487
|
-
exports.isOfficialMiniProgramNetworkUrl = isOfficialMiniProgramNetworkUrl;
|
|
488
|
-
exports.isProtectedMiniProgramNetworkPath = isProtectedMiniProgramNetworkPath;
|
|
489
|
-
exports.normalizeMiniProgramNetworkPathname = normalizeMiniProgramNetworkPathname;
|
|
490
215
|
exports.parseMiniProgramRuntimePermissions = parseMiniProgramRuntimePermissions;
|