2025-09-27 20:45:36 -04:00
|
|
|
|
2025-09-27 11:13:37 -04:00
|
|
|
import {
|
|
|
|
|
Message,
|
|
|
|
|
MessagePing,
|
|
|
|
|
PrismaClient,
|
|
|
|
|
Role,
|
|
|
|
|
UserAuth,
|
|
|
|
|
} from "@prisma/client";
|
2025-09-27 15:55:20 -04:00
|
|
|
import { CreateUserInput } from "../validators/userValidator";
|
2025-09-27 15:31:49 -04:00
|
|
|
import shaHash from "../helper/hashing";
|
2025-09-27 11:13:37 -04:00
|
|
|
|
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
|
|
2025-09-27 15:31:49 -04:00
|
|
|
export async function createUser(data: CreateUserInput): Promise<{
|
2025-09-27 15:55:20 -04:00
|
|
|
username: string;
|
|
|
|
|
nickname: string | null;
|
|
|
|
|
bio: string | null;
|
|
|
|
|
picture: string | null;
|
|
|
|
|
banner: string | null;
|
|
|
|
|
status: string;
|
|
|
|
|
admin: boolean;
|
2025-09-27 15:31:49 -04:00
|
|
|
} | null> {
|
|
|
|
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
2025-09-27 15:55:20 -04:00
|
|
|
const requestingUserCredentials = await getUserCredentials(
|
|
|
|
|
data.requestingUserId,
|
|
|
|
|
);
|
|
|
|
|
if (
|
|
|
|
|
!requestingUser ||
|
|
|
|
|
!requestingUserCredentials ||
|
|
|
|
|
!requestingUser.admin ||
|
|
|
|
|
requestingUserCredentials.token == null ||
|
|
|
|
|
data.requestingUserToken != requestingUserCredentials.token
|
|
|
|
|
) {
|
2025-09-27 15:31:49 -04:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-27 15:55:20 -04:00
|
|
|
if ((await prisma.user.count({ where: { username: data.username } })) >= 1) {
|
2025-09-27 14:17:15 -04:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-27 15:31:49 -04:00
|
|
|
const userData = await prisma.user.create({
|
2025-09-27 13:04:35 -04:00
|
|
|
data: {
|
|
|
|
|
username: data.username,
|
|
|
|
|
nickname: data.nickname,
|
|
|
|
|
bio: data.bio,
|
|
|
|
|
picture: data.picture,
|
|
|
|
|
banner: data.banner,
|
|
|
|
|
status: data.status,
|
|
|
|
|
admin: data.admin,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-09-27 15:31:49 -04:00
|
|
|
|
2025-09-27 15:55:20 -04:00
|
|
|
if (
|
|
|
|
|
!(await prisma.userAuth.create({
|
|
|
|
|
data: {
|
|
|
|
|
userId: userData.id,
|
|
|
|
|
password: shaHash(data.passwordhash, userData.id),
|
|
|
|
|
token: null,
|
|
|
|
|
},
|
|
|
|
|
}))
|
|
|
|
|
) {
|
2025-09-27 15:31:49 -04:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return userData;
|
2025-09-27 13:04:35 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-27 15:31:49 -04:00
|
|
|
export async function getUserCredentials(userId: string): Promise<{
|
2025-09-27 15:55:20 -04:00
|
|
|
userId: string;
|
|
|
|
|
password: string;
|
|
|
|
|
token: string | null;
|
|
|
|
|
} | null> {
|
|
|
|
|
try {
|
|
|
|
|
if (!userId) {
|
|
|
|
|
throw new Error("missing userId");
|
|
|
|
|
}
|
2025-09-27 15:31:49 -04:00
|
|
|
|
2025-09-27 15:55:20 -04:00
|
|
|
const userAuth = await prisma.userAuth.findUnique({
|
|
|
|
|
where: {
|
|
|
|
|
userId: userId,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-09-27 15:31:49 -04:00
|
|
|
|
2025-09-27 15:55:20 -04:00
|
|
|
if (!userAuth) {
|
|
|
|
|
throw new Error("could not find user credentials");
|
|
|
|
|
}
|
2025-09-27 15:31:49 -04:00
|
|
|
|
2025-09-27 15:55:20 -04:00
|
|
|
return {
|
|
|
|
|
userId: userAuth.userId,
|
|
|
|
|
password: userAuth.password,
|
|
|
|
|
token: userAuth.token,
|
|
|
|
|
};
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errMessage = err as Error;
|
2025-09-27 15:31:49 -04:00
|
|
|
|
2025-09-27 15:55:20 -04:00
|
|
|
if (errMessage.message === "missing userId") {
|
|
|
|
|
console.log("services::actions::getUserCredentials - missing userId");
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2025-09-27 15:31:49 -04:00
|
|
|
|
2025-09-27 15:55:20 -04:00
|
|
|
if (errMessage.message === "could not find user credentials") {
|
2025-09-27 15:31:49 -04:00
|
|
|
console.log(
|
2025-09-27 15:55:20 -04:00
|
|
|
"services::actions::getUserCredentials - unable to find user credentials",
|
2025-09-27 15:31:49 -04:00
|
|
|
);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2025-09-27 15:55:20 -04:00
|
|
|
|
|
|
|
|
console.log(
|
|
|
|
|
"services::actions::getUserCredentials - unknown error",
|
|
|
|
|
errMessage,
|
|
|
|
|
);
|
|
|
|
|
return null;
|
2025-09-27 15:31:49 -04:00
|
|
|
}
|
2025-09-27 15:55:20 -04:00
|
|
|
}
|
2025-09-27 15:31:49 -04:00
|
|
|
|
2025-09-27 11:13:37 -04:00
|
|
|
export async function getUserInformation(userId: string): Promise<{
|
|
|
|
|
id: string;
|
|
|
|
|
userName: string;
|
|
|
|
|
nickName: string | null;
|
|
|
|
|
bio: string | null;
|
|
|
|
|
picture: string | null;
|
|
|
|
|
banner: string | null;
|
|
|
|
|
admin: boolean;
|
|
|
|
|
status: "online" | "offline" | "dnd" | "idle" | "invis";
|
|
|
|
|
role: Role[];
|
|
|
|
|
} | null> {
|
|
|
|
|
try {
|
|
|
|
|
if (!userId) {
|
|
|
|
|
throw new Error("missing userId");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const user = await prisma.user.findUnique({
|
|
|
|
|
where: {
|
|
|
|
|
id: userId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!user) {
|
|
|
|
|
throw new Error("could not find user");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const userRoles = await prisma.role.findMany({
|
|
|
|
|
where: {
|
|
|
|
|
userId: userId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
id: userId,
|
|
|
|
|
userName: user.username,
|
|
|
|
|
nickName: user.nickname,
|
|
|
|
|
bio: user.bio,
|
|
|
|
|
picture: user.picture,
|
|
|
|
|
banner: user.banner,
|
|
|
|
|
admin: user.admin,
|
|
|
|
|
status: (["online", "offline", "dnd", "idle", "invis"] as const).includes(
|
|
|
|
|
user.status as any,
|
|
|
|
|
)
|
|
|
|
|
? (user.status as "online" | "offline" | "dnd" | "idle" | "invis")
|
|
|
|
|
: "offline",
|
|
|
|
|
role: userRoles,
|
|
|
|
|
};
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errMessage = err as Error;
|
|
|
|
|
|
|
|
|
|
if (errMessage.message === "missing userId") {
|
|
|
|
|
console.log("services::actions::getUserInformation - missing userId");
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (errMessage.message === "could not find user") {
|
|
|
|
|
console.log(
|
|
|
|
|
"services::actions::getUserInformation - unable to find user",
|
|
|
|
|
);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log(
|
|
|
|
|
"services::actions::getUserInformation - unknown error",
|
|
|
|
|
errMessage,
|
|
|
|
|
);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getAllUsersFrom(instanceId: string): Promise<
|
|
|
|
|
| {
|
|
|
|
|
id: string;
|
|
|
|
|
userName: string;
|
|
|
|
|
nickName: string | null;
|
|
|
|
|
bio: string | null;
|
|
|
|
|
picture: string | null;
|
|
|
|
|
banner: string | null;
|
|
|
|
|
admin: boolean;
|
|
|
|
|
status: "online" | "offline" | "dnd" | "idle" | "invis";
|
|
|
|
|
role: {
|
|
|
|
|
userId: string;
|
|
|
|
|
instanceId: string;
|
|
|
|
|
}[];
|
|
|
|
|
}[]
|
|
|
|
|
| null
|
|
|
|
|
> {
|
|
|
|
|
try {
|
2025-09-27 14:17:15 -04:00
|
|
|
const instances = await prisma.instance.count({
|
|
|
|
|
where: {
|
2025-09-27 15:55:20 -04:00
|
|
|
id: instanceId,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-09-27 14:17:15 -04:00
|
|
|
if (instances < 1) {
|
|
|
|
|
throw new Error("could not find given instance id");
|
2025-09-27 11:13:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const users = await prisma.user.findMany({
|
|
|
|
|
where: {
|
|
|
|
|
Role: {
|
|
|
|
|
some: {
|
|
|
|
|
instanceId: instanceId,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!users) {
|
|
|
|
|
throw new Error("could not get all users in instance");
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-27 12:26:24 -04:00
|
|
|
const admins = await prisma.user.findMany({
|
|
|
|
|
where: {
|
2025-09-27 15:55:20 -04:00
|
|
|
admin: true,
|
|
|
|
|
},
|
2025-09-27 12:26:24 -04:00
|
|
|
});
|
|
|
|
|
if (!admins) {
|
|
|
|
|
throw new Error("could not get all admins");
|
|
|
|
|
}
|
|
|
|
|
const adminData = await Promise.all(
|
|
|
|
|
admins.map(async (u) => {
|
|
|
|
|
const adminRoles = await prisma.role.findMany({
|
|
|
|
|
where: {
|
|
|
|
|
userId: u.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!adminRoles) {
|
|
|
|
|
throw new Error("could not get admin roles for admin " + u.id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
id: u.id,
|
|
|
|
|
userName: u.username,
|
|
|
|
|
nickName: u.nickname,
|
|
|
|
|
bio: u.bio,
|
|
|
|
|
picture: u.picture,
|
|
|
|
|
banner: u.banner,
|
|
|
|
|
admin: u.admin,
|
|
|
|
|
status: (
|
|
|
|
|
["online", "offline", "dnd", "idle", "invis"] as const
|
|
|
|
|
).includes(u.status as any)
|
|
|
|
|
? (u.status as "online" | "offline" | "dnd" | "idle" | "invis")
|
|
|
|
|
: "offline",
|
2025-09-27 15:55:20 -04:00
|
|
|
role: adminRoles.map((r) => ({
|
2025-09-27 12:26:24 -04:00
|
|
|
userId: r.userId,
|
|
|
|
|
instanceId: r.instanceId,
|
|
|
|
|
})),
|
2025-09-27 15:55:20 -04:00
|
|
|
};
|
|
|
|
|
}),
|
|
|
|
|
);
|
2025-09-27 12:26:24 -04:00
|
|
|
|
2025-09-27 11:13:37 -04:00
|
|
|
const userData = await Promise.all(
|
|
|
|
|
users.map(async (u) => {
|
|
|
|
|
const userRoles = await prisma.role.findMany({
|
|
|
|
|
where: {
|
|
|
|
|
userId: u.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!userRoles) {
|
|
|
|
|
throw new Error("could not get user roles for user " + u.id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
id: u.id,
|
|
|
|
|
userName: u.username,
|
|
|
|
|
nickName: u.nickname,
|
|
|
|
|
bio: u.bio,
|
|
|
|
|
picture: u.picture,
|
|
|
|
|
banner: u.banner,
|
|
|
|
|
admin: u.admin,
|
|
|
|
|
status: (
|
|
|
|
|
["online", "offline", "dnd", "idle", "invis"] as const
|
|
|
|
|
).includes(u.status as any)
|
|
|
|
|
? (u.status as "online" | "offline" | "dnd" | "idle" | "invis")
|
|
|
|
|
: "offline",
|
|
|
|
|
role: userRoles,
|
|
|
|
|
};
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
2025-09-27 12:26:24 -04:00
|
|
|
return userData.concat(adminData);
|
2025-09-27 11:13:37 -04:00
|
|
|
} catch (err) {
|
|
|
|
|
console.log(err);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|