feat: implement full CRUD and administrative management endpoints for WAP servers in the sysadmin API
This commit is contained in:
@@ -1,9 +1,28 @@
|
||||
import axios from "axios";
|
||||
import { Request, Response } from "express";
|
||||
import { WapService } from "../services/wap.service";
|
||||
import { PaginateWapServerParams } from "src/models/WapServers.Model";
|
||||
import { PaginateWapServerParams, UpdateWapServerParams, WapServerByIdParams, WapServerOrganizationActionParams } from "src/models/WapServers.Model";
|
||||
|
||||
const wapService = new WapService();
|
||||
|
||||
const getErrorStatus = (error: unknown): number => {
|
||||
if (axios.isAxiosError(error) && error.response?.status) {
|
||||
return error.response.status;
|
||||
}
|
||||
|
||||
return 500;
|
||||
};
|
||||
|
||||
const getErrorMessage = (error: unknown): string => {
|
||||
const responseData = axios.isAxiosError(error) ? error.response?.data : undefined;
|
||||
|
||||
if (typeof responseData === "string") {
|
||||
return responseData;
|
||||
}
|
||||
|
||||
return responseData?.desc || responseData?.message || responseData?.error || (error as Error)?.message || "Internal Server Error";
|
||||
};
|
||||
|
||||
export class WapController {
|
||||
public getServers = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
@@ -15,4 +34,117 @@ export class WapController {
|
||||
res.status(500).json({ success: false, message: "Internal Server Error" });
|
||||
}
|
||||
};
|
||||
|
||||
public auditServer = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const data: WapServerByIdParams = req.body as WapServerByIdParams;
|
||||
const audit = await wapService.auditWapServer(data);
|
||||
res.json(audit);
|
||||
} catch (error) {
|
||||
console.error("Error auditing wap server:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public updateServer = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const result = await wapService.updateWapServer(req.body as UpdateWapServerParams);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
console.error("Error updating wap server:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public recalculateCount = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const data: WapServerByIdParams = req.body as WapServerByIdParams;
|
||||
const result = await wapService.recalculateWapServerCount(data);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
console.error("Error recalculating wap server count:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public deleteServer = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const data: WapServerByIdParams = req.body as WapServerByIdParams;
|
||||
const result = await wapService.deleteWapServer(data);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
console.error("Error deleting wap server:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public startBot = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
await wapService.startBot(req.body as WapServerOrganizationActionParams);
|
||||
res.json({ success: true, message: "ok" });
|
||||
} catch (error) {
|
||||
console.error("Error starting wap bot:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public stopBot = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
await wapService.stopBot(req.body as WapServerOrganizationActionParams);
|
||||
res.json({ success: true, message: "ok" });
|
||||
} catch (error) {
|
||||
console.error("Error stopping wap bot:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public restartBot = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
await wapService.restartBot(req.body as WapServerOrganizationActionParams);
|
||||
res.json({ success: true, message: "ok" });
|
||||
} catch (error) {
|
||||
console.error("Error restarting wap bot:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public getBotQr = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const result = await wapService.getBotQr(req.body as WapServerOrganizationActionParams);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
console.error("Error getting wap bot qr:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public deleteBot = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
await wapService.deleteBot(req.body as WapServerOrganizationActionParams);
|
||||
res.json({ success: true, message: "ok" });
|
||||
} catch (error) {
|
||||
console.error("Error deleting wap bot:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
|
||||
public detachOrganizationServer = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const result = await wapService.detachOrganizationServer(req.body as WapServerOrganizationActionParams);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
console.error("Error detaching wap organization server:", error);
|
||||
const message = getErrorMessage(error);
|
||||
res.status(getErrorStatus(error)).json({ success: false, message, desc: message });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ export type FindWapServerParams = {
|
||||
description?: string;
|
||||
countBots?: number;
|
||||
maxBots?: number;
|
||||
port?: number;
|
||||
active?: boolean;
|
||||
countBotsFrom?: number;
|
||||
countBotsTo?: number;
|
||||
@@ -19,9 +20,19 @@ export interface IWapServer {
|
||||
ipv6: string;
|
||||
countBots: number;
|
||||
maxBots: number;
|
||||
port: number;
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
export type UpdateWapServerParams = {
|
||||
serverId: string;
|
||||
name?: string;
|
||||
ipv4?: string;
|
||||
port?: number;
|
||||
maxBots?: number;
|
||||
active?: boolean;
|
||||
};
|
||||
|
||||
export type PaginateWapServerParams = FindWapServerParams & {
|
||||
page: number;
|
||||
limit: number;
|
||||
@@ -36,3 +47,62 @@ export type PaginateWapServerResults = {
|
||||
export type SysAdminGetWapServerParams = PaginateWapServerParams & {
|
||||
payload: IPayload;
|
||||
};
|
||||
|
||||
export type WapServerByIdParams = {
|
||||
serverId: string;
|
||||
};
|
||||
|
||||
export type WapServerDeleteResult = {
|
||||
serverId: string;
|
||||
deleted: true;
|
||||
};
|
||||
|
||||
export type WapServerOrganizationActionParams = WapServerByIdParams & {
|
||||
organizationId: string;
|
||||
};
|
||||
|
||||
export type WapServerQrResult = WapServerOrganizationActionParams & {
|
||||
qr: string;
|
||||
};
|
||||
|
||||
export type WapServerDetachResult = WapServerOrganizationActionParams & {
|
||||
botDeleted: boolean;
|
||||
botAlreadyMissing: boolean;
|
||||
before: number;
|
||||
after: number;
|
||||
};
|
||||
|
||||
export type WapAssignedOrganization = {
|
||||
id: string;
|
||||
name?: string;
|
||||
};
|
||||
|
||||
export type WapContainerDto = {
|
||||
id?: string;
|
||||
name?: string;
|
||||
organizationId?: string;
|
||||
image?: string;
|
||||
state?: string;
|
||||
status?: string;
|
||||
ports?: unknown[];
|
||||
created?: number;
|
||||
};
|
||||
|
||||
export type WapServerAuditResult = {
|
||||
serverId: string;
|
||||
assignedOrganizations: WapAssignedOrganization[];
|
||||
detectedBots: WapContainerDto[];
|
||||
validBots: WapContainerDto[];
|
||||
ghostBots: WapContainerDto[];
|
||||
missingBots: WapAssignedOrganization[];
|
||||
expectedCountBots: number;
|
||||
storedCountBots: number;
|
||||
runtimeCountBots: number;
|
||||
countMismatch: boolean;
|
||||
};
|
||||
|
||||
export type WapServerRecalculateCountResult = {
|
||||
serverId: string;
|
||||
before: number;
|
||||
after: number;
|
||||
};
|
||||
|
||||
@@ -5,5 +5,15 @@ const router = Router();
|
||||
const wapController = new WapController();
|
||||
|
||||
router.post("/paginate", wapController.getServers);
|
||||
router.post("/update", wapController.updateServer);
|
||||
router.post("/audit", wapController.auditServer);
|
||||
router.post("/recalculate-count", wapController.recalculateCount);
|
||||
router.post("/delete", wapController.deleteServer);
|
||||
router.post("/bot/start", wapController.startBot);
|
||||
router.post("/bot/stop", wapController.stopBot);
|
||||
router.post("/bot/restart", wapController.restartBot);
|
||||
router.post("/bot/qr", wapController.getBotQr);
|
||||
router.post("/bot/delete", wapController.deleteBot);
|
||||
router.post("/bot/detach", wapController.detachOrganizationServer);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -2,7 +2,19 @@ import { getSysAdminNonce } from "../helpers/GetSysAdminNonce";
|
||||
import { getApiHost } from "../helpers/GetApiHost";
|
||||
import axios from "axios";
|
||||
import { getPayload } from "../helpers/GetPayload";
|
||||
import { PaginateWapServerParams, PaginateWapServerResults } from "../models/WapServers.Model";
|
||||
import {
|
||||
PaginateWapServerParams,
|
||||
PaginateWapServerResults,
|
||||
WapServerAuditResult,
|
||||
WapServerByIdParams,
|
||||
WapServerDeleteResult,
|
||||
WapServerDetachResult,
|
||||
WapServerOrganizationActionParams,
|
||||
WapServerQrResult,
|
||||
WapServerRecalculateCountResult,
|
||||
UpdateWapServerParams,
|
||||
IWapServer,
|
||||
} from "../models/WapServers.Model";
|
||||
|
||||
export class WapService {
|
||||
public async getWapServers(filters: PaginateWapServerParams): Promise<PaginateWapServerResults> {
|
||||
@@ -20,4 +32,88 @@ export class WapService {
|
||||
|
||||
return resultado;
|
||||
}
|
||||
|
||||
public async auditWapServer(data: WapServerByIdParams): Promise<WapServerAuditResult> {
|
||||
const nonce = await getSysAdminNonce();
|
||||
const postData = { ...data, ...{ payload: getPayload(nonce) } };
|
||||
|
||||
const response = await axios.post(`${getApiHost()}/sysadmin/wapserver/audit`, postData, {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
return response.data as WapServerAuditResult;
|
||||
}
|
||||
|
||||
public async updateWapServer(data: UpdateWapServerParams): Promise<IWapServer> {
|
||||
const nonce = await getSysAdminNonce();
|
||||
const postData = { ...data, ...{ payload: getPayload(nonce) } };
|
||||
|
||||
const response = await axios.post(`${getApiHost()}/sysadmin/wapserver/update`, postData, {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
return response.data as IWapServer;
|
||||
}
|
||||
|
||||
public async recalculateWapServerCount(data: WapServerByIdParams): Promise<WapServerRecalculateCountResult> {
|
||||
const nonce = await getSysAdminNonce();
|
||||
const postData = { ...data, ...{ payload: getPayload(nonce) } };
|
||||
|
||||
const response = await axios.post(`${getApiHost()}/sysadmin/wapserver/recalculate-count`, postData, {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
return response.data as WapServerRecalculateCountResult;
|
||||
}
|
||||
|
||||
public async deleteWapServer(data: WapServerByIdParams): Promise<WapServerDeleteResult> {
|
||||
const nonce = await getSysAdminNonce();
|
||||
const postData = { ...data, ...{ payload: getPayload(nonce) } };
|
||||
|
||||
const response = await axios.post(`${getApiHost()}/sysadmin/wapserver/delete`, postData, {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
timeout: 15000,
|
||||
});
|
||||
|
||||
return response.data as WapServerDeleteResult;
|
||||
}
|
||||
|
||||
private async postBotAction<T>(path: string, data: WapServerOrganizationActionParams, timeout = 10000): Promise<T> {
|
||||
const nonce = await getSysAdminNonce();
|
||||
const postData = { ...data, ...{ payload: getPayload(nonce) } };
|
||||
|
||||
const response = await axios.post(`${getApiHost()}/sysadmin/wapserver/bot/${path}`, postData, {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
timeout,
|
||||
});
|
||||
|
||||
return response.data as T;
|
||||
}
|
||||
|
||||
public async startBot(data: WapServerOrganizationActionParams): Promise<void> {
|
||||
await this.postBotAction("start", data);
|
||||
}
|
||||
|
||||
public async stopBot(data: WapServerOrganizationActionParams): Promise<void> {
|
||||
await this.postBotAction("stop", data);
|
||||
}
|
||||
|
||||
public async restartBot(data: WapServerOrganizationActionParams): Promise<void> {
|
||||
await this.postBotAction("restart", data, 15000);
|
||||
}
|
||||
|
||||
public async getBotQr(data: WapServerOrganizationActionParams): Promise<WapServerQrResult> {
|
||||
return await this.postBotAction<WapServerQrResult>("qr", data);
|
||||
}
|
||||
|
||||
public async deleteBot(data: WapServerOrganizationActionParams): Promise<void> {
|
||||
await this.postBotAction("delete", data);
|
||||
}
|
||||
|
||||
public async detachOrganizationServer(data: WapServerOrganizationActionParams): Promise<WapServerDetachResult> {
|
||||
return await this.postBotAction<WapServerDetachResult>("detach", data);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user