made pretty and fixed message posting
This commit is contained in:
@@ -1,127 +1,126 @@
|
||||
import { Context } from "hono";
|
||||
import { sendMessageToChannel, removeMessageFromChannel } from "../services/realtime.js"
|
||||
import {
|
||||
sendMessageToChannel,
|
||||
removeMessageFromChannel,
|
||||
} from "../services/realtime.js";
|
||||
import { success } from "zod";
|
||||
|
||||
export async function postMessageToChannel(io: any, c: Context) {
|
||||
try {
|
||||
io = c.get("io");
|
||||
|
||||
export async function postMessageToChannel(
|
||||
io: any,
|
||||
c: Context
|
||||
) {
|
||||
try {
|
||||
io = c.get("io");
|
||||
const instanceId = c.req.param("instanceId");
|
||||
const categoryId = c.req.param("categoryId");
|
||||
const channelId = c.req.param("channelId");
|
||||
const message = await c.req.json();
|
||||
|
||||
const instanceId = c.req.param("instanceId");
|
||||
const categoryId = c.req.param("categoryId");
|
||||
const channelId = c.req.param("channelId");
|
||||
const message = await c.req.json();
|
||||
|
||||
const result = await sendMessageToChannel(
|
||||
instanceId,
|
||||
categoryId,
|
||||
channelId,
|
||||
message,
|
||||
"new_channel_message",
|
||||
io
|
||||
)
|
||||
const result = await sendMessageToChannel(
|
||||
instanceId,
|
||||
categoryId,
|
||||
channelId,
|
||||
message,
|
||||
"new_channel_message",
|
||||
io,
|
||||
);
|
||||
|
||||
if(result === "Event not implemented"){
|
||||
console.log("controller::realtime::postMessageToChannel - Failed to send message")
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "Event not implemented or recognized",
|
||||
status: 400
|
||||
})
|
||||
}
|
||||
|
||||
if(result === "no acknowledgment"){
|
||||
console.log("controller::realtime::postMessageToChannel - No acknowledgment received from client")
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "No acknowledgment received from client",
|
||||
status: 500
|
||||
})
|
||||
}
|
||||
|
||||
if(!result){
|
||||
throw new Error("failed to send message");
|
||||
}
|
||||
|
||||
return c.json({
|
||||
success: true,
|
||||
message: "Message sent successfully",
|
||||
status: 200
|
||||
})
|
||||
|
||||
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
console.log("controller::realtime::postMessageToChannel - ", errMessage);
|
||||
return c.json({
|
||||
success: false,
|
||||
message: errMessage.message,
|
||||
status: 500
|
||||
});
|
||||
if (result === "Event not implemented") {
|
||||
console.log(
|
||||
"controller::realtime::postMessageToChannel - Failed to send message",
|
||||
);
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "Event not implemented or recognized",
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
if (result === "no acknowledgment") {
|
||||
console.log(
|
||||
"controller::realtime::postMessageToChannel - No acknowledgment received from client",
|
||||
);
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "No acknowledgment received from client",
|
||||
status: 500,
|
||||
});
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
throw new Error("failed to send message");
|
||||
}
|
||||
|
||||
return c.json({
|
||||
success: true,
|
||||
message: "Message sent successfully",
|
||||
status: 200,
|
||||
});
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
console.log("controller::realtime::postMessageToChannel - ", errMessage);
|
||||
return c.json({
|
||||
success: false,
|
||||
message: errMessage.message,
|
||||
status: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteMessageFromChannel(
|
||||
io: any,
|
||||
c: Context
|
||||
){
|
||||
try {
|
||||
export async function deleteMessageFromChannel(io: any, c: Context) {
|
||||
try {
|
||||
io = c.get("io");
|
||||
|
||||
io = c.get("io");
|
||||
const instanceId = c.req.param("instanceId");
|
||||
const categoryId = c.req.param("categoryId");
|
||||
const channelId = c.req.param("channelId");
|
||||
const messageId = c.req.param("messageId");
|
||||
|
||||
const instanceId = c.req.param("instanceId");
|
||||
const categoryId = c.req.param("categoryId");
|
||||
const channelId = c.req.param("channelId");
|
||||
const messageId = c.req.param("messageId");
|
||||
const result = await removeMessageFromChannel(
|
||||
instanceId,
|
||||
categoryId,
|
||||
channelId,
|
||||
messageId,
|
||||
"delete_channel_message",
|
||||
io,
|
||||
);
|
||||
|
||||
const result = await removeMessageFromChannel(
|
||||
instanceId,
|
||||
categoryId,
|
||||
channelId,
|
||||
messageId,
|
||||
"delete_channel_message",
|
||||
io
|
||||
)
|
||||
|
||||
if(result === "event not implemented"){
|
||||
console.log("controller::realtime::deleteMessageFromChannel - Event not implemented")
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "Event not implemented or recognized",
|
||||
status: 400
|
||||
});
|
||||
}
|
||||
|
||||
if(result === "no acknowledgment"){
|
||||
console.log("controller::realtime::deleteMessageFromChannel - No acknowledgment received from client")
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "No acknowledgment received from client",
|
||||
status: 500
|
||||
});
|
||||
}
|
||||
|
||||
if(!result){
|
||||
throw new Error("failed to delete message");
|
||||
}
|
||||
|
||||
c.json({
|
||||
success: true,
|
||||
message: "Message deleted successfully",
|
||||
status: 200
|
||||
})
|
||||
|
||||
} catch (err) {
|
||||
|
||||
const errMessage = err as Error;
|
||||
console.log("services::realtime::deleteMessageFromChannel - ", errMessage);
|
||||
return c.json({
|
||||
success: false,
|
||||
message: errMessage.message,
|
||||
status: 500
|
||||
});
|
||||
if (result === "event not implemented") {
|
||||
console.log(
|
||||
"controller::realtime::deleteMessageFromChannel - Event not implemented",
|
||||
);
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "Event not implemented or recognized",
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
if (result === "no acknowledgment") {
|
||||
console.log(
|
||||
"controller::realtime::deleteMessageFromChannel - No acknowledgment received from client",
|
||||
);
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "No acknowledgment received from client",
|
||||
status: 500,
|
||||
});
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
throw new Error("failed to delete message");
|
||||
}
|
||||
|
||||
c.json({
|
||||
success: true,
|
||||
message: "Message deleted successfully",
|
||||
status: 200,
|
||||
});
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
console.log("services::realtime::deleteMessageFromChannel - ", errMessage);
|
||||
return c.json({
|
||||
success: false,
|
||||
message: errMessage.message,
|
||||
status: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { getAllUsersFrom, getUserInformation, createUser } from "../services/userService";
|
||||
import {
|
||||
getAllUsersFrom,
|
||||
getUserInformation,
|
||||
createUser,
|
||||
} from "../services/userService";
|
||||
import { CreateUserInput } from "../validators/userValidator";
|
||||
|
||||
export async function fetchUserData(id: string) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as crypto from 'crypto';
|
||||
import * as crypto from "crypto";
|
||||
|
||||
export default function shaHash(data:string, salt:string) : string {
|
||||
return crypto.createHmac('sha256', salt).update(data).digest('hex');
|
||||
export default function shaHash(data: string, salt: string): string {
|
||||
return crypto.createHmac("sha256", salt).update(data).digest("hex");
|
||||
}
|
||||
|
||||
@@ -53,21 +53,19 @@ app.use(
|
||||
app.route("/api", routes);
|
||||
|
||||
app.get(
|
||||
'/openapi',
|
||||
"/openapi",
|
||||
openAPIRouteHandler(app, {
|
||||
documentation: {
|
||||
info: {
|
||||
title: 'Hono API',
|
||||
version: '1.0.0',
|
||||
description: 'Greeting API',
|
||||
title: "Hono API",
|
||||
version: "1.0.0",
|
||||
description: "Greeting API",
|
||||
},
|
||||
servers: [
|
||||
{ url: 'http://localhost:3000', description: 'Local Server' },
|
||||
],
|
||||
servers: [{ url: "http://localhost:3000", description: "Local Server" }],
|
||||
},
|
||||
})
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
||||
app.get('/scalar', Scalar({ url: '/openapi' }))
|
||||
app.get("/scalar", Scalar({ url: "/openapi" }));
|
||||
|
||||
export default app;
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
import { Hono } from "hono";
|
||||
import { zValidator } from "@hono/zod-validator";
|
||||
import { describeRoute, resolver } from "hono-openapi";
|
||||
import { postMessageToChannel,
|
||||
deleteMessageFromChannel
|
||||
import {
|
||||
postMessageToChannel,
|
||||
deleteMessageFromChannel,
|
||||
} from "../controller/realtime";
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
app.post(
|
||||
"message/",
|
||||
zValidator({
|
||||
body: z.object({
|
||||
content: z.string().min(1).max(500)
|
||||
})
|
||||
"message/",
|
||||
zValidator({
|
||||
body: z.object({
|
||||
content: z.string().min(1).max(500),
|
||||
}),
|
||||
async (c) => {
|
||||
const { instanceId, categoryId, channelId } = c.req.params;
|
||||
const { content } = c.req.body;
|
||||
}),
|
||||
async (c) => {
|
||||
const { instanceId, categoryId, channelId } = c.req.params;
|
||||
const { content } = c.req.body;
|
||||
|
||||
return postMessageToChannel(c.get("io"), {
|
||||
instanceId,
|
||||
categoryId,
|
||||
channelId,
|
||||
content
|
||||
});
|
||||
}
|
||||
);
|
||||
return postMessageToChannel(c.get("io"), {
|
||||
instanceId,
|
||||
categoryId,
|
||||
channelId,
|
||||
content,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,29 +1,38 @@
|
||||
import { Hono } from "hono";
|
||||
import { fetchAllUsers, fetchUserData, createNewUser } from "../controller/userController";
|
||||
import { createUserSchema, queryAllUsersByInstanceId, queryUserByIdSchema } from "../validators/userValidator";
|
||||
import {
|
||||
fetchAllUsers,
|
||||
fetchUserData,
|
||||
createNewUser,
|
||||
} from "../controller/userController";
|
||||
import {
|
||||
createUserSchema,
|
||||
queryAllUsersByInstanceId,
|
||||
queryUserByIdSchema,
|
||||
} from "../validators/userValidator";
|
||||
import { zValidator } from "@hono/zod-validator";
|
||||
import { describeRoute, resolver } from "hono-openapi";
|
||||
const actions = new Hono();
|
||||
|
||||
actions.get("user/:id",
|
||||
actions.get(
|
||||
"user/:id",
|
||||
describeRoute({
|
||||
description: "Get user by id",
|
||||
responses: {
|
||||
200: {
|
||||
description: "Success getting user",
|
||||
content: {
|
||||
"application/json": { schema: resolver(queryUserByIdSchema) }
|
||||
}
|
||||
"application/json": { schema: resolver(queryUserByIdSchema) },
|
||||
},
|
||||
},
|
||||
404: {
|
||||
description: "User id not found",
|
||||
content: {
|
||||
"application/json": { schema: resolver(queryUserByIdSchema) }
|
||||
}
|
||||
}
|
||||
}
|
||||
"application/json": { schema: resolver(queryUserByIdSchema) },
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator('param', queryUserByIdSchema),
|
||||
zValidator("param", queryUserByIdSchema),
|
||||
async (c) => {
|
||||
const id = c.req.param("id");
|
||||
const userData = await fetchUserData(id);
|
||||
@@ -32,22 +41,23 @@ actions.get("user/:id",
|
||||
} else {
|
||||
return c.json({ error: "User not found" }, 404);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
actions.get("user",
|
||||
actions.get(
|
||||
"user",
|
||||
describeRoute({
|
||||
description: "Get all users by instance id",
|
||||
responses: {
|
||||
200: {
|
||||
description: "Success getting all users in instance",
|
||||
content: {
|
||||
"application/json": { schema: resolver(queryAllUsersByInstanceId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
"application/json": { schema: resolver(queryAllUsersByInstanceId) },
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator('query', queryAllUsersByInstanceId),
|
||||
zValidator("query", queryAllUsersByInstanceId),
|
||||
async (c) => {
|
||||
const instanceId = c.req.query("instanceId");
|
||||
if (!instanceId) {
|
||||
@@ -60,7 +70,7 @@ actions.get("user",
|
||||
} else {
|
||||
return c.json({ error: "Error getting all users from instance" }, 500);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
actions.post(
|
||||
@@ -71,18 +81,18 @@ actions.post(
|
||||
201: {
|
||||
description: "Success",
|
||||
content: {
|
||||
'application/json': { schema: resolver(createUserSchema) },
|
||||
"application/json": { schema: resolver(createUserSchema) },
|
||||
},
|
||||
},
|
||||
400: {
|
||||
description: "Bad request (user exists)",
|
||||
content: {
|
||||
'application/json': { schema: resolver(createUserSchema) }
|
||||
}
|
||||
}
|
||||
}
|
||||
"application/json": { schema: resolver(createUserSchema) },
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator('json', createUserSchema),
|
||||
zValidator("json", createUserSchema),
|
||||
async (c) => {
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
@@ -94,7 +104,7 @@ actions.post(
|
||||
} catch (error) {
|
||||
return c.json({ error: "Error creating user" }, 500);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export default actions;
|
||||
|
||||
@@ -3,75 +3,76 @@ import {
|
||||
MessagePing,
|
||||
PrismaClient,
|
||||
Role,
|
||||
Reply
|
||||
|
||||
Reply,
|
||||
} from "@prisma/client";
|
||||
import { CreateUserInput } from '../validators/userValidator';
|
||||
import { CreateUserInput } from "../validators/userValidator";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
class MessageService {
|
||||
public async function sendMessageToChannel(
|
||||
channelId: string,
|
||||
userId: string,
|
||||
content: string,
|
||||
repliedMessageId: string | null
|
||||
): Promise<{
|
||||
id: string,
|
||||
channelId: string,
|
||||
userId: string,
|
||||
text: string,
|
||||
deleted: boolean,
|
||||
replies: null | {
|
||||
messageId: string,
|
||||
repliesToId: string,
|
||||
repliesToText: string
|
||||
}
|
||||
} | null> {
|
||||
try {
|
||||
|
||||
|
||||
const newMessage = await prisma.message.create({
|
||||
data: {
|
||||
channelId: channelId,
|
||||
userId: userId,
|
||||
text: content,
|
||||
deleted: false,
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
let origMessage;
|
||||
if(repliedMessageId){
|
||||
origMessage = await prisma.message.findUnique({
|
||||
where: {
|
||||
id: repliedMessageId
|
||||
}
|
||||
})
|
||||
|
||||
if(!origMessage){
|
||||
throw new Error("could not find original message to reply to");
|
||||
}
|
||||
|
||||
await prisma.reply.create({
|
||||
data: {
|
||||
messageId: newMessage.id,
|
||||
repliesToId: origMessage.id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
...newMessage,
|
||||
replies: repliedMessageId ? {
|
||||
messageId: newMessage.id,
|
||||
repliesToId: origMessage?.id,
|
||||
repliesToText: origMessage?.text
|
||||
} : null
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
|
||||
export async function sendMessageToChannel(
|
||||
channelId: string,
|
||||
userId: string,
|
||||
content: string,
|
||||
repliedMessageId: string | null,
|
||||
): Promise<{
|
||||
id: string;
|
||||
channelId: string;
|
||||
userId: string;
|
||||
text: string;
|
||||
deleted: boolean;
|
||||
replies: null | {
|
||||
messageId: string;
|
||||
repliesToId: string;
|
||||
repliesToText: string;
|
||||
};
|
||||
} | null> {
|
||||
try {
|
||||
const newMessage = await prisma.message.create({
|
||||
data: {
|
||||
channelId: channelId,
|
||||
userId: userId,
|
||||
text: content,
|
||||
deleted: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (!newMessage) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
let origMessage;
|
||||
if (repliedMessageId) {
|
||||
origMessage = await prisma.message.findUnique({
|
||||
where: {
|
||||
id: repliedMessageId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!origMessage) {
|
||||
throw new Error("could not find original message to reply to");
|
||||
}
|
||||
|
||||
await prisma.reply.create({
|
||||
data: {
|
||||
messageId: newMessage.id,
|
||||
repliesToId: origMessage.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
...newMessage,
|
||||
channelId: newMessage.channelId!,
|
||||
userId: newMessage.userId!,
|
||||
replies: origMessage
|
||||
? {
|
||||
messageId: newMessage.id,
|
||||
repliesToId: origMessage?.id,
|
||||
repliesToText: origMessage?.text,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +1,90 @@
|
||||
import { readonly } from "zod";
|
||||
|
||||
const EVENTS = {
|
||||
NEW_CHANNEL_MESSAGE: "new_channel_message",
|
||||
DELETE_CHANNEL_MESSAGE: "delete_channel_message",
|
||||
}
|
||||
|
||||
|
||||
NEW_CHANNEL_MESSAGE: "new_channel_message",
|
||||
DELETE_CHANNEL_MESSAGE: "delete_channel_message",
|
||||
};
|
||||
|
||||
export async function sendMessageToChannel(
|
||||
instanceId: string,
|
||||
categoryId: string,
|
||||
channelId: string,
|
||||
message: any,
|
||||
event: string,
|
||||
io: any,
|
||||
instanceId: string,
|
||||
categoryId: string,
|
||||
channelId: string,
|
||||
message: any,
|
||||
event: string,
|
||||
io: any,
|
||||
): Promise<string | boolean> {
|
||||
try {
|
||||
|
||||
//TODO: implement middleware to replace this
|
||||
if(EVENTS.NEW_CHANNEL_MESSAGE === event){
|
||||
throw new Error("Event not implemented");
|
||||
}
|
||||
|
||||
//TODO: add prisma to save channel message to DB
|
||||
|
||||
return new Promise((resolve) => {
|
||||
io.to(instanceId).emit(event, message, (ack: any) => {
|
||||
if (ack && ack.status === 'received') {
|
||||
console.log(`Message ${ack.messageId} acknowledged by client.`);
|
||||
resolve(true);
|
||||
} else {
|
||||
console.log('services::realtime::sendMessageToChannel No acknowledgment received from client.');
|
||||
resolve("no acknowledgment");
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
if (errMessage.message === "Event not implemented") {
|
||||
console.log(`services::realtime::sendMessageToChannel - Event not implemented. Attempted event: ${event}`)
|
||||
return "event not implemented"
|
||||
}
|
||||
console.log("services::realtime::sendMessageToChannel - ", errMessage);
|
||||
return false;
|
||||
|
||||
try {
|
||||
//TODO: implement middleware to replace this
|
||||
if (EVENTS.NEW_CHANNEL_MESSAGE === event) {
|
||||
throw new Error("Event not implemented");
|
||||
}
|
||||
|
||||
//TODO: add prisma to save channel message to DB
|
||||
|
||||
return new Promise((resolve) => {
|
||||
io.to(instanceId).emit(event, message, (ack: any) => {
|
||||
if (ack && ack.status === "received") {
|
||||
console.log(`Message ${ack.messageId} acknowledged by client.`);
|
||||
resolve(true);
|
||||
} else {
|
||||
console.log(
|
||||
"services::realtime::sendMessageToChannel No acknowledgment received from client.",
|
||||
);
|
||||
resolve("no acknowledgment");
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
if (errMessage.message === "Event not implemented") {
|
||||
console.log(
|
||||
`services::realtime::sendMessageToChannel - Event not implemented. Attempted event: ${event}`,
|
||||
);
|
||||
return "event not implemented";
|
||||
}
|
||||
console.log("services::realtime::sendMessageToChannel - ", errMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function removeMessageFromChannel(
|
||||
instanceId: string,
|
||||
categoryId: string,
|
||||
channelId: string,
|
||||
messageId: string,
|
||||
event: string,
|
||||
io: any
|
||||
): Promise<string | boolean>{
|
||||
try {
|
||||
|
||||
//TODO: implement middleware to replace this
|
||||
if(EVENTS.DELETE_CHANNEL_MESSAGE === event){
|
||||
throw new Error("event not implemented");
|
||||
}
|
||||
|
||||
//TODO: add prisma to flag a channel message as deleted
|
||||
|
||||
return new Promise((resolve) => {
|
||||
io.to(instanceId).emit(event, { messageId }, (ack: any) => {
|
||||
if (ack && ack.status === 'received') {
|
||||
console.log(`Message ${ack.messageId} acknowledged by client.`);
|
||||
resolve(true);
|
||||
} else {
|
||||
console.log('services::realtime::deleteMessageFromChannel No acknowledgment received from client.');
|
||||
resolve("no acknowledgment");
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
if (errMessage.message === "Event not implemented") {
|
||||
console.log(`services::realtime::deleteMessageFromChannel - Event not implemented. Attempted event: ${event}`)
|
||||
return false;
|
||||
}
|
||||
console.log("services::realtime::deleteMessageFromChannel - ", errMessage);
|
||||
return false;
|
||||
|
||||
instanceId: string,
|
||||
categoryId: string,
|
||||
channelId: string,
|
||||
messageId: string,
|
||||
event: string,
|
||||
io: any,
|
||||
): Promise<string | boolean> {
|
||||
try {
|
||||
//TODO: implement middleware to replace this
|
||||
if (EVENTS.DELETE_CHANNEL_MESSAGE === event) {
|
||||
throw new Error("event not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: add prisma to flag a channel message as deleted
|
||||
|
||||
return new Promise((resolve) => {
|
||||
io.to(instanceId).emit(event, { messageId }, (ack: any) => {
|
||||
if (ack && ack.status === "received") {
|
||||
console.log(`Message ${ack.messageId} acknowledged by client.`);
|
||||
resolve(true);
|
||||
} else {
|
||||
console.log(
|
||||
"services::realtime::deleteMessageFromChannel No acknowledgment received from client.",
|
||||
);
|
||||
resolve("no acknowledgment");
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
if (errMessage.message === "Event not implemented") {
|
||||
console.log(
|
||||
`services::realtime::deleteMessageFromChannel - Event not implemented. Attempted event: ${event}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
console.log("services::realtime::deleteMessageFromChannel - ", errMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,31 +5,35 @@ import {
|
||||
Role,
|
||||
UserAuth,
|
||||
} from "@prisma/client";
|
||||
import { CreateUserInput } from '../validators/userValidator';
|
||||
import { CreateUserInput } from "../validators/userValidator";
|
||||
import shaHash from "../helper/hashing";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
export async function createUser(data: CreateUserInput): Promise<{
|
||||
username: string,
|
||||
nickname: string | null,
|
||||
bio: string | null,
|
||||
picture: string | null,
|
||||
banner: string | null,
|
||||
status: string,
|
||||
admin: boolean
|
||||
username: string;
|
||||
nickname: string | null;
|
||||
bio: string | null;
|
||||
picture: string | null;
|
||||
banner: string | null;
|
||||
status: string;
|
||||
admin: boolean;
|
||||
} | null> {
|
||||
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||
const requestingUserCredentials = await getUserCredentials(data.requestingUserId)
|
||||
if (!requestingUser
|
||||
|| !requestingUserCredentials
|
||||
|| !requestingUser.admin
|
||||
|| requestingUserCredentials.token == null
|
||||
|| data.requestingUserToken != requestingUserCredentials.token) {
|
||||
const requestingUserCredentials = await getUserCredentials(
|
||||
data.requestingUserId,
|
||||
);
|
||||
if (
|
||||
!requestingUser ||
|
||||
!requestingUserCredentials ||
|
||||
!requestingUser.admin ||
|
||||
requestingUserCredentials.token == null ||
|
||||
data.requestingUserToken != requestingUserCredentials.token
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (await prisma.user.count({ where: { username: data.username }}) >= 1) {
|
||||
if ((await prisma.user.count({ where: { username: data.username } })) >= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -45,13 +49,15 @@ export async function createUser(data: CreateUserInput): Promise<{
|
||||
},
|
||||
});
|
||||
|
||||
if (!(await prisma.userAuth.create({
|
||||
data: {
|
||||
userId: userData.id,
|
||||
password: shaHash(data.passwordhash, userData.id),
|
||||
token: null,
|
||||
}
|
||||
}))) {
|
||||
if (
|
||||
!(await prisma.userAuth.create({
|
||||
data: {
|
||||
userId: userData.id,
|
||||
password: shaHash(data.passwordhash, userData.id),
|
||||
token: null,
|
||||
},
|
||||
}))
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -59,52 +65,52 @@ export async function createUser(data: CreateUserInput): Promise<{
|
||||
}
|
||||
|
||||
export async function getUserCredentials(userId: string): Promise<{
|
||||
userId: string,
|
||||
password: string,
|
||||
token: string | null
|
||||
} | null> {
|
||||
try {
|
||||
if (!userId) {
|
||||
throw new Error("missing userId");
|
||||
}
|
||||
userId: string;
|
||||
password: string;
|
||||
token: string | null;
|
||||
} | null> {
|
||||
try {
|
||||
if (!userId) {
|
||||
throw new Error("missing userId");
|
||||
}
|
||||
|
||||
const userAuth = await prisma.userAuth.findUnique({
|
||||
where: {
|
||||
userId: userId,
|
||||
},
|
||||
});
|
||||
const userAuth = await prisma.userAuth.findUnique({
|
||||
where: {
|
||||
userId: userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!userAuth) {
|
||||
throw new Error("could not find user credentials");
|
||||
}
|
||||
if (!userAuth) {
|
||||
throw new Error("could not find user credentials");
|
||||
}
|
||||
|
||||
return {
|
||||
userId: userAuth.userId,
|
||||
password: userAuth.password,
|
||||
token: userAuth.token,
|
||||
};
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
return {
|
||||
userId: userAuth.userId,
|
||||
password: userAuth.password,
|
||||
token: userAuth.token,
|
||||
};
|
||||
} catch (err) {
|
||||
const errMessage = err as Error;
|
||||
|
||||
if (errMessage.message === "missing userId") {
|
||||
console.log("services::actions::getUserCredentials - missing userId");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (errMessage.message === "could not find user credentials") {
|
||||
console.log(
|
||||
"services::actions::getUserCredentials - unable to find user credentials",
|
||||
);
|
||||
return null;
|
||||
}
|
||||
if (errMessage.message === "missing userId") {
|
||||
console.log("services::actions::getUserCredentials - missing userId");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (errMessage.message === "could not find user credentials") {
|
||||
console.log(
|
||||
"services::actions::getUserCredentials - unknown error",
|
||||
errMessage,
|
||||
"services::actions::getUserCredentials - unable to find user credentials",
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"services::actions::getUserCredentials - unknown error",
|
||||
errMessage,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUserInformation(userId: string): Promise<{
|
||||
id: string;
|
||||
@@ -196,9 +202,9 @@ export async function getAllUsersFrom(instanceId: string): Promise<
|
||||
try {
|
||||
const instances = await prisma.instance.count({
|
||||
where: {
|
||||
id: instanceId
|
||||
}
|
||||
})
|
||||
id: instanceId,
|
||||
},
|
||||
});
|
||||
if (instances < 1) {
|
||||
throw new Error("could not find given instance id");
|
||||
}
|
||||
@@ -218,8 +224,8 @@ export async function getAllUsersFrom(instanceId: string): Promise<
|
||||
|
||||
const admins = await prisma.user.findMany({
|
||||
where: {
|
||||
admin: true
|
||||
}
|
||||
admin: true,
|
||||
},
|
||||
});
|
||||
if (!admins) {
|
||||
throw new Error("could not get all admins");
|
||||
@@ -249,13 +255,13 @@ export async function getAllUsersFrom(instanceId: string): Promise<
|
||||
).includes(u.status as any)
|
||||
? (u.status as "online" | "offline" | "dnd" | "idle" | "invis")
|
||||
: "offline",
|
||||
role: adminRoles.map(r => ({
|
||||
role: adminRoles.map((r) => ({
|
||||
userId: r.userId,
|
||||
instanceId: r.instanceId,
|
||||
})),
|
||||
}
|
||||
})
|
||||
)
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
const userData = await Promise.all(
|
||||
users.map(async (u) => {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { z } from 'zod'
|
||||
import { z } from "zod";
|
||||
|
||||
export const queryUserByIdSchema = z.object({
|
||||
id: z.uuidv7()
|
||||
})
|
||||
id: z.uuidv7(),
|
||||
});
|
||||
|
||||
export const queryAllUsersByInstanceId = z.object({
|
||||
instanceId: z.uuidv7()
|
||||
})
|
||||
instanceId: z.uuidv7(),
|
||||
});
|
||||
|
||||
export const createUserSchema = z.object({
|
||||
username: z.string().min(3).max(30),
|
||||
@@ -14,13 +14,17 @@ export const createUserSchema = z.object({
|
||||
bio: z.string().max(500).optional(),
|
||||
picture: z.url().optional(),
|
||||
banner: z.url().optional(),
|
||||
status: z.enum(['online', 'offline', 'dnd', 'idle', 'invis']).default('online'),
|
||||
status: z
|
||||
.enum(["online", "offline", "dnd", "idle", "invis"])
|
||||
.default("online"),
|
||||
admin: z.boolean().default(false),
|
||||
requestingUserId: z.uuidv7(),
|
||||
requestingUserToken: z.uuidv4(),
|
||||
passwordhash: z.string(),
|
||||
})
|
||||
});
|
||||
|
||||
export type QueryUserByIdInput = z.infer<typeof queryUserByIdSchema>
|
||||
export type QueryAllUsersByInstanceIdInput = z.infer<typeof queryAllUsersByInstanceId>
|
||||
export type CreateUserInput = z.infer<typeof createUserSchema>
|
||||
export type QueryUserByIdInput = z.infer<typeof queryUserByIdSchema>;
|
||||
export type QueryAllUsersByInstanceIdInput = z.infer<
|
||||
typeof queryAllUsersByInstanceId
|
||||
>;
|
||||
export type CreateUserInput = z.infer<typeof createUserSchema>;
|
||||
|
||||
Reference in New Issue
Block a user