mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
@@ -144,6 +144,14 @@ export class DocUserModel extends BaseModel {
|
||||
});
|
||||
}
|
||||
|
||||
async deleteByUserId(userId: string) {
|
||||
await this.db.workspaceDocUserRole.deleteMany({
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getOwner(workspaceId: string, docId: string) {
|
||||
return await this.db.workspaceDocUserRole.findFirst({
|
||||
where: {
|
||||
|
||||
@@ -123,7 +123,7 @@ export class SessionModel extends BaseModel {
|
||||
});
|
||||
}
|
||||
|
||||
async deleteUserSession(userId: string, sessionId?: string) {
|
||||
async deleteUserSessions(userId: string, sessionId?: string) {
|
||||
const { count } = await this.db.userSession.deleteMany({
|
||||
where: {
|
||||
userId,
|
||||
@@ -131,7 +131,7 @@ export class SessionModel extends BaseModel {
|
||||
},
|
||||
});
|
||||
this.logger.log(
|
||||
`Deleted user session success by userId: ${userId} and sessionId: ${sessionId}`
|
||||
`Deleted user sessions success by userId: ${userId} and sessionId: ${sessionId}`
|
||||
);
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Transactional } from '@nestjs-cls/transactional';
|
||||
import { type ConnectedAccount, Prisma, type User } from '@prisma/client';
|
||||
import { omit } from 'lodash-es';
|
||||
|
||||
import {
|
||||
CryptoHelper,
|
||||
@@ -49,6 +51,10 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
interface UserFilter {
|
||||
withDisabled?: boolean;
|
||||
}
|
||||
|
||||
export type PublicUser = Pick<User, keyof typeof publicUserSelect>;
|
||||
export type WorkspaceUser = Pick<User, keyof typeof workspaceUserSelect>;
|
||||
export type { ConnectedAccount, User };
|
||||
@@ -62,52 +68,49 @@ export class UserModel extends BaseModel {
|
||||
super();
|
||||
}
|
||||
|
||||
async get(id: string) {
|
||||
async get(id: string, filter: UserFilter = {}) {
|
||||
return this.db.user.findUnique({
|
||||
where: { id },
|
||||
where: { id, disabled: filter.withDisabled ? undefined : false },
|
||||
});
|
||||
}
|
||||
|
||||
async exists(id: string) {
|
||||
const count = await this.db.user.count({
|
||||
where: { id },
|
||||
});
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
async getPublicUser(id: string): Promise<PublicUser | null> {
|
||||
return this.db.user.findUnique({
|
||||
select: publicUserSelect,
|
||||
where: { id },
|
||||
where: { id, disabled: false },
|
||||
});
|
||||
}
|
||||
|
||||
async getPublicUsers(ids: string[]): Promise<PublicUser[]> {
|
||||
return this.db.user.findMany({
|
||||
select: publicUserSelect,
|
||||
where: { id: { in: ids } },
|
||||
where: { id: { in: ids }, disabled: false },
|
||||
});
|
||||
}
|
||||
|
||||
async getWorkspaceUser(id: string): Promise<WorkspaceUser | null> {
|
||||
return this.db.user.findUnique({
|
||||
select: workspaceUserSelect,
|
||||
where: { id },
|
||||
where: { id, disabled: false },
|
||||
});
|
||||
}
|
||||
|
||||
async getWorkspaceUsers(ids: string[]): Promise<WorkspaceUser[]> {
|
||||
return this.db.user.findMany({
|
||||
select: workspaceUserSelect,
|
||||
where: { id: { in: ids } },
|
||||
where: { id: { in: ids }, disabled: false },
|
||||
});
|
||||
}
|
||||
|
||||
async getUserByEmail(email: string): Promise<User | null> {
|
||||
async getUserByEmail(
|
||||
email: string,
|
||||
filter: UserFilter = {}
|
||||
): Promise<User | null> {
|
||||
const rows = await this.db.$queryRaw<User[]>`
|
||||
SELECT id, name, email, password, registered, email_verified as emailVerifiedAt, avatar_url as avatarUrl, registered, created_at as createdAt
|
||||
FROM "users"
|
||||
WHERE lower("email") = lower(${email})
|
||||
${Prisma.raw(filter.withDisabled ? '' : 'AND disabled = false')}
|
||||
`;
|
||||
|
||||
return rows[0] ?? null;
|
||||
@@ -141,23 +144,14 @@ export class UserModel extends BaseModel {
|
||||
SELECT id, name, avatar_url as avatarUrl
|
||||
FROM "users"
|
||||
WHERE lower("email") = lower(${email})
|
||||
`;
|
||||
|
||||
return rows[0] ?? null;
|
||||
}
|
||||
|
||||
async getWorkspaceUserByEmail(email: string): Promise<WorkspaceUser | null> {
|
||||
const rows = await this.db.$queryRaw<WorkspaceUser[]>`
|
||||
SELECT id, name, email, avatar_url as avatarUrl
|
||||
FROM "users"
|
||||
WHERE lower("email") = lower(${email})
|
||||
AND disabled = false
|
||||
`;
|
||||
|
||||
return rows[0] ?? null;
|
||||
}
|
||||
|
||||
async create(data: CreateUserInput) {
|
||||
let user = await this.getUserByEmail(data.email);
|
||||
let user = await this.getUserByEmail(data.email, { withDisabled: true });
|
||||
|
||||
if (user) {
|
||||
throw new EmailAlreadyUsed();
|
||||
@@ -183,13 +177,16 @@ export class UserModel extends BaseModel {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Transactional()
|
||||
async update(id: string, data: UpdateUserInput) {
|
||||
if (data.password) {
|
||||
data.password = await this.crypto.encryptPassword(data.password);
|
||||
}
|
||||
|
||||
if (data.email) {
|
||||
const user = await this.getUserByEmail(data.email);
|
||||
const user = await this.getUserByEmail(data.email, {
|
||||
withDisabled: true,
|
||||
});
|
||||
if (user && user.id !== id) {
|
||||
throw new EmailAlreadyUsed();
|
||||
}
|
||||
@@ -211,7 +208,7 @@ export class UserModel extends BaseModel {
|
||||
* When user created by others invitation, we will leave it as unregistered.
|
||||
*/
|
||||
async fulfill(email: string, data: Omit<UpdateUserInput, 'email'> = {}) {
|
||||
const user = await this.getUserByEmail(email);
|
||||
const user = await this.getUserByEmail(email, { withDisabled: true });
|
||||
|
||||
if (!user) {
|
||||
return this.create({
|
||||
@@ -258,6 +255,30 @@ export class UserModel extends BaseModel {
|
||||
return user;
|
||||
}
|
||||
|
||||
async ban(id: string) {
|
||||
// ban an user barely share the same logic with delete an user,
|
||||
// but keep the record with `disabled` flag
|
||||
// we delete the account and create it again to trigger all cleanups
|
||||
let user = await this.delete(id);
|
||||
user = await this.db.user.create({
|
||||
data: {
|
||||
...omit(user, 'id'),
|
||||
disabled: true,
|
||||
},
|
||||
});
|
||||
|
||||
await this.event.emitAsync('user.postCreated', user);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
async enable(id: string) {
|
||||
return await this.db.user.update({
|
||||
where: { id },
|
||||
data: { disabled: false },
|
||||
});
|
||||
}
|
||||
|
||||
async pagination(skip: number = 0, take: number = 20, after?: Date) {
|
||||
return this.db.user.findMany({
|
||||
where: {
|
||||
|
||||
@@ -196,6 +196,14 @@ export class WorkspaceUserModel extends BaseModel {
|
||||
});
|
||||
}
|
||||
|
||||
async deleteByUserId(userId: string) {
|
||||
await this.db.workspaceUserRole.deleteMany({
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async get(workspaceId: string, userId: string) {
|
||||
return await this.db.workspaceUserRole.findUnique({
|
||||
where: {
|
||||
|
||||
Reference in New Issue
Block a user