0.11.2: 旗舰版第三轮完善(通用聊天/企微钉钉飞书扫码登录/个人安全策略)

- 门户通用聊天:选择已批准模型直接对话,审批通过后自动开通用户级运行时
  API Key(加密落库,限额取批准值),聊天经受管网关统一认证/限流/配额/审计;
  会话哈希链完整性 + busy 租约防并发,失败不落库。
- 扫码登录:identity_providers 扩展 wecom/dingtalk/feishu,管理端配置
  (AppID/AppSecret/AgentID/回调/自动开户/默认部门),登录页自动展示;
  one-time state 防 CSRF,provider_uid 全局唯一防多账号绑定,平台端点
  固定公网 URL 复用 public-only 拨号。
- 个人安全策略:账号安全页(登录设备管理/吊销非当前会话/登录提醒开关/
  扫码绑定解绑),登录成功发布 security.login_detected 事件按偏好落站内信
  (新增 security 类别),会话索引只存令牌摘要并惰性清理。
- 迁移 000038-000041;修复 social update 参数越界/凭据回读/路由挂载缺失;
  全量测试 25 包通过,前端 admin/portal 构建通过,端到端验证完成。
This commit is contained in:
LLMGuardX Dev
2026-08-13 12:53:38 +08:00
parent 4563979a15
commit e31cc54b8e
36 changed files with 2823 additions and 60 deletions
+48
View File
@@ -0,0 +1,48 @@
-- 000038_portal_chat.sql — 门户通用聊天:会话、消息链(哈希完整性)与用户运行时凭据。
-- 模型权限申请审批通过后,系统为该用户开通一把 gateway API Key(加密落库),
-- 门户"通用聊天"页面用这把 Key 直接调用 /v1/chat/completions,用量与审计
-- 均归属到用户自己的 Key,而不是共享一个全局凭据。
CREATE TABLE IF NOT EXISTS gateway.portal_user_runtime_credentials (
portal_user_id uuid PRIMARY KEY REFERENCES gateway.portal_users(id) ON DELETE CASCADE,
api_key_id uuid NOT NULL REFERENCES gateway.api_keys(id) ON DELETE CASCADE,
encrypted_key bytea NOT NULL,
key_kek_version integer NOT NULL,
created_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
COMMENT ON TABLE gateway.portal_user_runtime_credentials IS
'Per-portal-user gateway credential used by the general chat. Plaintext is encrypted with the application KEK and never returned to a browser.';
CREATE TABLE IF NOT EXISTS gateway.portal_chat_sessions (
id uuid PRIMARY KEY,
portal_user_id uuid NOT NULL REFERENCES gateway.portal_users(id) ON DELETE CASCADE,
title varchar(160) NOT NULL DEFAULT '',
provider_code text NOT NULL DEFAULT '',
model text NOT NULL CHECK (length(model) BETWEEN 1 AND 512),
status text NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'archived')),
busy boolean NOT NULL DEFAULT false,
busy_token text,
busy_since timestamptz,
next_sequence integer NOT NULL DEFAULT 1 CHECK (next_sequence >= 1),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE INDEX IF NOT EXISTS portal_chat_sessions_user_time_idx
ON gateway.portal_chat_sessions (portal_user_id, updated_at DESC);
CREATE TABLE IF NOT EXISTS gateway.portal_chat_messages (
id uuid PRIMARY KEY,
session_id uuid NOT NULL REFERENCES gateway.portal_chat_sessions(id) ON DELETE CASCADE,
sequence integer NOT NULL,
role varchar(16) NOT NULL CHECK (role IN ('user', 'assistant')),
content text NOT NULL,
previous_hash varchar(64) NOT NULL,
message_hash varchar(64) NOT NULL,
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
UNIQUE (session_id, sequence)
);
CREATE INDEX IF NOT EXISTS portal_chat_messages_session_idx
ON gateway.portal_chat_messages (session_id, sequence);
+30
View File
@@ -0,0 +1,30 @@
-- 000039_social_login.sql — 企微/钉钉/飞书扫码登录。
-- 身份源表 identity_providers 扩展三种内置扫码登录 kind;企业用户与平台账号的
-- 绑定关系单独落表(provider_uid 全局唯一,防止同一企微账号绑定多个本系统账号)。
ALTER TABLE gateway.identity_providers
DROP CONSTRAINT IF EXISTS identity_providers_kind_check;
ALTER TABLE gateway.identity_providers
ADD CONSTRAINT identity_providers_kind_check
CHECK (kind IN ('oidc', 'saml', 'wecom', 'dingtalk', 'feishu'));
-- 扫码登录自动开通的账号 auth_source 记为平台 kind。
ALTER TABLE gateway.portal_users
DROP CONSTRAINT IF EXISTS portal_users_auth_source_check;
ALTER TABLE gateway.portal_users
ADD CONSTRAINT portal_users_auth_source_check
CHECK (auth_source IN ('local', 'feishu', 'oidc', 'saml', 'wecom', 'dingtalk'));
CREATE TABLE IF NOT EXISTS gateway.portal_user_provider_bindings (
portal_user_id uuid NOT NULL REFERENCES gateway.portal_users(id) ON DELETE CASCADE,
provider_kind varchar(16) NOT NULL CHECK (provider_kind IN ('wecom', 'dingtalk', 'feishu')),
provider_uid varchar(255) NOT NULL,
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
PRIMARY KEY (provider_kind, provider_uid),
UNIQUE (portal_user_id, provider_kind)
);
CREATE INDEX IF NOT EXISTS portal_user_provider_bindings_user_idx
ON gateway.portal_user_provider_bindings (portal_user_id);
+9
View File
@@ -0,0 +1,9 @@
-- 000040_security_prefs.sql — 个人安全策略:新设备登录通知开关。
-- 登录成功后 identity 服务发布 security.login_detected 事件,通知 worker 依据
-- 本表开关决定是否落站内信(默认开启,收件人 = 账号本人)。
CREATE TABLE IF NOT EXISTS gateway.portal_security_prefs (
portal_user_id uuid PRIMARY KEY REFERENCES gateway.portal_users(id) ON DELETE CASCADE,
login_notify boolean NOT NULL DEFAULT true,
updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
@@ -0,0 +1,7 @@
-- 000041_inbox_security_category.sql — 站内信新增 security 类别(登录提醒等安全事件)。
ALTER TABLE gateway.inbox_messages
DROP CONSTRAINT IF EXISTS inbox_messages_category_check;
ALTER TABLE gateway.inbox_messages
ADD CONSTRAINT inbox_messages_category_check
CHECK (category = ANY (ARRAY['system', 'approval', 'task_result', 'resource', 'security']));