mirror of
https://github.com/docmost/docmost.git
synced 2026-09-11 07:56:54 +08:00
* Add page_hierarchy table * feat(ee): page-level permissions * pagination * rename migration fixes * fix * tabs * fix theme * cleanup * sync * page permissions notification * other fixes * sharing disbled * fix column nodes * toggle error handling
189 lines
4.6 KiB
TypeScript
189 lines
4.6 KiB
TypeScript
import {
|
|
BadRequestException,
|
|
Injectable,
|
|
NotFoundException,
|
|
} from '@nestjs/common';
|
|
import { InjectKysely } from 'nestjs-kysely';
|
|
import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types';
|
|
import { dbOrTx, executeTx } from '@docmost/db/utils';
|
|
import { sql } from 'kysely';
|
|
import { GroupUser, InsertableGroupUser } from '@docmost/db/types/entity.types';
|
|
import { PaginationOptions } from '../../pagination/pagination-options';
|
|
import { executeWithCursorPagination } from '@docmost/db/pagination/cursor-pagination';
|
|
import { GroupRepo } from '@docmost/db/repos/group/group.repo';
|
|
import { UserRepo } from '@docmost/db/repos/user/user.repo';
|
|
|
|
@Injectable()
|
|
export class GroupUserRepo {
|
|
constructor(
|
|
@InjectKysely() private readonly db: KyselyDB,
|
|
private readonly groupRepo: GroupRepo,
|
|
private readonly userRepo: UserRepo,
|
|
) {}
|
|
|
|
async getGroupUserById(
|
|
userId: string,
|
|
groupId: string,
|
|
trx?: KyselyTransaction,
|
|
) {
|
|
const db = dbOrTx(this.db, trx);
|
|
return db
|
|
.selectFrom('groupUsers')
|
|
.selectAll()
|
|
.where('userId', '=', userId)
|
|
.where('groupId', '=', groupId)
|
|
.executeTakeFirst();
|
|
}
|
|
|
|
async insertGroupUser(
|
|
insertableGroupUser: InsertableGroupUser,
|
|
trx?: KyselyTransaction,
|
|
): Promise<GroupUser> {
|
|
const db = dbOrTx(this.db, trx);
|
|
return db
|
|
.insertInto('groupUsers')
|
|
.values(insertableGroupUser)
|
|
.returningAll()
|
|
.executeTakeFirst();
|
|
}
|
|
|
|
async getGroupUsersPaginated(groupId: string, pagination: PaginationOptions) {
|
|
let query = this.db
|
|
.selectFrom('groupUsers')
|
|
.innerJoin('users', 'users.id', 'groupUsers.userId')
|
|
.selectAll('users')
|
|
.where('groupId', '=', groupId);
|
|
|
|
if (pagination.query) {
|
|
query = query.where((eb) =>
|
|
eb(
|
|
sql`f_unaccent(users.name)`,
|
|
'ilike',
|
|
sql`f_unaccent(${'%' + pagination.query + '%'})`,
|
|
),
|
|
);
|
|
}
|
|
|
|
const result = await executeWithCursorPagination(query, {
|
|
perPage: pagination.limit,
|
|
cursor: pagination.cursor,
|
|
beforeCursor: pagination.beforeCursor,
|
|
fields: [{ expression: 'users.id', direction: 'asc', key: 'id' }],
|
|
parseCursor: (cursor) => ({ id: cursor.id }),
|
|
});
|
|
|
|
result.items.map((user) => {
|
|
delete user.password;
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
async addUserToGroup(
|
|
userId: string,
|
|
groupId: string,
|
|
workspaceId: string,
|
|
trx?: KyselyTransaction,
|
|
): Promise<void> {
|
|
await executeTx(
|
|
this.db,
|
|
async (trx) => {
|
|
const group = await this.groupRepo.findById(groupId, workspaceId, {
|
|
trx,
|
|
});
|
|
if (!group) {
|
|
throw new NotFoundException('Group not found');
|
|
}
|
|
|
|
const user = await this.userRepo.findById(userId, workspaceId, {
|
|
trx: trx,
|
|
});
|
|
|
|
if (!user) {
|
|
throw new NotFoundException('User not found');
|
|
}
|
|
|
|
const groupUserExists = await this.getGroupUserById(
|
|
userId,
|
|
groupId,
|
|
trx,
|
|
);
|
|
|
|
if (groupUserExists) {
|
|
throw new BadRequestException(
|
|
'User is already a member of this group',
|
|
);
|
|
}
|
|
|
|
await this.insertGroupUser(
|
|
{
|
|
userId,
|
|
groupId,
|
|
},
|
|
trx,
|
|
);
|
|
},
|
|
trx,
|
|
);
|
|
}
|
|
|
|
async addUserToDefaultGroup(
|
|
userId: string,
|
|
workspaceId: string,
|
|
trx?: KyselyTransaction,
|
|
): Promise<void> {
|
|
await executeTx(
|
|
this.db,
|
|
async (trx) => {
|
|
const defaultGroup = await this.groupRepo.getDefaultGroup(
|
|
workspaceId,
|
|
trx,
|
|
);
|
|
await this.insertGroupUser(
|
|
{
|
|
userId,
|
|
groupId: defaultGroup.id,
|
|
},
|
|
trx,
|
|
);
|
|
},
|
|
trx,
|
|
);
|
|
}
|
|
|
|
async getUserIdsByGroupId(groupId: string): Promise<string[]> {
|
|
const rows = await this.db
|
|
.selectFrom('groupUsers')
|
|
.select('userId')
|
|
.where('groupId', '=', groupId)
|
|
.execute();
|
|
|
|
return rows.map((r) => r.userId);
|
|
}
|
|
|
|
async delete(
|
|
userId: string,
|
|
groupId: string,
|
|
opts?: { trx?: KyselyTransaction },
|
|
): Promise<void> {
|
|
const { trx } = opts;
|
|
const db = dbOrTx(this.db, trx);
|
|
|
|
await db
|
|
.deleteFrom('groupUsers')
|
|
.where('userId', '=', userId)
|
|
.where('groupId', '=', groupId)
|
|
.execute();
|
|
}
|
|
|
|
async getUserGroupIds(userId: string): Promise<string[]> {
|
|
const results = await this.db
|
|
.selectFrom('groupUsers')
|
|
.select('groupId')
|
|
.where('userId', '=', userId)
|
|
.execute();
|
|
|
|
return results.map((r) => r.groupId);
|
|
}
|
|
}
|