All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m1s
61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import { Body, Controller, Post, Request, Route, Security } from "tsoa";
|
|
import { sendWebSocket } from "../services/webSocket";
|
|
import { RequestWithUser } from "../middlewares/user";
|
|
|
|
@Route("/api/v1/org/through-socket")
|
|
export class SocketController extends Controller {
|
|
@Post("notify")
|
|
async notify(
|
|
@Body()
|
|
payload: {
|
|
message: string;
|
|
userId?: string | string[];
|
|
roles?: string | string[];
|
|
error?: boolean;
|
|
},
|
|
) {
|
|
sendWebSocket(
|
|
"socket-notification",
|
|
{ success: !payload.error, message: payload.message },
|
|
{
|
|
roles: payload.roles || [],
|
|
userId: payload.userId || [],
|
|
},
|
|
);
|
|
}
|
|
|
|
@Post("notify-from-token")
|
|
@Security("bearerAuth")
|
|
async notifyFromToken(
|
|
@Body()
|
|
payload: {
|
|
message: string;
|
|
targetUserId?: string | string[];
|
|
roles?: string | string[];
|
|
error?: boolean;
|
|
},
|
|
@Request() req: RequestWithUser,
|
|
) {
|
|
const toArray = (value?: string | string[]) => {
|
|
if (Array.isArray(value)) return value.filter(Boolean);
|
|
if (typeof value === "string" && value.trim()) return [value];
|
|
return [] as string[];
|
|
};
|
|
|
|
const targetUserIds = toArray(payload.targetUserId);
|
|
const targetRoles = toArray(payload.roles);
|
|
|
|
// If caller provides explicit user targets, do not combine with role targeting.
|
|
// This prevents accidental broad notifications when roles include common roles.
|
|
const recipients =
|
|
targetUserIds.length > 0
|
|
? { userId: targetUserIds, roles: [] as string[] }
|
|
: { userId: [req.user.sub], roles: targetRoles };
|
|
|
|
sendWebSocket(
|
|
"socket-notification",
|
|
{ success: !payload.error, message: payload.message },
|
|
recipients,
|
|
);
|
|
}
|
|
}
|