81 lines
2.1 KiB
JavaScript
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],
|
|
});
|