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';
|
2023-09-03 13:05:22 +00:00
|
|
|
import { jwtVerify } from '../middleware/auth';
|
2023-10-20 15:12:42 +00:00
|
|
|
import { TRPCError } from '@trpc/server';
|
2023-11-12 15:49:02 +00:00
|
|
|
import { Prisma } from '@prisma/client';
|
2023-09-02 12:13:50 +00:00
|
|
|
|
|
|
|
async function hashPassword(password: string) {
|
|
|
|
return await bcryptjs.hash(password, 10);
|
|
|
|
}
|
|
|
|
|
2023-09-03 13:05:22 +00:00
|
|
|
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,
|
2023-11-12 15:49:02 +00:00
|
|
|
dashboardLayout: true,
|
2023-09-03 13:05:22 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
workspaces: {
|
|
|
|
select: {
|
|
|
|
role: true,
|
|
|
|
workspace: {
|
|
|
|
select: {
|
|
|
|
id: true,
|
|
|
|
name: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-11-12 15:49:02 +00:00
|
|
|
} satisfies Prisma.UserSelect;
|
2023-09-03 13:05:22 +00:00
|
|
|
|
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) {
|
2023-09-03 13:05:22 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2023-09-03 13:30:19 +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
|
|
|
},
|
2023-09-03 13:05:22 +00:00
|
|
|
select: createUserSelect,
|
2023-09-02 12:13:50 +00:00
|
|
|
});
|
2023-09-03 06:38:38 +00:00
|
|
|
|
|
|
|
if (user.workspaces[0]) {
|
2023-09-03 13:30:19 +00:00
|
|
|
user = await prisma.user.update({
|
2023-09-03 06:38:38 +00:00
|
|
|
where: {
|
|
|
|
id: user.id,
|
|
|
|
},
|
|
|
|
data: {
|
2023-09-03 13:05:22 +00:00
|
|
|
currentWorkspaceId: user.workspaces[0].workspace.id,
|
2023-09-03 06:38:38 +00:00
|
|
|
},
|
2023-09-03 13:30:19 +00:00
|
|
|
select: createUserSelect,
|
2023-09-03 06:38:38 +00:00
|
|
|
});
|
|
|
|
}
|
2023-09-03 13:05:22 +00:00
|
|
|
|
|
|
|
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');
|
|
|
|
}
|
|
|
|
|
2023-09-03 13:30:19 +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.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
|
|
|
},
|
2023-09-03 13:05:22 +00:00
|
|
|
select: createUserSelect,
|
2023-09-02 12:13:50 +00:00
|
|
|
});
|
2023-09-03 06:38:38 +00:00
|
|
|
|
|
|
|
if (user.workspaces[0]) {
|
2023-09-03 13:30:19 +00:00
|
|
|
user = await prisma.user.update({
|
2023-09-03 06:38:38 +00:00
|
|
|
where: {
|
|
|
|
id: user.id,
|
|
|
|
},
|
|
|
|
data: {
|
2023-09-03 13:05:22 +00:00
|
|
|
currentWorkspaceId: user.workspaces[0].workspace.id,
|
2023-09-03 06:38:38 +00:00
|
|
|
},
|
2023-09-03 13:30:19 +00:00
|
|
|
select: createUserSelect,
|
2023-09-03 06:38:38 +00:00
|
|
|
});
|
|
|
|
}
|
2023-09-03 13:05:22 +00:00
|
|
|
|
|
|
|
return user;
|
2023-09-02 12:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function authUser(username: string, password: string) {
|
2023-09-03 13:05:22 +00:00
|
|
|
const user = await prisma.user.findUnique({
|
2023-09-02 12:13:50 +00:00
|
|
|
where: {
|
|
|
|
username,
|
|
|
|
},
|
2023-09-03 13:05:22 +00:00
|
|
|
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
|
|
|
},
|
2023-09-03 13:05:22 +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) {
|
2023-09-03 06:38:38 +00:00
|
|
|
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;
|
|
|
|
}
|
2023-10-20 15:12:42 +00:00
|
|
|
|
|
|
|
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),
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|