fix: validate PNVS provider rows for alias env

This commit is contained in:
Codex
2026-07-04 00:32:31 +08:00
parent 3a10daf847
commit ae491f592b
4 changed files with 28 additions and 6 deletions

View File

@@ -154,7 +154,7 @@ Taro H5 构建存在 webpack asset size warning这是前端包体优化事项
- 生产 API 已能启动,`https://api.tjszsb.com/api/tenant/resolve?host=app.tjszsb.com` 已返回 `master` 租户。
- Supabase self-hosted 运行在 `/opt/tiku-saas/supabase-project`Kong 通过 Nginx 暴露到 `https://supabase.tjszsb.com`
- 线上 H5 公开配置文件在 `/srv/tiku-saas/www/*/runtime-config.json`,密钥只允许放 `supabasePublishableKey` 这类公开 key。
- 短信登录推荐生产使用 `AUTH_SMS_PROVIDER=aliyun-pnvs`。阿里云 AccessKey/Secret 只写入 `app_private.tenant_secrets(secret_scope='sms', secret_key='aliyun-pnvs')`,不要写进 `/etc/tiku-saas/api.env` 或 H5 `runtime-config.json`
- 短信验证码登录生产必须使用 `AUTH_SMS_PROVIDER=aliyun-pnvs`。阿里云 AccessKey/Secret 只写入 `app_private.tenant_secrets(secret_scope='sms', secret_key='aliyun-pnvs')`,不要写进 `/etc/tiku-saas/api.env` 或 H5 `runtime-config.json`
配置 PNVS provider 推荐用仓库脚本写入数据库,避免手写 SQL 时把密钥打进命令历史。生产环境建议临时关闭 shell history再用 `read -s` 输入 AccessKeySecret

View File

@@ -219,10 +219,28 @@ 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(
`

View File

@@ -160,19 +160,23 @@ function normalizeProvider(value) {
return String(value || '').trim().toLowerCase();
}
function normalizeSmsProvider(value) {
return normalizeProvider(value).replace(/[_\s]/g, '-');
}
function providerIn(provider, aliases) {
return aliases.has(normalizeProvider(provider));
}
function currentSmsProviderAliases() {
const provider = normalizeProvider(env('AUTH_SMS_PROVIDER', 'mock')).replace(/_/g, '-');
const provider = normalizeSmsProvider(env('AUTH_SMS_PROVIDER', 'mock'));
if (AUTH_PROVIDER_ALIASES.aliyunPnvs.has(provider)) return { provider: 'aliyun-pnvs', aliases: AUTH_PROVIDER_ALIASES.aliyunPnvs };
return { provider, aliases: new Set([provider]) };
}
function validateActiveSmsProviderRows(rows, sourceLabel = 'database') {
const expected = currentSmsProviderAliases();
if (!PRODUCTION_SMS_PROVIDERS.has(normalizeProvider(env('AUTH_SMS_PROVIDER', 'mock')))) return;
if (!PRODUCTION_SMS_PROVIDERS.has(normalizeSmsProvider(env('AUTH_SMS_PROVIDER', 'mock')))) return;
const activeRows = rows.filter(row => row.source === 'auth' && providerIn(row.provider, expected.aliases));
if (activeRows.length === 0) {
block('db.auth_sms_provider_configured', 'AUTH_SMS_PROVIDER must have a matching active/testing tenant_auth_providers row', {
@@ -565,7 +569,7 @@ function validateEnv() {
}
}
const authSmsProvider = normalizeProvider(env('AUTH_SMS_PROVIDER', 'mock')).replace(/[_\s]/g, '-');
const authSmsProvider = normalizeSmsProvider(env('AUTH_SMS_PROVIDER', 'mock'));
if (!PRODUCTION_SMS_PROVIDERS.has(authSmsProvider)) {
block('env.auth_sms_provider', 'AUTH_SMS_PROVIDER must be aliyun-pnvs in production', {
provider: authSmsProvider || '(empty)',