'use strict'; const { test } = require('node:test'), assert = require('node:assert/strict'), path = require('node:path'); const config = require('../../h5/lib/entry-config'); test('rednote rejects missing, shared data paths and wrong public prefixes before initializing storage', () => { const root = path.resolve(__dirname, '../../h5'); assert.equal(config({}, root).mode, 'state'); const env = { JUZI_ENTRY_MODE: 'rednote', PUBLIC_BASE_URL: 'https://skin.example.test/rednote/' }; for (const dataRoot of [undefined, root, path.join(root, 'custom-data'), path.join(root, 'data'), path.join(root, 'data/subdir')]) { assert.throws(() => config({ ...env, JUZI_DATA_ROOT: dataRoot }, root), /own JUZI_DATA_ROOT/); } assert.throws(() => config({ ...env, JUZI_DATA_ROOT: path.join(root, '../temp/rednote'), PUBLIC_BASE_URL: 'https://skin.example.test/state/' }, root), /rednote/); assert.equal(config({ ...env, JUZI_DATA_ROOT: path.join(root, '../temp/rednote') }, root).channel, 'rednote'); assert.throws(() => config({ ...env, JUZI_DATA_ROOT: path.join(root, '../temp/original'), JUZI_PROTECTED_DATA_ROOT: path.join(root, '../temp/original') }, root), /own JUZI_DATA_ROOT/); assert.throws(() => config({ ...env, JUZI_DATA_ROOT: path.join(root, '../temp/rednote'), NODE_ENV: 'production', PUBLIC_BASE_URL: 'http://skin.example.test/rednote/' }, root), /rednote/); }); test('HTTPS browser cookies are secure and persistent, even when WeChat credentials exist', async () => { const fs = require('node:fs'), os = require('node:os'), { Readable } = require('node:stream'); const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'juzi-rednote-secure-')); try { const accounts = require('../../h5/lib/accounts')(dir, { JUZI_ENTRY_MODE: 'rednote', PUBLIC_BASE_URL: 'https://skin.example.test/rednote/', WECHAT_APP_ID: 'configured', WECHAT_APP_SECRET: 'fixture' }); assert.equal(accounts.wechatAvailable, false); const headers = {}; const req = Readable.from([Buffer.from('{"consent":true}')]); req.method = 'POST'; req.url = '/api/auth/browser'; req.headers = { host: 'skin.example.test', origin: 'https://skin.example.test' }; req.socket = { remoteAddress: '127.0.0.1' }; let response; await accounts.route(req, { setHeader: (k, v) => { headers[k] = v; }, getHeader: k => headers[k], writeHead() {}, end: text => { response = JSON.parse(text); } }, '/api/auth/browser'); assert.match(headers['Set-Cookie'][0], /HttpOnly; SameSite=Lax; Max-Age=2592000; Secure$/); assert.equal(response.user.kind, 'browser_persistent'); } finally { fs.rmSync(dir, { recursive: true, force: true }); } }); test('data-directory aliases cannot bypass protection of the original deployment', () => { const fs = require('node:fs'), os = require('node:os'); const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'juzi-rednote-path-')); try { const original = path.join(dir, 'original'), alias = path.join(dir, 'alias'); fs.mkdirSync(original); fs.symlinkSync(original, alias, process.platform === 'win32' ? 'junction' : 'dir'); assert.throws(() => config({ JUZI_ENTRY_MODE: 'rednote', PUBLIC_BASE_URL: 'https://skin.example.test/rednote/', JUZI_DATA_ROOT: path.join(alias, 'nested'), JUZI_PROTECTED_DATA_ROOT: original }, path.join(dir, 'h5')), /own JUZI_DATA_ROOT/); } finally { fs.rmSync(dir, { recursive: true, force: true }); } }); test('new-channel provider requests serialize through body consumption and cap the queue', async () => { let active = 0, peak = 0; const gated = require('../../h5/lib/provider-gate')(async () => { peak = Math.max(peak, ++active); return { ok: true, status: 200, json: async () => { await new Promise(resolve => setTimeout(resolve, 10)); active--; return { ok: true }; } }; }, 2); const a = gated('fixture'), b = gated('fixture'); await assert.rejects(gated('fixture'), /queue is full/); assert.deepEqual(await (await a).json(), { ok: true }); await b; assert.equal(peak, 1); assert.equal(active, 0); });