Files
john b1577a16e9
Memind CI / Test, build, and release guards (push) Failing after 12m3s
fix: harden release gate and page delivery
2026-07-26 14:32:01 +08:00

81 lines
2.1 KiB
JavaScript

const FORBIDDEN_HOSTS = new Set([
'58.38.22.103',
'm.tkmind.cn',
'plaza.tkmind.cn',
]);
const TARGET_ENV_KEYS = [
'STUDIO_HOST',
'STUDIO_HEALTH_URL',
'H5_PUBLIC_BASE_URL',
'MINDSPACE_BASE_URL',
'DATABASE_URL',
'MINDSPACE_USERDATA_PG_URL',
'MYSQL_HOST',
'PGHOST',
'REDIS_URL',
'SEARXNG_URL',
'DEEP_SEARCH_URL',
];
function extractHostname(value) {
const text = String(value ?? '').trim();
if (!text) return '';
try {
return new URL(text.includes('://') ? text : `tcp://${text}`).hostname.toLowerCase();
} catch {
return text.split('/')[0].split(':')[0].toLowerCase();
}
}
export function isProductionTarget(value) {
const text = String(value ?? '').toLowerCase();
const hostname = extractHostname(text);
return FORBIDDEN_HOSTS.has(hostname)
|| hostname.endsWith('.tkmind.cn')
|| text.includes('58.38.22.103')
|| text.includes('/users/john/project/memind');
}
export function assertNonProductionTarget(value, label = 'target') {
if (isProductionTarget(value)) {
throw new Error(`Release gate refused production ${label}`);
}
}
export function assertSafePortalBase(portalBase) {
assertNonProductionTarget(portalBase, 'Portal base URL');
const parsed = new URL(portalBase);
if (!['127.0.0.1', 'localhost', '::1', '[::1]'].includes(parsed.hostname)) {
throw new Error('Release gate Portal base must use an isolated loopback host');
}
return parsed.toString().replace(/\/$/, '');
}
export function assertSafeGateEnvironment({
env = process.env,
targets = [],
} = {}) {
const unsafeKeys = [];
for (const key of TARGET_ENV_KEYS) {
if (env[key] && isProductionTarget(env[key])) {
unsafeKeys.push(key);
}
}
for (const [index, target] of targets.entries()) {
if (target && isProductionTarget(target)) {
unsafeKeys.push(`target[${index}]`);
}
}
if (unsafeKeys.length) {
throw new Error(
`Release gate refused production-linked configuration: ${unsafeKeys.join(', ')}`,
);
}
}
export const productionTargetPolicy = Object.freeze({
forbiddenHosts: [...FORBIDDEN_HOSTS],
inspectedEnvironmentKeys: [...TARGET_ENV_KEYS],
});