feat: support Aliyun PNVS SMS verification

This commit is contained in:
Codex
2026-07-03 22:34:19 +08:00
parent 8ebe505dba
commit 69b3d80621
11 changed files with 441 additions and 59 deletions

View File

@@ -10,11 +10,23 @@ const DEFAULT_AUTH_SESSION_SECRET = 'development-session-secret-change-me';
const DEFAULT_AUTH_JWT_SECRET = 'development-jwt-secret-change-me';
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', 'aliyun-sms', 'aliyun_sms', 'tencent', 'tencent-sms', 'tencent_sms']);
const PRODUCTION_SMS_PROVIDERS = new Set([
'aliyun',
'aliyun-sms',
'aliyun_sms',
'aliyun-pnvs',
'aliyun_pnvs',
'aliyun-sms-auth',
'aliyun_sms_auth',
'tencent',
'tencent-sms',
'tencent_sms',
]);
const PRODUCTION_STORAGE_PROVIDERS = new Set(['aliyun_oss', 'tencent_cos', 'supabase_storage']);
const AUTH_PROVIDER_ALIASES = {
sms: new Set(['aliyun', 'aliyun-sms', 'aliyun_sms', 'tencent', 'tencent-sms', 'tencent_sms']),
sms: new Set(['aliyun', 'aliyun-sms', 'aliyun_sms', 'aliyun-pnvs', 'aliyun_pnvs', 'aliyun-sms-auth', 'aliyun_sms_auth', 'tencent', 'tencent-sms', 'tencent_sms']),
aliyun: new Set(['aliyun', 'aliyun-sms', 'aliyun_sms']),
aliyunPnvs: new Set(['aliyun-pnvs', 'aliyun_pnvs', 'aliyun-pnvs-sms', 'aliyun_sms_auth', 'aliyun-sms-auth']),
tencent: new Set(['tencent', 'tencent-sms', 'tencent_sms']),
wechatMiniapp: new Set(['wechat-miniapp', 'wechat_miniapp', 'wechat-mini', 'wx-miniapp', 'wx_miniapp']),
wechatWeb: new Set(['wechat-web', 'wechat_web', 'wechat', 'wechat-oauth', 'wechat_oauth']),
@@ -232,6 +244,23 @@ function validateAuthProviderPublicConfig(row) {
return;
}
if (providerIn(provider, AUTH_PROVIDER_ALIASES.aliyunPnvs)) {
blockMissingPublicConfig(row, missingPublicKeyGroups(configPublic, [
{ label: 'signName', keys: ['signName'] },
{ label: 'templateCode', keys: ['templateCode'] },
]));
validateProviderUrl({
id: `db.auth.${safeProviderName(row.provider)}.endpoint`,
value: publicString(configPublic, ['endpoint']),
allowedHosts: ['aliyuncs.com'],
details,
});
if (!publicString(configPublic, ['regionId'])) {
warn(`db.auth.${safeProviderName(row.provider)}.region`, 'Aliyun PNVS regionId is not set; default cn-hangzhou will be used', details);
}
return;
}
if (providerIn(provider, AUTH_PROVIDER_ALIASES.tencent)) {
blockMissingPublicConfig(row, missingPublicKeyGroups(configPublic, [
{ label: 'smsSdkAppId/appId', keys: ['smsSdkAppId', 'appId'] },
@@ -507,7 +536,7 @@ function validateEnv() {
const authSmsProvider = env('AUTH_SMS_PROVIDER', 'mock').trim().toLowerCase();
if (!PRODUCTION_SMS_PROVIDERS.has(authSmsProvider)) {
block('env.auth_sms_provider', 'AUTH_SMS_PROVIDER must be aliyun/aliyun-sms or tencent/tencent-sms in production', {
block('env.auth_sms_provider', 'AUTH_SMS_PROVIDER must be aliyun/aliyun-sms, aliyun-pnvs, or tencent/tencent-sms in production', {
provider: authSmsProvider || '(empty)',
});
} else {
@@ -842,7 +871,7 @@ async function validateDatabase() {
left join app_private.tenant_secrets s
on s.tenant_id = p.tenant_id
and s.secret_scope = case
when lower(replace(p.provider, '_', '-')) in ('aliyun', 'aliyun-sms', 'tencent', 'tencent-sms') then 'sms'
when lower(replace(p.provider, '_', '-')) in ('aliyun', 'aliyun-sms', 'aliyun-pnvs', 'aliyun-pnvs-sms', 'aliyun-sms-auth', 'tencent', 'tencent-sms') then 'sms'
else 'oauth'
end
and s.secret_key = coalesce(nullif(split_part(p.config_public->>'secretRef', ':', 3), ''), p.provider)