feat(admin): 嵌入代码双形态 + shared_widget_domain 平台键
- 后端 GET /api/platform/settings/widget-domain:读平台设置键 shared_widget_domain(settings_store 内存快照,PUT settings 后热刷新 即时可见);platform_user 两种角色可读(超管配置/租户管理员生成嵌入 代码——与 settings CRUD 的 require_super 不同,非密钥无敏感面); 空串/非字符串视同未配置 → null - config/center 嵌入卡双形态(spec 2026-10-19 §5):域名形态 + 共享域名形态(/t/<slug>/static/widget.js,路径前缀即租户标识); 可用性规则(两料齐双形态/无域名仅共享/共享未配仅域名/都无引导文案) 与生效态回退;data-site 两形态通用 - normalizeSharedDomain 主机名字符集校验(拒引号/尖括号/空格——防 配置侧把恶意字符注入生成的 script src 串)+ buildEmbedCode 纯函数, vitest 6 例钉位 - 平台设置页新增「共享域名」组(shared_widget_domain 推荐键,表驱动 渲染自动生效);settings API 模块加 getWidgetDomain Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -29,7 +29,9 @@
|
||||
ai.*/smtp.* 对齐 admin 平台设置页)即时生效,无需重启。
|
||||
|
||||
鉴权矩阵(spec §3):config 系 = require_tenant(slug)(租户全开——本租户
|
||||
管理员可自助改配置);settings = require_super。409 门经 platform_user 连锁。
|
||||
管理员可自助改配置);settings = require_super(例外:GET /settings/widget-domain
|
||||
= platform_user 两种角色可读——嵌入代码生成器的原料,spec 2026-10-19 §5)。
|
||||
409 门经 platform_user 连锁。
|
||||
|
||||
密钥掩码哨兵(Phase 3 Task 1):push.api_key / ai.api_key /
|
||||
email.smtp.password 及平台设置的密钥名值,所有携带 config/value 的响应
|
||||
@@ -53,7 +55,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from app.engine.services import boundary_filter
|
||||
from app.engine.services.email_service import send_test_email
|
||||
from app.engine.wall_schema import WallConfigError, compile_wall
|
||||
from app.platform.auth import UserContext, require_super
|
||||
from app.platform.auth import UserContext, platform_user, require_super
|
||||
from app.platform.config_validation import (
|
||||
CONFIG_GROUPS,
|
||||
ValidationContext,
|
||||
@@ -743,3 +745,16 @@ async def put_setting(request: Request, user=Depends(require_super)):
|
||||
await session.commit()
|
||||
await settings_store.refresh(engine)
|
||||
return {"key": key, "value": _mask_setting_item(key, value)}
|
||||
|
||||
|
||||
@settings_router.get("/widget-domain")
|
||||
async def get_widget_domain(user: platform_user):
|
||||
"""共享挂件域名读取(spec 2026-10-19 §5)——配置中心嵌入代码生成器
|
||||
消费的平台设置键 shared_widget_domain。两种平台角色可读:超管在平台
|
||||
设置页配置、租户管理员生成 /t/<slug>/ 形态嵌入代码都要用(与 settings
|
||||
CRUD 的 require_super 不同——本值非密钥、无敏感面,公开到登录管理员
|
||||
层即可)。读 settings_store 内存快照(lifespan 装载 / PUT settings 后
|
||||
refresh 热刷新,Phase 4 Task 5A 同链路);空串/None/非字符串值视同
|
||||
未配置 → None(前端生成侧还有域名合法字符校验兜底)。"""
|
||||
raw = settings_store.get("shared_widget_domain")
|
||||
return {"widget_domain": raw if isinstance(raw, str) and raw else None}
|
||||
|
||||
Reference in New Issue
Block a user