mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
feat(core): Extend user list to allow expanding the user list to projects (#16314)
Co-authored-by: Guillaume Jacquart <jacquart.guillaume@gmail.com> Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Csaba Tuncsik <csaba.tuncsik@gmail.com>
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
import { RoleChangeRequestDto, SettingsUpdateRequestDto } from '@n8n/api-types';
|
||||
import {
|
||||
RoleChangeRequestDto,
|
||||
SettingsUpdateRequestDto,
|
||||
UsersListFilterDto,
|
||||
usersListSchema,
|
||||
} from '@n8n/api-types';
|
||||
import { Logger } from '@n8n/backend-common';
|
||||
import type { PublicUser } from '@n8n/db';
|
||||
import {
|
||||
@@ -19,6 +24,7 @@ import {
|
||||
Licensed,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
} from '@n8n/decorators';
|
||||
import { Response } from 'express';
|
||||
|
||||
@@ -29,8 +35,7 @@ import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
|
||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||
import { EventService } from '@/events/event.service';
|
||||
import { ExternalHooks } from '@/external-hooks';
|
||||
import { listQueryMiddleware } from '@/middlewares';
|
||||
import { ListQuery, AuthenticatedRequest, UserRequest } from '@/requests';
|
||||
import { AuthenticatedRequest, UserRequest } from '@/requests';
|
||||
import { FolderService } from '@/services/folder.service';
|
||||
import { ProjectService } from '@/services/project.service.ee';
|
||||
import { UserService } from '@/services/user.service';
|
||||
@@ -64,20 +69,16 @@ export class UsersController {
|
||||
|
||||
private removeSupplementaryFields(
|
||||
publicUsers: Array<Partial<PublicUser>>,
|
||||
listQueryOptions: ListQuery.Options,
|
||||
listQueryOptions: UsersListFilterDto,
|
||||
) {
|
||||
const { take, select, filter } = listQueryOptions;
|
||||
const { select } = listQueryOptions;
|
||||
|
||||
// remove fields added to satisfy query
|
||||
|
||||
if (take && select && !select?.id) {
|
||||
if (select !== undefined && !select.includes('id')) {
|
||||
for (const user of publicUsers) delete user.id;
|
||||
}
|
||||
|
||||
if (filter?.isOwner) {
|
||||
for (const user of publicUsers) delete user.role;
|
||||
}
|
||||
|
||||
// remove computed fields (unselectable)
|
||||
|
||||
if (select) {
|
||||
@@ -91,25 +92,40 @@ export class UsersController {
|
||||
return publicUsers;
|
||||
}
|
||||
|
||||
@Get('/', { middlewares: listQueryMiddleware })
|
||||
@Get('/')
|
||||
@GlobalScope('user:list')
|
||||
async listUsers(req: ListQuery.Request) {
|
||||
const { listQueryOptions } = req;
|
||||
async listUsers(
|
||||
req: AuthenticatedRequest,
|
||||
_res: Response,
|
||||
@Query listQueryOptions: UsersListFilterDto,
|
||||
) {
|
||||
const userQuery = this.userRepository.buildUserQuery(listQueryOptions);
|
||||
|
||||
const findManyOptions = await this.userRepository.toFindManyOptions(listQueryOptions);
|
||||
const response = await userQuery.getManyAndCount();
|
||||
|
||||
const users = await this.userRepository.find(findManyOptions);
|
||||
const [users, count] = response;
|
||||
|
||||
const publicUsers: Array<Partial<PublicUser>> = await Promise.all(
|
||||
users.map(
|
||||
async (u) =>
|
||||
await this.userService.toPublic(u, { withInviteUrl: true, inviterId: req.user.id }),
|
||||
),
|
||||
const publicUsers = await Promise.all(
|
||||
users.map(async (u) => {
|
||||
const user = await this.userService.toPublic(u, {
|
||||
withInviteUrl: true,
|
||||
inviterId: req.user.id,
|
||||
});
|
||||
return {
|
||||
...user,
|
||||
projectRelations: u.projectRelations?.map((pr) => ({
|
||||
id: pr.projectId,
|
||||
role: pr.role, // normalize role for frontend
|
||||
name: pr.project.name,
|
||||
})),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
return listQueryOptions
|
||||
? this.removeSupplementaryFields(publicUsers, listQueryOptions)
|
||||
: publicUsers;
|
||||
return usersListSchema.parse({
|
||||
count,
|
||||
items: this.removeSupplementaryFields(publicUsers, listQueryOptions),
|
||||
});
|
||||
}
|
||||
|
||||
@Get('/:id/password-reset-link')
|
||||
|
||||
Reference in New Issue
Block a user