Files
IdP/apps/sso-core/src/domain/admin-seed.service.ts

141 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaService } from '../infra/prisma.service';
import { DEFAULT_USER_ROLE_SLUG } from './rbac.constants';
import { RbacService } from './rbac.service';
const PERMISSIONS = [
{ slug: 'admin.access', name: 'Доступ к админ-панели', description: 'Позволяет открывать раздел администрирования' },
{ slug: 'oauth.view', name: 'Просмотр OAuth-приложений', description: 'Просмотр списка OAuth2-клиентов' },
{ slug: 'oauth.view.all', name: 'Просмотр всех OAuth-приложений', description: 'Просмотр OAuth2-клиентов, созданных другими пользователями' },
{ slug: 'oauth.manage', name: 'Управление своими OAuth-приложениями', description: 'Создание и редактирование собственных OAuth2-клиентов' },
{ slug: 'oauth.manage.all', name: 'Управление всеми OAuth-приложениями', description: 'Создание и редактирование любых OAuth2-клиентов' },
{ slug: 'users.view', name: 'Просмотр пользователей', description: 'Чтение списка пользователей без изменений' },
{ slug: 'users.view.all', name: 'Просмотр всех пользователей', description: 'Просмотр полного списка пользователей системы' },
{ slug: 'users.manage', name: 'Управление пользователями', description: 'Редактирование, блокировка и сброс паролей' },
{ slug: 'users.manage.all', name: 'Полное управление пользователями', description: 'Расширенное управление всеми пользователями' },
{ slug: 'users.verify', name: 'Верификация пользователей', description: 'Выдача и снятие верификации, выбор значка' },
{ slug: 'users.read', name: 'Просмотр пользователей (устар.)', description: 'Устаревшее право, заменено на users.view' },
{ slug: 'settings.manage', name: 'Управление настройками', description: 'Изменение глобальных SystemSetting' },
{ slug: 'rbac.manage', name: 'Управление ролями и правами', description: 'Назначение ролей, прав пользователям и редактирование ролей' },
{ slug: 'documents.view_others', name: 'Просмотр документов пользователей', description: 'Просмотр документов и фото других пользователей' },
{ slug: 'bots.manage.all', name: 'Управление всеми ботами', description: 'Просмотр, блокировка и администрирование всех Telegram-ботов' }
] as const;
const ROLES = [
{
slug: DEFAULT_USER_ROLE_SLUG,
name: 'Пользователь',
description: 'Стандартная роль всех пользователей системы',
permissions: [] as string[],
isSystem: true,
isDefault: true
},
{
slug: 'bot',
name: 'Бот',
description: 'Системная учётная запись Telegram-бота',
permissions: [] as string[],
isSystem: true,
isDefault: false
},
{
slug: 'admin',
name: 'Администратор',
description: 'Полный доступ к админ-панели',
permissions: ['admin.access', 'oauth.manage.all', 'oauth.view.all', 'users.manage.all', 'users.view.all', 'users.verify', 'settings.manage', 'rbac.manage', 'bots.manage.all'],
isSystem: false,
isDefault: false
},
{
slug: 'moderator',
name: 'Модератор',
description: 'Просмотр пользователей и базовый доступ к админке',
permissions: ['admin.access', 'users.view', 'users.view.all'],
isSystem: false,
isDefault: false
},
{
slug: 'manager',
name: 'Менеджер',
description: 'Управление OAuth-приложениями',
permissions: ['admin.access', 'oauth.manage', 'oauth.view'],
isSystem: false,
isDefault: false
}
] as const;
const OAUTH_SCOPES = [
{ slug: 'openid', name: 'OpenID', description: 'Базовая идентификация OpenID Connect' },
{ slug: 'profile', name: 'Профиль', description: 'Имя, логин и аватар пользователя' },
{ slug: 'email', name: 'Email', description: 'Основная и резервная почта' },
{ slug: 'phone', name: 'Телефон', description: 'Основной и резервный телефон' },
{ slug: 'address', name: 'Адреса', description: 'Адреса пользователя' },
{ slug: 'documents', name: 'Документы', description: 'Документы пользователя' }
] as const;
@Injectable()
export class AdminSeedService implements OnModuleInit {
constructor(
private readonly prisma: PrismaService,
private readonly rbac: RbacService
) {}
async onModuleInit() {
for (const permission of PERMISSIONS) {
await this.rbac.upsertPermission(permission);
}
for (const scope of OAUTH_SCOPES) {
await this.prisma.oAuthScope.upsert({
where: { slug: scope.slug },
create: scope,
update: { name: scope.name, description: scope.description }
});
}
for (const role of ROLES) {
const existing = await this.prisma.role.findUnique({ where: { slug: role.slug } });
const roleRecord =
existing ??
(await this.prisma.role.create({
data: {
slug: role.slug,
name: role.name,
description: role.description,
isSystem: role.isSystem,
isDefault: role.isDefault
}
}));
await this.prisma.role.update({
where: { id: roleRecord.id },
data: {
name: role.name,
description: role.description,
isSystem: role.isSystem,
isDefault: role.isDefault
}
});
for (const slug of role.permissions) {
const permission = await this.prisma.permission.findUnique({ where: { slug } });
if (!permission) continue;
await this.prisma.rolePermission.upsert({
where: { roleId_permissionId: { roleId: roleRecord.id, permissionId: permission.id } },
create: { roleId: roleRecord.id, permissionId: permission.id },
update: {}
});
}
}
const users = await this.prisma.user.findMany({ where: { deletedAt: null }, select: { id: true, isSystemAccount: true, linkedBotId: true } });
for (const user of users) {
if (user.linkedBotId || user.isSystemAccount) {
await this.rbac.ensureBotUserRole(user.id);
} else {
await this.rbac.ensureDefaultUserRole(user.id);
}
}
}
}