Files
gongxue-base/scripts/production-readiness-check-test.js

520 lines
22 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { spawnSync } from 'node:child_process';
const repoRoot = process.cwd();
const scriptPath = path.join(repoRoot, 'scripts', 'production-readiness-check.js');
function runReadiness(envContent, options = {}) {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tiku-readiness-'));
const envFile = path.join(tempDir, '.env');
fs.writeFileSync(envFile, envContent, 'utf8');
const args = [scriptPath, '--env-file', envFile, '--skip-db', '--json'];
if (options.providerRows) {
const fixtureFile = path.join(tempDir, 'provider-fixture.json');
fs.writeFileSync(fixtureFile, JSON.stringify({ rows: options.providerRows }, null, 2), 'utf8');
args.push('--provider-config-fixture', fixtureFile);
}
const result = spawnSync(process.execPath, args, {
cwd: repoRoot,
encoding: 'utf8',
env: {
PATH: process.env.PATH || '',
Path: process.env.Path || '',
SystemRoot: process.env.SystemRoot || '',
ComSpec: process.env.ComSpec || '',
TEMP: process.env.TEMP || os.tmpdir(),
TMP: process.env.TMP || os.tmpdir(),
},
});
const payload = JSON.parse(result.stdout || '{}');
fs.rmSync(tempDir, { recursive: true, force: true });
return { ...result, payload };
}
const unsafe = runReadiness(`
NODE_ENV=development
DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
AUTH_SMS_PROVIDER=mock
`);
assert.notEqual(unsafe.status, 0, 'unsafe production readiness should fail');
assert.ok(unsafe.payload.summary?.blocker > 0, 'unsafe readiness should report blockers');
assert.ok(
unsafe.payload.checks?.some(item => item.id === 'env.node_env' && item.status === 'blocker'),
'unsafe readiness should block non-production NODE_ENV',
);
assert.ok(
unsafe.payload.checks?.some(item => item.id === 'env.auth_sms_provider' && item.status === 'blocker'),
'unsafe readiness should block mock SMS provider',
);
const unsupportedSmsProvider = runReadiness(`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-production
AUTH_CODE_PEPPER=s3cure-prod-code-pepper-2026-06-29-abcdef
AUTH_SESSION_SECRET=s3cure-prod-session-secret-2026-06-29-ghijkl
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=s3cure-platform-admin-key-2026-06-29-mnopqr
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
`);
assert.notEqual(unsupportedSmsProvider.status, 0, 'unsupported production SMS provider readiness should fail');
assert.ok(
unsupportedSmsProvider.payload.checks?.some(item => item.id === 'env.auth_sms_provider' && item.status === 'blocker'),
'readiness should block unsupported AUTH_SMS_PROVIDER values',
);
const traditionalAliyunSmsProvider = runReadiness(`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com
AUTH_SMS_PROVIDER=aliyun
AUTH_CODE_PEPPER=s3cure-prod-code-pepper-2026-06-29-abcdef
AUTH_SESSION_SECRET=s3cure-prod-session-secret-2026-06-29-ghijkl
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=s3cure-platform-admin-key-2026-06-29-mnopqr
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
`);
assert.notEqual(traditionalAliyunSmsProvider.status, 0, 'traditional Aliyun SMS provider readiness should fail in production');
assert.ok(
traditionalAliyunSmsProvider.payload.checks?.some(item => item.id === 'env.auth_sms_provider' && item.status === 'blocker'),
'readiness should require PNVS instead of traditional Aliyun SMS',
);
const strongSecretA = 's3cure-prod-code-pepper-2026-06-29-abcdef';
const strongSecretB = 's3cure-prod-session-secret-2026-06-29-ghijkl';
const strongSecretC = 's3cure-platform-admin-key-2026-06-29-mnopqr';
const safe = runReadiness(`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com,https://tenant-admin.gongxue100.com,https://platform-admin.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
MAX_JSON_BODY_BYTES=1048576
MAX_IMPORT_JSON_BODY_BYTES=10485760
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
STORAGE_ALLOWED_MIME_TYPES=application/pdf,image/png,image/jpeg,video/mp4,text/plain,text/csv
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_HTTP_TIMEOUT_MS=10000
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
WORKER_CRM_ALLOW_INSECURE_LOCALHOST=false
WORKER_PLATFORM_AUDIT_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=false
WORKER_PLATFORM_DUNNING_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=false
WORKER_CRM_BATCH_SIZE=20
WORKER_COMMERCE_BATCH_SIZE=20
WORKER_ASSET_BATCH_SIZE=50
WORKER_IMPORT_BATCH_SIZE=5
WORKER_PUBLIC_BANK_SYNC_BATCH_SIZE=5
`);
assert.equal(safe.status, 0, `safe readiness should pass without blockers: ${safe.stdout} ${safe.stderr}`);
assert.equal(safe.payload.summary?.blocker, 0, 'safe readiness should have no blockers');
assert.ok(
safe.payload.checks?.some(item => item.id === 'db.skipped' && item.status === 'warn'),
'env-only readiness should explicitly warn that DB checks are skipped',
);
const safeAliyunPnvs = runReadiness(`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com,https://tenant-admin.gongxue100.com,https://platform-admin.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
WORKER_CRM_BATCH_SIZE=20
WORKER_COMMERCE_BATCH_SIZE=20
WORKER_ASSET_BATCH_SIZE=50
WORKER_IMPORT_BATCH_SIZE=5
WORKER_PUBLIC_BANK_SYNC_BATCH_SIZE=5
`);
assert.equal(safeAliyunPnvs.status, 0, `aliyun-pnvs readiness should pass without blockers: ${safeAliyunPnvs.stdout} ${safeAliyunPnvs.stderr}`);
assert.equal(safeAliyunPnvs.payload.summary?.blocker, 0, 'aliyun-pnvs readiness should have no blockers');
const safeAliyunPnvsUnderscoreAlias = runReadiness(`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com,https://tenant-admin.gongxue100.com,https://platform-admin.gongxue100.com
AUTH_SMS_PROVIDER=aliyun_pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
`, {
providerRows: [
{
source: 'auth',
tenantId: 'tenant-pnvs',
provider: 'aliyun-pnvs',
configPublic: {
signName: '短信签名',
templateCode: 'SMS_123456789',
endpoint: 'https://dypnsapi.aliyuncs.com',
templateParam: { code: '##code##', min: '5' },
},
},
],
});
assert.equal(safeAliyunPnvsUnderscoreAlias.status, 0, `aliyun_pnvs readiness should pass without blockers: ${safeAliyunPnvsUnderscoreAlias.stdout} ${safeAliyunPnvsUnderscoreAlias.stderr}`);
assert.equal(safeAliyunPnvsUnderscoreAlias.payload.summary?.blocker, 0, 'aliyun_pnvs readiness should have no blockers');
assert.ok(
safeAliyunPnvsUnderscoreAlias.payload.checks?.some(item => item.id === 'db.auth_sms_provider_configured' && item.status === 'pass'),
'aliyun_pnvs readiness should still validate matching PNVS provider rows',
);
const pnvsTemplateParamWarning = runReadiness(
`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com,https://tenant-admin.gongxue100.com,https://platform-admin.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
`,
{
providerRows: [
{
source: 'auth',
tenantId: 'tenant-pnvs',
provider: 'aliyun-pnvs',
configPublic: {
signName: '短信签名',
templateCode: 'SMS_123456789',
endpoint: 'https://dypnsapi.aliyuncs.com',
templateParam: { min: '5' },
},
},
],
},
);
assert.equal(pnvsTemplateParamWarning.status, 0, 'PNVS templateParam warning should not block readiness');
assert.ok(
pnvsTemplateParamWarning.payload.checks?.some(item => item.id === 'db.auth.aliyun-pnvs.template_param' && item.status === 'warn'),
'readiness should warn when PNVS templateParam lacks ##code##',
);
assert.ok(
pnvsTemplateParamWarning.payload.checks?.some(item => item.id === 'db.auth_sms_provider_configured' && item.status === 'pass'),
'readiness should pass when AUTH_SMS_PROVIDER has a matching PNVS provider row',
);
const mismatchedSmsProviderFixture = runReadiness(
`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com,https://tenant-admin.gongxue100.com,https://platform-admin.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
`,
{
providerRows: [
{
source: 'auth',
tenantId: 'tenant-aliyun',
provider: 'aliyun',
configPublic: {
signName: '短信签名',
templateCode: 'SMS_123456789',
endpoint: 'https://dysmsapi.aliyuncs.com',
},
},
],
},
);
assert.notEqual(mismatchedSmsProviderFixture.status, 0, 'readiness should fail when AUTH_SMS_PROVIDER has no matching active provider row');
assert.ok(
mismatchedSmsProviderFixture.payload.checks?.some(item => item.id === 'db.auth_sms_provider_configured' && item.status === 'blocker'),
'readiness should block env/provider mismatch',
);
const unsafeProviderFixture = runReadiness(
`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com,https://tenant-admin.gongxue100.com,https://platform-admin.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
`,
{
providerRows: [
{
source: 'auth',
tenantId: 'tenant-a',
provider: 'qq-oauth',
configPublic: {
appId: '101000000',
redirectUri: 'http://localhost:5173/auth/qq/callback',
},
},
{
source: 'payment',
tenantId: 'tenant-a',
provider: 'wechat_pay',
configPublic: {
appId: 'wx123',
merchantId: '1900000001',
merchantSerialNo: 'serial123',
},
},
{
source: 'payment',
tenantId: 'tenant-b',
provider: 'alipay',
configPublic: {
appId: '2021000000000000',
notifyUrl: 'http://pay.example.com/notify',
privateKey: 'should-not-be-public',
},
},
],
},
);
assert.notEqual(unsafeProviderFixture.status, 0, 'unsafe provider fixture readiness should fail');
assert.ok(
unsafeProviderFixture.payload.checks?.some(item => item.id === 'db.auth.qq-oauth.redirect_uri.unsafe' && item.status === 'blocker'),
'readiness should block unsafe QQ redirectUri',
);
assert.ok(
unsafeProviderFixture.payload.checks?.some(item => item.id === 'db.payment.wechat_pay.public_required' && item.status === 'blocker'),
'readiness should block missing WeChat Pay notifyUrl',
);
assert.ok(
unsafeProviderFixture.payload.checks?.some(item => item.id === 'db.payment.alipay.notify_url.unsafe' && item.status === 'blocker'),
'readiness should block unsafe Alipay notifyUrl',
);
assert.ok(
unsafeProviderFixture.payload.checks?.some(item => item.id === 'db.payment.alipay.public_secret' && item.status === 'blocker'),
'readiness should block secret-like public payment config keys',
);
const missingJwksIssuer = runReadiness(`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
WORKER_PLATFORM_AUDIT_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=false
WORKER_PLATFORM_DUNNING_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=false
`);
assert.notEqual(missingJwksIssuer.status, 0, 'JWKS readiness without issuer should fail');
assert.ok(
missingJwksIssuer.payload.checks?.some(item => item.id === 'env.auth_jwt_issuer' && item.status === 'blocker'),
'JWKS readiness should block missing AUTH_JWT_ISSUER',
);
const unsafePlatformAuditNotificationLocalhost = runReadiness(`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
WORKER_PLATFORM_AUDIT_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=true
`);
assert.notEqual(unsafePlatformAuditNotificationLocalhost.status, 0, 'platform audit notification localhost readiness should fail');
assert.ok(
unsafePlatformAuditNotificationLocalhost.payload.checks?.some(item => item.id === 'env.worker_platform_audit_notification_insecure_localhost' && item.status === 'blocker'),
'readiness should block platform audit notification localhost mode in production',
);
const unsafePlatformDunningNotificationLocalhost = runReadiness(`
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:prod_password@db.prod.internal:5432/tiku
CORS_ORIGIN=https://student.gongxue100.com
AUTH_SMS_PROVIDER=aliyun-pnvs
AUTH_CODE_PEPPER=${strongSecretA}
AUTH_SESSION_SECRET=${strongSecretB}
AUTH_JWT_JWKS_URL=https://auth.gongxue100.com/auth/v1/.well-known/jwks.json
AUTH_JWT_ISSUER=https://auth.gongxue100.com/auth/v1
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
PLATFORM_ADMIN_API_KEY=${strongSecretC}
STORAGE_DEFAULT_PROVIDER=aliyun_oss
STORAGE_DEFAULT_BUCKET=tiku-assets
STORAGE_REQUIRE_TENANT_PREFIX=true
ALIYUN_OSS_REGION=cn-hangzhou
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_ACCESS_KEY_ID=LTAI_READINESS_TEST_ONLY
ALIYUN_OSS_ACCESS_KEY_SECRET=aliyun-readiness-secret-placeholder
WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=https://scanner.gongxue100.com/api/scan
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=s3cure-asset-scanner-token-2026-06-29-stuvwx
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
WORKER_PLATFORM_AUDIT_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=false
WORKER_PLATFORM_DUNNING_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=true
`);
assert.notEqual(unsafePlatformDunningNotificationLocalhost.status, 0, 'platform dunning notification localhost readiness should fail');
assert.ok(
unsafePlatformDunningNotificationLocalhost.payload.checks?.some(item => item.id === 'env.worker_platform_dunning_notification_insecure_localhost' && item.status === 'blocker'),
'readiness should block platform dunning notification localhost mode in production',
);
console.log('[PASS] production readiness check script');