ТTessora Docs

Auth и RBAC

Better Auth, 7 ролей, 56 permissions и 4 уровня защиты

Аутентификация — Better Auth (src/lib/auth/), сессии в cookie. Регистрация только по приглашениям.

7 ролей

РольКто это
super_adminПолный доступ ко всему, включая AI-настройки
monster_adminАдминистратор Monster Team: пользователи, компании, аудит
monster_pmПроект-менеджер команды
monster_creatorИсполнитель (производство роликов)
client_ownerВладелец компании-клиента, максимум прав в своей компании
client_managerМенеджер клиента: создаёт задачи, материалы, правки
client_viewerRead-only доступ

Permissions

56 ключей в src/lib/auth/permissions.ts, сгруппированы по доменам:

task.*                view / create / update / delete
file.*                upload / download / delete
content.*             view_ready / upload_ready / approve / request_revision / delete_ready
revision.*            create / view / resolve
calendar.*            view / assign_date / move_item
ai.*                  generate_prompt / generate_copy / view_usage
user.*                view / invite / change_role
company.*             view / create / edit
admin.*               manage_clients / manage_storage / manage_ai_budget
audit.view
safebot.*             view / create / edit / delete / promote
reference_category.*  create / update / delete

Источник истины — ROLE_PERMISSIONS_MATRIX. Хардкод проверок ролей в коде запрещён.

Динамические overrides

Помимо матрицы, отдельному пользователю можно добавить/забрать права через таблицу UserPermission (админ UI: /users, API: /api/admin/users/[id]/permissions). Кэш overrides хранится в User.permissionOverridesJson.

4 уровня защиты

1. src/proxy.ts (middleware)        — есть ли сессия вообще
2. lib/auth/redirects.ts            — может ли роль видеть страницу (server-side redirect)
3. withPermission("key", handler)   — guard каждого API endpoint
4. usePermissions() / <Can>         — скрытие кнопок и секций в UI

UI-уровень — только косметика; настоящая защита — уровень 3. Любой новый endpoint обязан быть обёрнут:

import { withPermission } from "@/lib/auth/with-permission";

export const POST = withPermission("task.create", async (req, { auth }) => {
  // auth: { userId, role, companyId, permissions }
});

Multi-tenancy

Все данные привязаны к companyId. Скоуп определяется в src/lib/api/scope.ts:

  • companyScope(auth) — клиент получает фильтр по своей компании, Monster/super видит всё;
  • resolveWriteCompanyId(auth, requestedId) — валидация, куда можно писать.

Приглашения

  1. Админ создаёт приглашение: POST /api/admin/invitations (permission user.invite) → ссылка с токеном.
  2. Пользователь открывает /invite/accept?token=…, форма показывает email/роль/компанию (GET /api/invitations/[token]).
  3. POST /api/invitations/[token]/accept — создание аккаунта и вход.

Как добавить новое право

  1. Добавить ключ в src/lib/auth/permissions.ts и в ROLE_PERMISSIONS_MATRIX нужным ролям.
  2. Человекочитаемое название — в permission-presets.ts (для admin UI).
  3. Обернуть API в withPermission("новый.ключ", …).
  4. В UI — usePermissions().can("новый.ключ") или <Can permission="новый.ключ">.

On this page