security(users): SafeUser — passwordHash/токены не уходят клиенту

Шаг 0.8 плана production-готовности:
- shared/schema.ts: тип SafeUser + safeUserColumns
- getUsersByOrganization, listUsers, searchUsers, getUsersByRole,
  getUsersByOrgRoleId, documents getUser — без чувствительных колонок
- sync (initial/delta), автоматизации ctx.users.list, MCP list_users — sanitized
This commit is contained in:
2026-09-07 21:03:00 +03:00
parent 26419f395f
commit cf6f937108
12 changed files with 79 additions and 51 deletions

View File

@@ -10,7 +10,7 @@ import { McpClient } from '../utils/mcp-client';
import { eventBus } from '../routes/shared';
import { publishConvTypingEvent } from '../routes/messenger.helpers';
import { getOllamaNumThread, getOllamaNumCtx } from '../utils/ollama-config';
import type { Bot, Task, User } from '@shared/schema';
import type { Bot, Task, SafeUser } from '@shared/schema';
import { db } from '../db';
import { conversationMessages, bots } from '@shared/schema';
import { eq, and, desc } from 'drizzle-orm';
@@ -48,7 +48,7 @@ interface AiBotContext {
task: Task;
message: string;
attachments?: Array<{ url: string; name: string; size: number; mimeType?: string }>;
user: User;
user: SafeUser;
organizationId: number;
}
@@ -189,7 +189,7 @@ async function callLlm(
}
}
export function checkBotAccess(bot: Bot, user: User): boolean {
export function checkBotAccess(bot: Bot, user: SafeUser): boolean {
const policy = bot.accessPolicy;
if (!policy || policy.mode === 'all') return true;
if (policy.mode === 'roles') {
@@ -491,7 +491,7 @@ export async function handleAiBotDirectMessage(ctx: {
bot: Bot;
conversationId: number;
message: string;
user: User;
user: SafeUser;
organizationId: number;
}): Promise<void> {
const { bot, conversationId, message, user, organizationId } = ctx;