@heybox/hb-sdk 0.5.17 → 0.6.0
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/README.md +46 -25
- package/dist/cli-chunks/{create-CPIjDM-n.cjs → create-DYb53EQ-.cjs} +1 -1
- package/dist/cli-chunks/{dev-Cr2u9ajy.cjs → dev-CPKTuA6q.cjs} +35 -6
- package/dist/cli-chunks/{doctor-mIgvLfLl.cjs → doctor-TshFvqHC.cjs} +1 -1
- package/dist/cli-chunks/{index-Dor8wa6R.cjs → index-CCeHouBU.cjs} +269 -17
- package/dist/cli-chunks/{index-DHWEoki_.cjs → index-NOO3q8_C.cjs} +3 -3
- package/dist/cli-chunks/{login-B63QgKed.cjs → login-DtXHSm8R.cjs} +2 -2
- package/dist/cli-chunks/remote-BWfn7qIN.cjs +9915 -0
- package/dist/cli-chunks/{context-mav2gs13.cjs → sdk-version-policy-B1CFC1Dk.cjs} +122 -1
- package/dist/cli-chunks/{session-BMSThs93.cjs → session-DIcRjyDY.cjs} +4 -54
- package/dist/cli.cjs +1 -1
- package/dist/devtools/mock-host/index.html +40 -0
- package/dist/devtools/mock-host/main.js +85 -0
- package/dist/index.cjs.js +232 -4
- package/dist/index.esm.js +233 -3
- package/dist/miniapp-publish.cjs.js +4 -0
- package/dist/miniapp-publish.esm.js +4 -1
- package/dist/protocol.cjs.js +9 -0
- package/dist/protocol.esm.js +7 -1
- package/dist/vite.cjs.js +9159 -22
- package/dist/vite.esm.js +9159 -23
- package/package.json +19 -7
- package/skill/SKILL.md +23 -23
- package/skill/references/api-protocol.md +11 -2
- package/skill/references/api-root.md +145 -19
- package/skill/references/cli.md +29 -14
- package/skill/references/recipes.md +12 -44
- package/skill/references/safety-boundaries.md +1 -2
- package/skill/scripts/sync-references.mjs +2 -2
- package/skill/skill.json +4 -4
- package/types/cli/auth/base-url.d.ts +20 -0
- package/types/cli/config.d.ts +11 -0
- package/types/core/client.d.ts +7 -0
- package/types/core/csp-violation.d.ts +5 -0
- package/types/core/history-observer.d.ts +4 -0
- package/types/core/version.d.ts +2 -0
- package/types/index.d.ts +0 -2
- package/types/miniapp-manifest/schema.d.ts +6 -1
- package/types/miniapp-manifest/sdk-version-policy.d.ts +9 -0
- package/types/miniapp-publish/index.d.ts +1 -0
- package/types/protocol/constants.d.ts +6 -0
- package/types/protocol/types.d.ts +45 -0
- package/types/protocol.d.ts +2 -2
- package/types/vite/html-policy.d.ts +4 -0
- package/types/vite/index.d.ts +23 -3
- package/types/vite/runtime-gate.d.ts +5 -0
- package/types/vite/sdk-version-gate.d.ts +8 -0
- package/dist/cli-chunks/remote-Dksa9s5M.cjs +0 -1603
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var session = require('./session-
|
|
3
|
+
var session = require('./session-DIcRjyDY.cjs');
|
|
4
4
|
var fs$1 = require('node:fs');
|
|
5
5
|
var fs = require('node:fs/promises');
|
|
6
6
|
var path = require('node:path');
|
|
7
|
+
var index = require('./index-CCeHouBU.cjs');
|
|
8
|
+
|
|
9
|
+
const APIUserMiniprogramPublicSdkConfigPath = '/user_miniprogram/public/sdk_config';
|
|
10
|
+
function createUserMiniprogramPublicSdkConfigRequest(serviceTag) {
|
|
11
|
+
return {
|
|
12
|
+
path: APIUserMiniprogramPublicSdkConfigPath,
|
|
13
|
+
searchParams: serviceTag ? { special_tag: serviceTag } : {},
|
|
14
|
+
headers: serviceTag ? { 'x-rylai-service-tag': serviceTag } : {},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function parseUserMiniprogramPublicSdkConfigResult(value) {
|
|
18
|
+
if (!isRecord(value) ||
|
|
19
|
+
typeof value.minimum_sdk_version !== 'string') {
|
|
20
|
+
throw new Error('公共 SDK 配置响应无效');
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
function isRecord(value) {
|
|
25
|
+
return typeof value === 'object' && value !== null;
|
|
26
|
+
}
|
|
7
27
|
|
|
8
28
|
var re = {exports: {}};
|
|
9
29
|
|
|
@@ -2794,6 +2814,7 @@ const MINIAPP_UPLOAD_SCOPE = 'activity';
|
|
|
2794
2814
|
const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
|
|
2795
2815
|
const MINIAPP_UPLOAD_BATCH_SIZE = 50;
|
|
2796
2816
|
const MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES = 100 * 1024 * 1024;
|
|
2817
|
+
const PUBLIC_USER_MINIPROGRAM_SDK_CONFIG_API_PATH = APIUserMiniprogramPublicSdkConfigPath;
|
|
2797
2818
|
const USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = '/mall/developer/user_miniprogram/access_status';
|
|
2798
2819
|
const DEVELOPER_ENTITY_LIST_API_PATH = '/mall/developer/entity/list';
|
|
2799
2820
|
const DEVELOPER_ENTITY_SWITCH_API_PATH = '/mall/developer/entity/switch';
|
|
@@ -2909,6 +2930,20 @@ function createRemoteApiClient(options) {
|
|
|
2909
2930
|
listUserMiniprogramVersions: (requestOptions) => listUserMiniprogramVersions(requestOptions, options),
|
|
2910
2931
|
};
|
|
2911
2932
|
}
|
|
2933
|
+
async function getPublicSdkConfig(runtime) {
|
|
2934
|
+
const fetchImpl = runtime.fetchImpl ?? fetch;
|
|
2935
|
+
const serviceTag = index.resolveHeyboxRylaiServiceTag(PUBLIC_USER_MINIPROGRAM_SDK_CONFIG_API_PATH);
|
|
2936
|
+
const request = createUserMiniprogramPublicSdkConfigRequest(serviceTag);
|
|
2937
|
+
const response = await fetchImpl(session.createHeyboxApiUrl(runtime.baseUrl ?? 'https://api.xiaoheihe.cn', request.path, request.searchParams), {
|
|
2938
|
+
method: 'GET',
|
|
2939
|
+
headers: {
|
|
2940
|
+
Referer: session.HEYBOX_WEB_REFERER,
|
|
2941
|
+
...request.headers,
|
|
2942
|
+
},
|
|
2943
|
+
});
|
|
2944
|
+
const result = await readRequiredResult(response, request.path);
|
|
2945
|
+
return parseUserMiniprogramPublicSdkConfigResult(result);
|
|
2946
|
+
}
|
|
2912
2947
|
async function listDeveloperEntities(runtime) {
|
|
2913
2948
|
return remoteGet(DEVELOPER_ENTITY_LIST_API_PATH, {}, runtime);
|
|
2914
2949
|
}
|
|
@@ -3179,6 +3214,91 @@ function isTruthyEnvFlag(value) {
|
|
|
3179
3214
|
.toLowerCase());
|
|
3180
3215
|
}
|
|
3181
3216
|
|
|
3217
|
+
const CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1_000;
|
|
3218
|
+
const CACHE_FILE_NAME = 'minimum-sdk-versions.json';
|
|
3219
|
+
async function resolveMinimumSdkVersion(options) {
|
|
3220
|
+
const now = options.now ?? Date.now();
|
|
3221
|
+
const cachePath = path.join(options.cacheDir, CACHE_FILE_NAME);
|
|
3222
|
+
const cache = await readCache(cachePath);
|
|
3223
|
+
let minimumSdkVersion;
|
|
3224
|
+
try {
|
|
3225
|
+
minimumSdkVersion = validateStableSdkVersion(await options.fetchMinimumSdkVersion(), 'minimumSdkVersion');
|
|
3226
|
+
}
|
|
3227
|
+
catch {
|
|
3228
|
+
const cached = cache.environments[options.environment];
|
|
3229
|
+
const cacheAge = cached ? now - cached.fetchedAt : Number.NaN;
|
|
3230
|
+
if (cached && Number.isFinite(cached.fetchedAt) && cacheAge >= 0 && cacheAge <= CACHE_MAX_AGE_MS) {
|
|
3231
|
+
try {
|
|
3232
|
+
return validateStableSdkVersion(cached.minimumSdkVersion, 'cached minimumSdkVersion');
|
|
3233
|
+
}
|
|
3234
|
+
catch {
|
|
3235
|
+
// 非法缓存按不存在处理。
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
throw new Error('MINIMUM_SDK_VERSION_UNAVAILABLE:无法获取最低 SDK 版本,且没有 24 小时内的有效缓存');
|
|
3239
|
+
}
|
|
3240
|
+
cache.environments[options.environment] = { fetchedAt: now, minimumSdkVersion };
|
|
3241
|
+
try {
|
|
3242
|
+
await writeCache(cachePath, cache);
|
|
3243
|
+
}
|
|
3244
|
+
catch {
|
|
3245
|
+
// 已校验的远端策略仍然可信;缓存只是离线回退优化。
|
|
3246
|
+
}
|
|
3247
|
+
return minimumSdkVersion;
|
|
3248
|
+
}
|
|
3249
|
+
function validateCurrentSdkVersion(currentSdkVersion, minimumSdkVersion, options) {
|
|
3250
|
+
const current = validateSdkVersion(currentSdkVersion, '当前 SDK 版本');
|
|
3251
|
+
const minimum = validateStableSdkVersion(minimumSdkVersion, 'minimumSdkVersion');
|
|
3252
|
+
if (!options.allowPrerelease && semverExports.prerelease(current) !== null) {
|
|
3253
|
+
throw new Error('正式发布不允许使用预发布 SDK,请运行 pnpm add @heybox/hb-sdk@latest 后重新构建');
|
|
3254
|
+
}
|
|
3255
|
+
if (!semverExports.satisfies(current, `>=${minimum}`, { includePrerelease: options.allowPrerelease })) {
|
|
3256
|
+
throw new Error(`SDK_VERSION_TOO_LOW:当前 @heybox/hb-sdk@${current} 低于最低版本 ${minimum},请运行 pnpm add @heybox/hb-sdk@latest`);
|
|
3257
|
+
}
|
|
3258
|
+
return current;
|
|
3259
|
+
}
|
|
3260
|
+
function validateSdkVersion(value, label) {
|
|
3261
|
+
const normalized = String(value).trim();
|
|
3262
|
+
const parsed = semverExports.parse(normalized);
|
|
3263
|
+
if (!parsed || parsed.version !== normalized || parsed.build.length > 0) {
|
|
3264
|
+
throw new Error(`${label} 必须是合法 SemVer:${normalized}`);
|
|
3265
|
+
}
|
|
3266
|
+
return normalized;
|
|
3267
|
+
}
|
|
3268
|
+
function validateStableSdkVersion(value, label) {
|
|
3269
|
+
const normalized = validateSdkVersion(value, label);
|
|
3270
|
+
if (semverExports.prerelease(normalized) !== null)
|
|
3271
|
+
throw new Error(`${label} 必须是稳定 SemVer:${normalized}`);
|
|
3272
|
+
return normalized;
|
|
3273
|
+
}
|
|
3274
|
+
async function readCache(cachePath) {
|
|
3275
|
+
try {
|
|
3276
|
+
const parsed = JSON.parse(await fs.readFile(cachePath, 'utf8'));
|
|
3277
|
+
if (parsed && typeof parsed === 'object' && parsed.environments && typeof parsed.environments === 'object')
|
|
3278
|
+
return parsed;
|
|
3279
|
+
}
|
|
3280
|
+
catch {
|
|
3281
|
+
// 缓存缺失或损坏时继续请求最新配置。
|
|
3282
|
+
}
|
|
3283
|
+
return { environments: {} };
|
|
3284
|
+
}
|
|
3285
|
+
async function writeCache(cachePath, cache) {
|
|
3286
|
+
await fs.mkdir(path.dirname(cachePath), { recursive: true });
|
|
3287
|
+
const temporaryPath = `${cachePath}.${process.pid}.tmp`;
|
|
3288
|
+
await fs.writeFile(temporaryPath, `${JSON.stringify(cache, null, 2)}\n`, { mode: 0o600 });
|
|
3289
|
+
await fs.rename(temporaryPath, cachePath);
|
|
3290
|
+
}
|
|
3291
|
+
|
|
3292
|
+
const paths = index.envPaths('hb-sdk');
|
|
3293
|
+
async function enforceRemoteSdkVersion(options) {
|
|
3294
|
+
const minimumSdkVersion = await resolveMinimumSdkVersion({
|
|
3295
|
+
cacheDir: options.cacheDir ?? paths.cache,
|
|
3296
|
+
environment: options.environment,
|
|
3297
|
+
fetchMinimumSdkVersion: async () => (await getPublicSdkConfig({ baseUrl: options.environment, fetchImpl: options.fetchImpl })).minimum_sdk_version,
|
|
3298
|
+
});
|
|
3299
|
+
return validateCurrentSdkVersion(options.sdkVersion, minimumSdkVersion, { allowPrerelease: options.allowPrerelease });
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3182
3302
|
exports.ACTIVITY_UPLOAD_KEY_MAX_LENGTH = ACTIVITY_UPLOAD_KEY_MAX_LENGTH;
|
|
3183
3303
|
exports.MINIAPP_UPLOAD_BATCH_SIZE = MINIAPP_UPLOAD_BATCH_SIZE;
|
|
3184
3304
|
exports.MINIAPP_UPLOAD_SCOPE = MINIAPP_UPLOAD_SCOPE;
|
|
@@ -3186,6 +3306,7 @@ exports.MiniProgramProjectBindingError = MiniProgramProjectBindingError;
|
|
|
3186
3306
|
exports.PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH = PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH;
|
|
3187
3307
|
exports.SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH = SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH;
|
|
3188
3308
|
exports.createRemoteApiClientForEnvironment = createRemoteApiClientForEnvironment;
|
|
3309
|
+
exports.enforceRemoteSdkVersion = enforceRemoteSdkVersion;
|
|
3189
3310
|
exports.getBoundMiniProgram = getBoundMiniProgram;
|
|
3190
3311
|
exports.getMiniappUploadKey = getMiniappUploadKey;
|
|
3191
3312
|
exports.normalizeRelativePath = normalizeRelativePath;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-CCeHouBU.cjs');
|
|
4
4
|
var node_crypto = require('node:crypto');
|
|
5
5
|
var path = require('node:path');
|
|
6
6
|
var require$$0$2 = require('fs');
|
|
@@ -67,57 +67,6 @@ function isTruthyEnvFlag(value) {
|
|
|
67
67
|
.toLowerCase());
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const globalHeyboxCliRequestConfig = {};
|
|
71
|
-
function readHeyboxCliRequestConfig() {
|
|
72
|
-
return normalizeHeyboxRylaiServiceTagConfig(globalHeyboxCliRequestConfig);
|
|
73
|
-
}
|
|
74
|
-
function resolveHeyboxRylaiServiceTag(pathWithQuery, config = readHeyboxCliRequestConfig()) {
|
|
75
|
-
const normalized = normalizeHeyboxRylaiServiceTagConfig(config);
|
|
76
|
-
const pathname = pathWithQuery ? getPathname(pathWithQuery) : '';
|
|
77
|
-
const specialTag = normalized.special_tag;
|
|
78
|
-
if (pathname && specialTag?.path_prefix_list.some((prefix) => pathname.startsWith(prefix))) {
|
|
79
|
-
return specialTag.tag_name;
|
|
80
|
-
}
|
|
81
|
-
return normalized.default_tag;
|
|
82
|
-
}
|
|
83
|
-
function normalizeHeyboxRylaiServiceTagConfig(config) {
|
|
84
|
-
const defaultTag = normalizeHeyboxRylaiServiceTag(config.default_tag);
|
|
85
|
-
const specialTagName = normalizeHeyboxRylaiServiceTag(config.special_tag?.tag_name);
|
|
86
|
-
const pathPrefixList = config.special_tag?.path_prefix_list?.filter(isValidPathPrefix) || [];
|
|
87
|
-
return {
|
|
88
|
-
...(defaultTag ? { default_tag: defaultTag } : {}),
|
|
89
|
-
...(specialTagName && pathPrefixList.length
|
|
90
|
-
? {
|
|
91
|
-
special_tag: {
|
|
92
|
-
tag_name: specialTagName,
|
|
93
|
-
path_prefix_list: pathPrefixList,
|
|
94
|
-
},
|
|
95
|
-
}
|
|
96
|
-
: {}),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
function normalizeHeyboxRylaiServiceTag(value) {
|
|
100
|
-
const tag = String(value ?? '').trim();
|
|
101
|
-
if (!tag) {
|
|
102
|
-
return undefined;
|
|
103
|
-
}
|
|
104
|
-
if (/[\r\n]/.test(tag)) {
|
|
105
|
-
throw new Error('x-rylai-service-tag 不允许包含换行符');
|
|
106
|
-
}
|
|
107
|
-
return tag;
|
|
108
|
-
}
|
|
109
|
-
function isValidPathPrefix(value) {
|
|
110
|
-
return typeof value === 'string' && value.startsWith('/') && !/[\r\n]/.test(value);
|
|
111
|
-
}
|
|
112
|
-
function getPathname(pathWithQuery) {
|
|
113
|
-
try {
|
|
114
|
-
return new URL(pathWithQuery, 'https://api.xiaoheihe.cn').pathname;
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
return '';
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
70
|
const SIGN_VERSION = '999.0.4';
|
|
122
71
|
const SIGN_CHARSET = 'AB45STUVWZEFGJ6CH01D237IXYPQRKLMN89';
|
|
123
72
|
function createHeyboxOpenPlatformSignParams(pathname, options = {}) {
|
|
@@ -217,7 +166,7 @@ function resolveHeyboxId(session) {
|
|
|
217
166
|
?.slice('heybox_id='.length);
|
|
218
167
|
}
|
|
219
168
|
function createHeyboxAuthHeaders(session, options = {}) {
|
|
220
|
-
const serviceTag = resolveHeyboxRylaiServiceTag(options.pathWithQuery);
|
|
169
|
+
const serviceTag = index.resolveHeyboxRylaiServiceTag(options.pathWithQuery);
|
|
221
170
|
return {
|
|
222
171
|
Cookie: session.cookieHeader,
|
|
223
172
|
Referer: HEYBOX_WEB_REFERER,
|
|
@@ -227,7 +176,7 @@ function createHeyboxAuthHeaders(session, options = {}) {
|
|
|
227
176
|
}
|
|
228
177
|
function createHeyboxRequestContext(session, options = {}) {
|
|
229
178
|
const heyboxId = resolveHeyboxId(session);
|
|
230
|
-
const serviceTag = resolveHeyboxRylaiServiceTag(options.pathWithQuery);
|
|
179
|
+
const serviceTag = index.resolveHeyboxRylaiServiceTag(options.pathWithQuery);
|
|
231
180
|
return {
|
|
232
181
|
baseUrl: HEYBOX_API_BASE_URL,
|
|
233
182
|
headers: createHeyboxAuthHeaders(session, options),
|
|
@@ -3372,6 +3321,7 @@ function isRecord(value) {
|
|
|
3372
3321
|
return Object.prototype.toString.call(value) === '[object Object]';
|
|
3373
3322
|
}
|
|
3374
3323
|
|
|
3324
|
+
exports.HEYBOX_WEB_REFERER = HEYBOX_WEB_REFERER;
|
|
3375
3325
|
exports.clearHeyboxAuthSession = clearHeyboxAuthSession;
|
|
3376
3326
|
exports.createHeyboxApiUrl = createHeyboxApiUrl;
|
|
3377
3327
|
exports.createHeyboxAuthSession = createHeyboxAuthSession;
|
package/dist/cli.cjs
CHANGED
|
@@ -212,6 +212,42 @@
|
|
|
212
212
|
overflow: auto;
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
.csp-violations {
|
|
216
|
+
border: 1px solid #dc2626;
|
|
217
|
+
border-radius: 8px;
|
|
218
|
+
padding: 12px;
|
|
219
|
+
color: #7f1d1d;
|
|
220
|
+
background: #fef2f2;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.csp-violations[hidden] {
|
|
224
|
+
display: none;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.csp-violations > strong {
|
|
228
|
+
display: block;
|
|
229
|
+
color: #991b1b;
|
|
230
|
+
font-size: 14px;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.csp-violations ol {
|
|
234
|
+
display: grid;
|
|
235
|
+
gap: 8px;
|
|
236
|
+
margin: 8px 0 0;
|
|
237
|
+
padding-left: 20px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.csp-violations li strong,
|
|
241
|
+
.csp-violations li span {
|
|
242
|
+
display: block;
|
|
243
|
+
overflow-wrap: anywhere;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.csp-violations li span {
|
|
247
|
+
margin-top: 2px;
|
|
248
|
+
font-size: 12px;
|
|
249
|
+
}
|
|
250
|
+
|
|
215
251
|
.log {
|
|
216
252
|
border: 1px solid #d7dee8;
|
|
217
253
|
border-radius: 8px;
|
|
@@ -317,6 +353,10 @@
|
|
|
317
353
|
<strong id="mini-url"></strong>
|
|
318
354
|
</section>
|
|
319
355
|
|
|
356
|
+
<section class="csp-violations" id="csp-violations" hidden>
|
|
357
|
+
<strong>网络或资源请求已被 CSP 阻止</strong>
|
|
358
|
+
</section>
|
|
359
|
+
|
|
320
360
|
<section class="block">
|
|
321
361
|
<span>Mac App</span>
|
|
322
362
|
<div class="actions" style="margin-top: 10px">
|
|
@@ -4,6 +4,8 @@ const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
|
|
|
4
4
|
const MINI_PROGRAM_MESSAGE_VERSION = 1;
|
|
5
5
|
/** 父容器注入到小程序 URL 上的通信 nonce 参数名。 */
|
|
6
6
|
const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
|
|
7
|
+
/** SDK 向 Runtime 报告 CSP 违规的内部方法名。 */
|
|
8
|
+
const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* 登录授权能力方法名。
|
|
@@ -3373,6 +3375,76 @@ function requireBrowser () {
|
|
|
3373
3375
|
|
|
3374
3376
|
var browserExports = requireBrowser();
|
|
3375
3377
|
|
|
3378
|
+
function createCSPViolationPanel(container) {
|
|
3379
|
+
const seen = new Set();
|
|
3380
|
+
const list = document.createElement('ol');
|
|
3381
|
+
container.setAttribute('role', 'alert');
|
|
3382
|
+
container.setAttribute('aria-live', 'assertive');
|
|
3383
|
+
container.appendChild(list);
|
|
3384
|
+
return {
|
|
3385
|
+
report(payload) {
|
|
3386
|
+
if (!isCSPViolationPayload(payload)) {
|
|
3387
|
+
return false;
|
|
3388
|
+
}
|
|
3389
|
+
const key = createViolationKey(payload);
|
|
3390
|
+
if (seen.has(key)) {
|
|
3391
|
+
return false;
|
|
3392
|
+
}
|
|
3393
|
+
seen.add(key);
|
|
3394
|
+
const item = document.createElement('li');
|
|
3395
|
+
const directive = document.createElement('strong');
|
|
3396
|
+
directive.textContent = payload.effectiveDirective;
|
|
3397
|
+
const detail = document.createElement('span');
|
|
3398
|
+
detail.textContent = formatBlockedResource(payload);
|
|
3399
|
+
item.append(directive, detail);
|
|
3400
|
+
list.appendChild(item);
|
|
3401
|
+
container.hidden = false;
|
|
3402
|
+
return true;
|
|
3403
|
+
},
|
|
3404
|
+
};
|
|
3405
|
+
}
|
|
3406
|
+
function isCSPViolationPayload(payload) {
|
|
3407
|
+
if (!payload || typeof payload !== 'object') {
|
|
3408
|
+
return false;
|
|
3409
|
+
}
|
|
3410
|
+
const candidate = payload;
|
|
3411
|
+
return (typeof candidate.effectiveDirective === 'string' &&
|
|
3412
|
+
typeof candidate.violatedDirective === 'string' &&
|
|
3413
|
+
typeof candidate.disposition === 'string' &&
|
|
3414
|
+
['url', 'inline', 'eval', 'unknown'].includes(candidate.blockedResourceType ?? '') &&
|
|
3415
|
+
typeof candidate.sdkVersion === 'string' &&
|
|
3416
|
+
typeof candidate.timestamp === 'number' &&
|
|
3417
|
+
isOptionalString(candidate.blockedOrigin) &&
|
|
3418
|
+
isOptionalString(candidate.redactedPathname) &&
|
|
3419
|
+
isOptionalString(candidate.sanitizedPathnameHash));
|
|
3420
|
+
}
|
|
3421
|
+
function isOptionalString(value) {
|
|
3422
|
+
return value === undefined || typeof value === 'string';
|
|
3423
|
+
}
|
|
3424
|
+
function createViolationKey(payload) {
|
|
3425
|
+
return [
|
|
3426
|
+
payload.effectiveDirective,
|
|
3427
|
+
payload.violatedDirective,
|
|
3428
|
+
payload.disposition,
|
|
3429
|
+
payload.blockedResourceType,
|
|
3430
|
+
payload.blockedOrigin,
|
|
3431
|
+
payload.redactedPathname,
|
|
3432
|
+
payload.sanitizedPathnameHash,
|
|
3433
|
+
].join('\n');
|
|
3434
|
+
}
|
|
3435
|
+
function formatBlockedResource(payload) {
|
|
3436
|
+
if (payload.blockedResourceType === 'url') {
|
|
3437
|
+
return `${payload.blockedOrigin ?? '未知来源'}${payload.redactedPathname ?? ''}`;
|
|
3438
|
+
}
|
|
3439
|
+
if (payload.blockedResourceType === 'inline') {
|
|
3440
|
+
return '内联资源';
|
|
3441
|
+
}
|
|
3442
|
+
if (payload.blockedResourceType === 'eval') {
|
|
3443
|
+
return '动态代码执行';
|
|
3444
|
+
}
|
|
3445
|
+
return '未知资源';
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3376
3448
|
async function getMiniProgramRuntimeUserInfo(platformAdapter) {
|
|
3377
3449
|
const userId = await resolveCurrentUserId(platformAdapter);
|
|
3378
3450
|
if (!userId) {
|
|
@@ -6211,6 +6283,7 @@ function isPlainRecord(value) {
|
|
|
6211
6283
|
|
|
6212
6284
|
const NETWORK_PROXY_PATH = '/__hb_sdk_mock_network__';
|
|
6213
6285
|
const MOCK_HOST_BOOTSTRAP_PATH = '/__hb_sdk_bootstrap__';
|
|
6286
|
+
const RUNTIME_GATE_PROBE_METHOD = 'runtime.gate.probe';
|
|
6214
6287
|
const params = new URL(location.href).searchParams;
|
|
6215
6288
|
const miniUrl = params.get('mini_url');
|
|
6216
6289
|
let lanAddresses = [];
|
|
@@ -6230,6 +6303,7 @@ let currentUser = {
|
|
|
6230
6303
|
const elements = {
|
|
6231
6304
|
bridgeStatus: queryElement('#bridge-status'),
|
|
6232
6305
|
copyDebugPageUrlButton: queryElement('#copy-debug-page-url-button'),
|
|
6306
|
+
cspViolations: queryElement('#csp-violations'),
|
|
6233
6307
|
debugPageCopyStatus: queryElement('#debug-page-copy-status'),
|
|
6234
6308
|
debugPageUrl: queryElement('#debug-page-url'),
|
|
6235
6309
|
device: queryElement('#device'),
|
|
@@ -6244,6 +6318,7 @@ const elements = {
|
|
|
6244
6318
|
storageSnapshot: queryElement('#storage-snapshot'),
|
|
6245
6319
|
userStatus: queryElement('#user-status'),
|
|
6246
6320
|
};
|
|
6321
|
+
const cspViolationPanel = createCSPViolationPanel(elements.cspViolations);
|
|
6247
6322
|
if (!miniUrl) {
|
|
6248
6323
|
elements.device.innerHTML = '<div class="error">Missing mini_url query.</div>';
|
|
6249
6324
|
throw new Error('Missing mini_url query.');
|
|
@@ -6323,6 +6398,12 @@ function handleMessage(event) {
|
|
|
6323
6398
|
}
|
|
6324
6399
|
if (message.type === 'request') {
|
|
6325
6400
|
void handleRequest(message);
|
|
6401
|
+
return;
|
|
6402
|
+
}
|
|
6403
|
+
if (message.type === 'event' && message.method === SDK_CSP_VIOLATION_METHOD) {
|
|
6404
|
+
if (cspViolationPanel.report(message.payload)) {
|
|
6405
|
+
pushLog(message.method, message.payload);
|
|
6406
|
+
}
|
|
6326
6407
|
}
|
|
6327
6408
|
}
|
|
6328
6409
|
function handleHandshake() {
|
|
@@ -6344,6 +6425,10 @@ async function handleRequest(message) {
|
|
|
6344
6425
|
if (!message.id || !message.method) {
|
|
6345
6426
|
return;
|
|
6346
6427
|
}
|
|
6428
|
+
if (!handshaken && message.method === RUNTIME_GATE_PROBE_METHOD) {
|
|
6429
|
+
postResponse(message, { ready: true });
|
|
6430
|
+
return;
|
|
6431
|
+
}
|
|
6347
6432
|
try {
|
|
6348
6433
|
const payload = await runtime.runMethod(message.method, message.payload);
|
|
6349
6434
|
postResponse(message, payload);
|