'use strict'; const assert = require('assert'); const fs = require('fs'); const path = require('path'); const vm = require('vm'); const db = require('../src/core/database'); const accountsRouter = require('../src/routes/accounts'); function routeHandler(routePath) { const layer = accountsRouter.stack.find(item => ( item.route && item.route.path === routePath && item.route.methods.get )); assert(layer, `未找到 GET ${routePath}`); return layer.route.stack[0].handle; } function invoke(handler, params = {}, remoteAddress = '127.0.0.1') { const response = { statusCode: 200, headers: {}, body: null, status(code) { this.statusCode = code; return this; }, set(name, value) { this.headers[String(name).toLowerCase()] = value; return this; }, json(body) { this.body = body; return this; }, }; handler({ params, socket: { remoteAddress } }, response); return response; } (async () => { const originalGetAccount = db.getAccount; const originalGetAllAccounts = db.getAllAccounts; const originalGetStagingBatch = db.getStagingBatch; try { const session = { user: { email: 'session@example.com' }, expires: '2099-01-01T00:00:00.000Z', accessToken: 'test-token', }; const account = { email: 'session@example.com', chatgpt_status: '已登录', chatgpt_session: JSON.stringify(session), }; db.getAccount = () => account; db.getAllAccounts = () => [account]; const listResponse = invoke(routeHandler('/')); assert.strictEqual(listResponse.statusCode, 200); assert.strictEqual(listResponse.body.data[0].chatgpt_session, undefined, '账号列表不得返回 Session'); const sessionResponse = invoke(routeHandler('/:email/chatgpt-session'), { email: encodeURIComponent(account.email), }); assert.strictEqual(sessionResponse.statusCode, 200); assert.strictEqual(sessionResponse.headers['cache-control'], 'no-store'); assert.deepStrictEqual(sessionResponse.body.data, session); const remoteSessionResponse = invoke(routeHandler('/:email/chatgpt-session'), { email: encodeURIComponent(account.email), }, '192.0.2.10'); assert.strictEqual(remoteSessionResponse.statusCode, 403); assert.strictEqual(remoteSessionResponse.headers['cache-control'], 'no-store'); assert.strictEqual(JSON.stringify(remoteSessionResponse.body).includes('test-token'), false); db.getStagingBatch = () => ({ batch: { id: 1, selected_fields: JSON.stringify(['email', 'chatgpt_session']) }, accounts: [account], }); const stagedWithSession = invoke(routeHandler('/staging/:batchId'), { batchId: '1' }); assert.strictEqual(stagedWithSession.body.data.accounts[0].chatgpt_session, account.chatgpt_session); const remoteStagedWithSession = invoke( routeHandler('/staging/:batchId'), { batchId: '1' }, '192.0.2.10', ); assert.strictEqual(remoteStagedWithSession.statusCode, 403); assert.strictEqual(JSON.stringify(remoteStagedWithSession.body).includes('test-token'), false); db.getStagingBatch = () => ({ batch: { id: 2, selected_fields: JSON.stringify(['email']) }, accounts: [account], }); const stagedWithoutSession = invoke(routeHandler('/staging/:batchId'), { batchId: '2' }); assert.strictEqual(stagedWithoutSession.body.data.accounts[0].chatgpt_session, undefined); db.getAccount = () => ({ email: account.email, chatgpt_session: null }); const emptyResponse = invoke(routeHandler('/:email/chatgpt-session'), { email: encodeURIComponent(account.email), }); assert.strictEqual(emptyResponse.statusCode, 404); assert.match(emptyResponse.body.msg, /尚未保存/); const appSource = fs.readFileSync(path.join(__dirname, '..', 'public', 'app.js'), 'utf8'); let clipboardText = ''; const context = vm.createContext({ console, Set, Map, Date, JSON, Math, String, Object, Array, RegExp, setTimeout, clearTimeout, navigator: { clipboard: { writeText: async text => { clipboardText = text; }, }, }, fetch: async () => ({ ok: true, status: 200, json: async () => ({ success: true, data: session }), }), }); vm.runInContext(`${appSource}\nthis.__geminiApp = geminiApp;`, context, { filename: 'public/app.js' }); const app = context.__geminiApp(); await app.openChatgptSession(account); assert.strictEqual(app.showChatgptSessionModal, true); assert.strictEqual(app.chatgptSessionLoading, false); assert.strictEqual(JSON.parse(app.chatgptSessionText).user.email, account.email); await app.copyChatgptSession(); assert.strictEqual(clipboardText, app.chatgptSessionText); app._exportList = [{ email: account.email }]; Object.keys(app.exportFields).forEach(key => { app.exportFields[key] = false; }); app.exportFields.email = true; app.exportFields.chatgpt_session = true; app.exportMode = { file: false, clipboard: true, staging: false }; app.addLog = () => {}; await app.confirmExport(); assert.strictEqual(clipboardText, `${account.email}----${JSON.stringify(session)}`); console.log('chatgpt_session_access.test.js: PASS'); } finally { db.getAccount = originalGetAccount; db.getAllAccounts = originalGetAllAccounts; db.getStagingBatch = originalGetStagingBatch; } })().catch(error => { console.error(error); process.exitCode = 1; });