forked from wangziqi/gongxue-base
fix: normalize PNVS SMS provider aliases
This commit is contained in:
@@ -55,10 +55,8 @@ const DEFAULT_MAX_IMPORT_JSON_BODY_BYTES = 10 * 1024 * 1024;
|
||||
const HARD_MAX_JSON_BODY_BYTES = 50 * 1024 * 1024;
|
||||
const PRODUCTION_SMS_PROVIDERS = new Set([
|
||||
'aliyun-pnvs',
|
||||
'aliyun_pnvs',
|
||||
'aliyun-pnvs-sms',
|
||||
'aliyun-sms-auth',
|
||||
'aliyun_sms_auth',
|
||||
]);
|
||||
const PRODUCTION_STORAGE_PROVIDERS = new Set(['aliyun_oss', 'tencent_cos', 'supabase_storage']);
|
||||
|
||||
@@ -107,7 +105,7 @@ function validateProductionConfig(nextConfig: ApiConfig) {
|
||||
|
||||
const failures: string[] = [];
|
||||
if (nextConfig.corsOrigins.includes('*')) failures.push('CORS_ORIGIN must not include * in production');
|
||||
if (!PRODUCTION_SMS_PROVIDERS.has(nextConfig.authSmsProvider.trim().toLowerCase())) {
|
||||
if (!PRODUCTION_SMS_PROVIDERS.has(nextConfig.authSmsProvider.trim().toLowerCase().replace(/[_\s]/g, '-'))) {
|
||||
failures.push('AUTH_SMS_PROVIDER must be aliyun-pnvs in production');
|
||||
}
|
||||
if (isUnsafeSecret(nextConfig.authCodePepper, DEFAULT_AUTH_CODE_PEPPER)) {
|
||||
|
||||
@@ -208,7 +208,7 @@ async function consumeSmsCode(
|
||||
}
|
||||
|
||||
function normalizeSmsProviderName(value: string) {
|
||||
const normalized = value.toLowerCase().replace(/_/g, '-');
|
||||
const normalized = value.toLowerCase().replace(/[_\s]/g, '-');
|
||||
if (normalized === 'aliyun-pnvs' || normalized === 'aliyun-pnvs-sms' || normalized === 'aliyun-sms-auth') return 'aliyun-pnvs';
|
||||
if (normalized === 'aliyun' || normalized === 'aliyun-sms') return 'aliyun';
|
||||
if (normalized === 'tencent' || normalized === 'tencent-sms') return 'tencent';
|
||||
|
||||
@@ -19,6 +19,7 @@ assert.match(providerSource, /CheckSmsVerifyCode/, 'PNVS provider should call Ch
|
||||
assert.match(providerSource, /VerifyResult.*PASS/s, 'PNVS verify should require provider PASS result');
|
||||
assert.match(providerSource, /##code##/, 'PNVS provider should preserve Aliyun-generated code placeholder');
|
||||
assert.match(routeSource, /aliyun-pnvs/, 'auth routes should recognize aliyun-pnvs aliases');
|
||||
assert.match(routeSource, /replace\(\s*\/\[_\\s\]\/g,\s*'-'\s*\)/, 'auth routes should normalize underscore PNVS provider aliases before runtime selection');
|
||||
assert.match(routeSource, /verification.*provider/s, 'auth routes should store provider verification mode');
|
||||
assert.match(routeSource, /provider\.verify/, 'auth routes should delegate PNVS verification to provider');
|
||||
assert.match(routeSource, /export async function bindPhoneRoute[\s\S]*activeSmsProvider[\s\S]*consumeSmsCode/, 'phone binding should reuse active SMS provider verification');
|
||||
|
||||
@@ -120,6 +120,12 @@ assert.match(
|
||||
const safeApi = runImport(apiConfigUrl, safeApiEnv);
|
||||
assert.equal(safeApi.status, 0, `safe production API config should load: ${safeApi.output}`);
|
||||
|
||||
const safeApiUnderscorePnvsAlias = runImport(apiConfigUrl, {
|
||||
...safeApiEnv,
|
||||
AUTH_SMS_PROVIDER: 'aliyun_pnvs',
|
||||
});
|
||||
assert.equal(safeApiUnderscorePnvsAlias.status, 0, `underscore PNVS alias should load in production API config: ${safeApiUnderscorePnvsAlias.output}`);
|
||||
|
||||
const unsafeWorker = runImport(workerConfigUrl, {
|
||||
...safeBaseEnv,
|
||||
STORAGE_DEFAULT_PROVIDER: 'local_dev',
|
||||
|
||||
@@ -196,6 +196,34 @@ 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
|
||||
`);
|
||||
|
||||
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');
|
||||
|
||||
const pnvsTemplateParamWarning = runReadiness(
|
||||
`
|
||||
NODE_ENV=production
|
||||
|
||||
@@ -12,10 +12,8 @@ const DEFAULT_PLATFORM_ADMIN_API_KEY = 'local-platform-admin-key';
|
||||
const HARD_MAX_JSON_BODY_BYTES = 50 * 1024 * 1024;
|
||||
const PRODUCTION_SMS_PROVIDERS = new Set([
|
||||
'aliyun-pnvs',
|
||||
'aliyun_pnvs',
|
||||
'aliyun-pnvs-sms',
|
||||
'aliyun-sms-auth',
|
||||
'aliyun_sms_auth',
|
||||
]);
|
||||
const PRODUCTION_STORAGE_PROVIDERS = new Set(['aliyun_oss', 'tencent_cos', 'supabase_storage']);
|
||||
const AUTH_PROVIDER_ALIASES = {
|
||||
@@ -567,7 +565,7 @@ function validateEnv() {
|
||||
}
|
||||
}
|
||||
|
||||
const authSmsProvider = env('AUTH_SMS_PROVIDER', 'mock').trim().toLowerCase();
|
||||
const authSmsProvider = normalizeProvider(env('AUTH_SMS_PROVIDER', 'mock')).replace(/[_\s]/g, '-');
|
||||
if (!PRODUCTION_SMS_PROVIDERS.has(authSmsProvider)) {
|
||||
block('env.auth_sms_provider', 'AUTH_SMS_PROVIDER must be aliyun-pnvs in production', {
|
||||
provider: authSmsProvider || '(empty)',
|
||||
|
||||
Reference in New Issue
Block a user