first commit
This commit is contained in:
125
apps/api-gateway/src/controllers/settings.controller.ts
Normal file
125
apps/api-gateway/src/controllers/settings.controller.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
import { Body, Controller, Delete, Get, Param, Put, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { map } from 'rxjs';
|
||||
import { CoreGrpcService } from '../core-grpc.service';
|
||||
import { CurrentAdmin } from '../decorators/current-admin.decorator';
|
||||
import { ConnectLinkedAccountDto, UpsertSettingDto, UpsertSocialProviderDto } from '../dto/settings.dto';
|
||||
import { AdminGuard, AdminRequestUser, assertAdminPermission } from '../guards/admin.guard';
|
||||
|
||||
const settingsWritePipe = new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: false
|
||||
});
|
||||
|
||||
@ApiTags('Глобальные настройки')
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(AdminGuard)
|
||||
@Controller('admin/settings')
|
||||
export class SettingsController {
|
||||
constructor(private readonly core: CoreGrpcService) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Список системных настроек', description: 'Возвращает динамические настройки, включая PIN timeout и OAuth providers.' })
|
||||
@ApiResponse({ status: 200, description: 'Список настроек получен' })
|
||||
list(@CurrentAdmin() admin: AdminRequestUser) {
|
||||
assertAdminPermission(admin, 'canManageSettings');
|
||||
return this.core.settings.ListSettings({}).pipe(
|
||||
map((response) => {
|
||||
const payload = response as { settings?: unknown[] };
|
||||
return { settings: payload.settings ?? [] };
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Get('key/:key')
|
||||
@ApiOperation({ summary: 'Получить настройку', description: 'Возвращает SystemSetting по ключу.' })
|
||||
@ApiParam({ name: 'key', description: 'Ключ настройки', example: 'PIN_LOCK_TIMEOUT_MINUTES' })
|
||||
@ApiResponse({ status: 200, description: 'Настройка получена' })
|
||||
get(@Param('key') key: string, @CurrentAdmin() admin: AdminRequestUser) {
|
||||
assertAdminPermission(admin, 'canManageSettings');
|
||||
return this.core.settings.GetSetting({ key });
|
||||
}
|
||||
|
||||
@Put()
|
||||
@UsePipes(settingsWritePipe)
|
||||
@ApiOperation({ summary: 'Создать или обновить настройку', description: 'Меняет значение SystemSetting без изменения кода frontend.' })
|
||||
@ApiBody({ type: UpsertSettingDto })
|
||||
@ApiResponse({ status: 200, description: 'Настройка создана или обновлена' })
|
||||
upsert(@Body() dto: UpsertSettingDto, @CurrentAdmin() admin: AdminRequestUser) {
|
||||
assertAdminPermission(admin, 'canManageSettings');
|
||||
return this.core.settings.UpsertSetting({
|
||||
key: dto.key,
|
||||
value: dto.value,
|
||||
description: dto.description,
|
||||
isSecret: dto.isSecret
|
||||
});
|
||||
}
|
||||
|
||||
@Delete('key/:key')
|
||||
@ApiOperation({ summary: 'Удалить настройку', description: 'Удаляет SystemSetting по ключу.' })
|
||||
@ApiParam({ name: 'key', description: 'Ключ настройки' })
|
||||
@ApiResponse({ status: 200, description: 'Настройка удалена' })
|
||||
delete(@Param('key') key: string, @CurrentAdmin() admin: AdminRequestUser) {
|
||||
assertAdminPermission(admin, 'canManageSettings');
|
||||
return this.core.settings.DeleteSetting({ key });
|
||||
}
|
||||
|
||||
@Get('oauth/providers')
|
||||
@ApiOperation({ summary: 'Список OAuth провайдеров', description: 'Возвращает глобальные настройки Google/Yandex и других social login providers.' })
|
||||
@ApiResponse({ status: 200, description: 'Список провайдеров получен' })
|
||||
listProviders(@CurrentAdmin() admin: AdminRequestUser) {
|
||||
assertAdminPermission(admin, 'canManageSettings');
|
||||
return this.core.settings.ListSocialProviders({});
|
||||
}
|
||||
|
||||
@Put('oauth/providers')
|
||||
@UsePipes(settingsWritePipe)
|
||||
@ApiOperation({ summary: 'Создать или обновить OAuth провайдера', description: 'Управляет clientId/clientSecret и глобальным включением Google/Yandex входа.' })
|
||||
@ApiBody({ type: UpsertSocialProviderDto })
|
||||
@ApiResponse({ status: 200, description: 'Провайдер создан или обновлен' })
|
||||
upsertProvider(@Body() dto: UpsertSocialProviderDto, @CurrentAdmin() admin: AdminRequestUser) {
|
||||
assertAdminPermission(admin, 'canManageSettings');
|
||||
return this.core.settings.UpsertSocialProvider({
|
||||
providerName: dto.providerName,
|
||||
clientId: dto.clientId,
|
||||
clientSecret: dto.clientSecret,
|
||||
isEnabled: dto.isEnabled
|
||||
});
|
||||
}
|
||||
|
||||
@Delete('oauth/providers/:providerName')
|
||||
@ApiOperation({ summary: 'Удалить OAuth провайдера', description: 'Удаляет глобальную настройку social login provider.' })
|
||||
@ApiParam({ name: 'providerName', description: 'Название провайдера', example: 'google' })
|
||||
@ApiResponse({ status: 200, description: 'Провайдер удален' })
|
||||
deleteProvider(@Param('providerName') providerName: string, @CurrentAdmin() admin: AdminRequestUser) {
|
||||
assertAdminPermission(admin, 'canManageSettings');
|
||||
return this.core.settings.DeleteSocialProvider({ providerName });
|
||||
}
|
||||
|
||||
@Get('linked-accounts/users/:userId')
|
||||
@ApiOperation({ summary: 'Связанные внешние аккаунты', description: 'Возвращает LinkedAccount записи пользователя для Google/Yandex и других провайдеров.' })
|
||||
@ApiParam({ name: 'userId', description: 'ID пользователя' })
|
||||
@ApiResponse({ status: 200, description: 'Список внешних аккаунтов получен' })
|
||||
listLinkedAccounts(@Param('userId') userId: string) {
|
||||
return this.core.security.ListLinkedAccounts({ userId });
|
||||
}
|
||||
|
||||
@Put('linked-accounts/users/:userId')
|
||||
@ApiOperation({ summary: 'Подключить внешний аккаунт', description: 'Создает или обновляет LinkedAccount для social OAuth логина пользователя.' })
|
||||
@ApiParam({ name: 'userId', description: 'ID пользователя' })
|
||||
@ApiBody({ type: ConnectLinkedAccountDto })
|
||||
@ApiResponse({ status: 200, description: 'Внешний аккаунт подключен' })
|
||||
connectLinkedAccount(@Param('userId') userId: string, @Body() dto: ConnectLinkedAccountDto) {
|
||||
return this.core.security.ConnectLinkedAccount({ userId, ...dto });
|
||||
}
|
||||
|
||||
@Delete('linked-accounts/users/:userId/:providerName')
|
||||
@ApiOperation({ summary: 'Отключить внешний аккаунт', description: 'Удаляет связь пользователя с Google/Yandex или другим social provider.' })
|
||||
@ApiParam({ name: 'userId', description: 'ID пользователя' })
|
||||
@ApiParam({ name: 'providerName', description: 'Название провайдера', example: 'google' })
|
||||
@ApiResponse({ status: 200, description: 'Внешний аккаунт отключен' })
|
||||
disconnectLinkedAccount(@Param('userId') userId: string, @Param('providerName') providerName: string) {
|
||||
return this.core.security.DisconnectLinkedAccount({ userId, providerName });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user