tianji/src/server/model/user.ts

232 lines
4.5 KiB
TypeScript
Raw Normal View History

2023-09-02 12:13:50 +00:00
import { prisma } from './_client';
import bcryptjs from 'bcryptjs';
2023-09-26 06:45:28 +00:00
import { ROLES, SYSTEM_ROLES } from '../utils/const';
import { jwtVerify } from '../middleware/auth';
import { TRPCError } from '@trpc/server';
import { Prisma } from '@prisma/client';
2023-09-02 12:13:50 +00:00
async function hashPassword(password: string) {
return await bcryptjs.hash(password, 10);
}
function comparePassword(password: string, hash: string): Promise<boolean> {
return bcryptjs.compare(password, hash);
}
export async function getUserCount(): Promise<number> {
const count = await prisma.user.count();
return count;
}
const createUserSelect = {
id: true,
username: true,
role: true,
createdAt: true,
updatedAt: true,
deletedAt: true,
currentWorkspace: {
select: {
id: true,
name: true,
2023-10-16 16:23:49 +00:00
dashboardOrder: true,
dashboardLayout: true,
},
},
workspaces: {
select: {
role: true,
workspace: {
select: {
id: true,
name: true,
},
},
},
},
} satisfies Prisma.UserSelect;
2023-09-02 12:13:50 +00:00
/**
* Create User
*/
export async function createAdminUser(username: string, password: string) {
const count = await prisma.user.count();
if (count > 0) {
throw new Error(
'Create Admin User Just Only allow in non people exist, you can Grant Privilege with admin user'
);
2023-09-02 12:13:50 +00:00
}
let user = await prisma.user.create({
2023-09-02 12:13:50 +00:00
data: {
username,
password: await hashPassword(password),
2023-09-26 06:45:28 +00:00
role: SYSTEM_ROLES.admin,
2023-09-02 19:49:20 +00:00
workspaces: {
create: [
{
role: ROLES.owner,
workspace: {
create: {
name: username,
},
},
},
],
},
2023-09-02 12:13:50 +00:00
},
select: createUserSelect,
2023-09-02 12:13:50 +00:00
});
if (user.workspaces[0]) {
user = await prisma.user.update({
where: {
id: user.id,
},
data: {
currentWorkspaceId: user.workspaces[0].workspace.id,
},
select: createUserSelect,
});
}
return user;
2023-09-02 12:13:50 +00:00
}
export async function createUser(username: string, password: string) {
2023-09-02 19:49:20 +00:00
const existCount = await prisma.user.count({
where: {
username,
},
});
if (existCount > 0) {
throw new Error('User already exists');
}
let user = await prisma.user.create({
2023-09-02 12:13:50 +00:00
data: {
username,
password: await hashPassword(password),
2023-09-26 06:45:28 +00:00
role: SYSTEM_ROLES.user,
2023-09-02 19:49:20 +00:00
workspaces: {
create: [
{
role: ROLES.owner,
workspace: {
create: {
name: username,
},
},
},
],
},
2023-09-02 12:13:50 +00:00
},
select: createUserSelect,
2023-09-02 12:13:50 +00:00
});
if (user.workspaces[0]) {
user = await prisma.user.update({
where: {
id: user.id,
},
data: {
currentWorkspaceId: user.workspaces[0].workspace.id,
},
select: createUserSelect,
});
}
return user;
2023-09-02 12:13:50 +00:00
}
export async function authUser(username: string, password: string) {
const user = await prisma.user.findUnique({
2023-09-02 12:13:50 +00:00
where: {
username,
},
select: { ...createUserSelect, password: true },
});
if (!user) {
throw new Error('User not existed');
}
const checkPassword = await comparePassword(password, user.password);
if (!checkPassword) {
throw new Error('Password incorrected');
}
delete (user as any)['password'];
return user;
}
export async function authUserWithToken(token: string) {
const payload = jwtVerify(token);
const id = payload.id;
const user = await prisma.user.findUniqueOrThrow({
where: {
id,
2023-09-02 19:49:20 +00:00
},
select: createUserSelect,
2023-09-02 12:13:50 +00:00
});
return user;
}
2023-09-02 17:01:55 +00:00
export async function findUser(userId: string) {
const user = await prisma.user.findUnique({
2023-09-02 17:01:55 +00:00
where: {
id: userId,
},
select: {
id: true,
username: true,
role: true,
},
});
return user;
}
export async function changeUserPassword(
userId: string,
oldPassword: string,
newPassword: string
) {
const user = await prisma.user.findUnique({
where: {
id: userId,
},
});
if (!user) {
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'user not found',
});
}
const checkPassword = await comparePassword(oldPassword, user.password);
if (!checkPassword) {
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'old password not correct',
});
}
return prisma.user.update({
where: {
id: userId,
},
data: {
password: await hashPassword(newPassword),
},
});
}