Files
Yuvomi-App/scripts/integration-server.mjs
T
Yuvomi Mobile Contributors 7ac9882307
Android validation / emulator (37.0) (push) Failing after 3s
Android validation / emulator (35) (push) Failing after 4s
iOS validation / simulator (push) Successful in 59s
Android validation / build (push) Successful in 5m30s
feat(android): align native preview with measured PWA design
2026-10-21 10:45:16 +02:00

65 lines
3.0 KiB
JavaScript

// Test-only reverse proxy around the unmodified pinned upstream application.
import fs from 'node:fs';
import http from 'node:http';
import https from 'node:https';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
import { randomBytes } from 'node:crypto';
import { once } from 'node:events';
import { startIdentityProvider } from './oidc-fixture.mjs';
const [upstream, directory] = process.argv.slice(2);
process.env.PORT = '0';
process.env.BIND_ADDRESS = '127.0.0.1';
process.env.DB_PATH = path.join(directory, 'fixture.db');
process.env.SESSION_SECRET = randomBytes(48).toString('hex');
// Exercise both explicit Secure cookies and upstream's default behind HTTPS.
const sessionSecure = process.env.YUVOMI_TEST_SESSION_SECURE ?? 'true';
if (!['true', 'false'].includes(sessionSecure)) throw new Error('Invalid fixture cookie mode');
process.env.SESSION_SECURE = sessionSecure;
process.env.DB_ENCRYPTION_KEY = '';
process.env.NODE_ENV = 'test';
process.env.LOG_LEVEL = 'warn';
const tls = { key: fs.readFileSync(path.join(directory, 'key.pem')), cert: fs.readFileSync(path.join(directory, 'cert.pem')) };
const idp = process.env.YUVOMI_TEST_DISABLE_OIDC === 'true' ? null : await startIdentityProvider(tls);
if (idp) {
process.env.OIDC_ISSUER = idp.issuer;
process.env.OIDC_CLIENT_ID = idp.clientId;
process.env.OIDC_CLIENT_SECRET = idp.secret;
} else {
delete process.env.OIDC_ISSUER;
delete process.env.OIDC_CLIENT_ID;
delete process.env.OIDC_CLIENT_SECRET;
}
const { server } = await import(pathToFileURL(path.join(upstream, 'server/index.js')));
if (!server.listening) await once(server, 'listening');
let networkAvailable = true;
const proxy = https.createServer(tls, (request, response) => {
// Fault injection lives only in this loopback fixture, never in upstream/app code.
if (request.method === 'POST' && ['/__mobile_test/network/off', '/__mobile_test/network/on'].includes(request.url)) {
networkAvailable = request.url.endsWith('/on');
response.writeHead(200, { 'Content-Type': 'application/json' });
response.end('{}');
return;
}
if (!networkAvailable) { request.socket.destroy(); return; }
const backend = http.request({
hostname: '127.0.0.1', port: server.address().port,
method: request.method, path: request.url,
headers: { ...request.headers, 'x-forwarded-proto': 'https', 'x-forwarded-for': '127.0.0.1' },
}, incoming => {
response.writeHead(incoming.statusCode, incoming.headers);
incoming.pipe(response);
});
backend.on('error', () => { response.writeHead(502); response.end(); });
request.pipe(backend);
});
proxy.listen(0, '127.0.0.1');
await once(proxy, 'listening');
if (idp) {
process.env.OIDC_REDIRECT_URI = `https://127.0.0.1:${proxy.address().port}/api/v1/auth/oidc/callback`;
idp.setRedirect(process.env.OIDC_REDIRECT_URI);
}
fs.writeFileSync(path.join(directory, 'ready.json'), JSON.stringify({ port: proxy.address().port, idpPort: idp?.port ?? null }));
process.on('SIGTERM', () => { idp?.close(); proxy.close(); server.close(); process.exit(0); });