first commit

This commit is contained in:
2026-07-16 20:48:43 -03:00
commit 5696cee264
1111 changed files with 322270 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
API_HOST = http://localhost:3000
API_PRIVATE_KEY=keys/tx-sysadmin-private.key
+4
View File
@@ -0,0 +1,4 @@
node_modules
dist
certs
.DS_Store
+3
View File
@@ -0,0 +1,3 @@
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIEQTLBlaMj4qXGMq36lHwXCO18Z1u7kOZrqFLMbJ8cDI
-----END PRIVATE KEY-----
+1681
View File
File diff suppressed because it is too large Load Diff
+30
View File
@@ -0,0 +1,30 @@
{
"name": "sysadmin",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon src/server.ts",
"build": "tsc",
"start": "node dist/server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"axios": "^1.13.4",
"cors": "^2.8.6",
"dotenv": "^17.2.3",
"express": "^5.2.1",
"helmet": "^8.1.0"
},
"devDependencies": {
"@types/cors": "^2.8.19",
"@types/express": "^5.0.6",
"@types/node": "^25.0.10",
"nodemon": "^3.1.11",
"ts-node": "^10.9.2",
"typescript": "^5.9.3"
}
}
+20
View File
@@ -0,0 +1,20 @@
import express from "express";
import cors from "cors";
import helmet from "helmet";
import wapRoutes from "./routes/wap.routes";
import usersRoutes from "./routes/users.routes";
import companiesRoutes from "./routes/companies.routes";
import servicesRoutes from "./routes/services.routes";
const app = express();
app.use(helmet());
app.use(cors());
app.use(express.json());
app.use("/wap", wapRoutes);
app.use("/users", usersRoutes);
app.use("/companies", companiesRoutes);
app.use("/services", servicesRoutes);
export default app;
@@ -0,0 +1,35 @@
import { Request, Response } from "express";
import { paginateCompanies, setCompanyBanned, updateCompany } from "../services/companies.service";
export const paginate = async (req: Request, res: Response) => {
try {
const result = await paginateCompanies(req.body);
res.json(result);
} catch (e: any) {
console.log(e);
const err = e.response ? e.response.data : e.message;
res.status(500).json({ error: err });
}
};
export const update = async (req: Request, res: Response) => {
try {
const result = await updateCompany(req.body);
res.json(result);
} catch (e: any) {
console.log(e);
const err = e.response ? e.response.data : e.message;
res.status(500).json({ error: err });
}
};
export const setBanned = async (req: Request, res: Response) => {
try {
const result = await setCompanyBanned(req.body);
res.json(result);
} catch (e: any) {
console.log(e);
const err = e.response ? e.response.data : e.message;
res.status(500).json({ error: err });
}
};
@@ -0,0 +1,24 @@
import { Request, Response } from "express";
import { paginateServices, setServiceBanned } from "../services/services.service";
export const paginate = async (req: Request, res: Response) => {
try {
const result = await paginateServices(req.body);
res.json(result);
} catch (e: any) {
console.log(e);
const err = e.response ? e.response.data : e.message;
res.status(500).json({ error: err });
}
};
export const setBanned = async (req: Request, res: Response) => {
try {
const result = await setServiceBanned(req.body);
res.json(result);
} catch (e: any) {
console.log(e);
const err = e.response ? e.response.data : e.message;
res.status(500).json({ error: err });
}
};
@@ -0,0 +1,68 @@
import { Request, Response } from "express";
import { UsersService } from "../services/users.service";
import {
SysAdminPaginateUsersParams,
SysAdminUpdateProfileParams,
SysAdminSetVerifiedParams,
SysAdminDeleteUserParams,
SysAdminOrganizationsStatusParams,
} from "../models/Users.Model";
const usersService = new UsersService();
export class UsersController {
public paginateUsers = async (req: Request, res: Response): Promise<void> => {
try {
const data: SysAdminPaginateUsersParams = req.body;
const users = await usersService.paginateUsers(data);
res.json(users);
} catch (error: any) {
console.error("Error paginating users:", error?.response?.data || error);
res.status(500).json(error?.response?.data || { success: false, message: "Internal Server Error" });
}
};
public updateProfile = async (req: Request, res: Response): Promise<void> => {
try {
const data: SysAdminUpdateProfileParams = req.body;
const result = await usersService.updateProfile(data);
res.json(result);
} catch (error: any) {
console.error("Error updating user profile:", error?.response?.data || error);
res.status(500).json(error?.response?.data || { success: false, message: "Internal Server Error" });
}
};
public setVerifiedStatus = async (req: Request, res: Response): Promise<void> => {
try {
const data: SysAdminSetVerifiedParams = req.body;
const result = await usersService.setVerifiedStatus(data);
res.json(result);
} catch (error: any) {
console.error("Error setting verified status:", error?.response?.data || error);
res.status(500).json(error?.response?.data || { success: false, message: "Internal Server Error" });
}
};
public organizationsStatus = async (req: Request, res: Response): Promise<void> => {
try {
const data: SysAdminOrganizationsStatusParams = req.body;
const result = await usersService.organizationsStatus(data);
res.json(result);
} catch (error: any) {
console.error("Error fetching organizations status:", error?.response?.data || error);
res.status(500).json(error?.response?.data || { success: false, message: "Internal Server Error" });
}
};
public deleteUser = async (req: Request, res: Response): Promise<void> => {
try {
const data: SysAdminDeleteUserParams = req.body;
const result = await usersService.deleteUser(data);
res.json(result);
} catch (error: any) {
console.error("Error deleting user:", error?.response?.data || error);
res.status(500).json(error?.response?.data || { success: false, message: "Internal Server Error" });
}
};
}
@@ -0,0 +1,18 @@
import { Request, Response } from "express";
import { WapService } from "../services/wap.service";
import { PaginateWapServerParams } from "src/models/WapServers.Model";
const wapService = new WapService();
export class WapController {
public getServers = async (req: Request, res: Response): Promise<void> => {
try {
let data: PaginateWapServerParams = req.body as PaginateWapServerParams;
const servers = await wapService.getWapServers(data);
res.json(servers);
} catch (error) {
console.error("Error fetching wap servers:", error);
res.status(500).json({ success: false, message: "Internal Server Error" });
}
};
}
+3
View File
@@ -0,0 +1,3 @@
export const getApiHost = () => {
return process.env.API_HOST || "http://localhost:3000";
};
+22
View File
@@ -0,0 +1,22 @@
import { INonce } from "src/models/Nonce.Model";
import crypto from "crypto";
import fs from "fs";
import path from "path";
import { IPayload } from "src/models/Payload.Model";
export const getPayload = (nonce: INonce): IPayload => {
const privateKeyPath = path.resolve(process.cwd(), process.env.API_PRIVATE_KEY || "");
const privateKey = fs.readFileSync(privateKeyPath);
const signature = crypto.sign(
null, // Ed25519 no usa hash explícito
Buffer.from(nonce.nonce), // mensaje a firmar
privateKey,
);
const payload: IPayload = {
nonce,
signature: signature.toString("base64"),
};
return payload;
};
+26
View File
@@ -0,0 +1,26 @@
import axios from "axios";
import { INonce } from "src/models/Nonce.Model";
import { getApiHost } from "./GetApiHost";
export const getSysAdminNonce = async (): Promise<INonce> => {
try {
const response = await axios.get<INonce>(`${getApiHost()}/sysadmin-challenges/create`, {
headers: {
"Content-Type": "application/json",
},
});
if (response.status !== 201) {
throw new Error("Ha ocurrido un error al generar el nonce, por favor intente nuevamente.");
}
if (!response.data) {
throw new Error("Ha ocurrido un error al generar el nonce, por favor intente nuevamente.");
}
return response.data as INonce;
} catch (e) {
console.error(e);
throw new Error("Ha ocurrido un error al generar el nonce, por favor intente nuevamente.");
}
};
+37
View File
@@ -0,0 +1,37 @@
export interface ICompany {
id?: string;
name: string;
slug: string;
description: string;
categoryId: number;
ownerId: string;
banned?: boolean;
// ... we don't need all the properties in the proxy model, just what we return/use
}
export type PaginateCompaniesParams = {
_id?: string;
name?: string;
ownerId?: string;
banned?: boolean;
page: number;
limit: number;
};
export type PaginateCompaniesResults = {
data: any[];
page: number;
pages: number;
};
export type UpdateCompanyParams = {
id: string;
name?: string;
description?: string;
categoryId?: number;
};
export type SetCompanyBannedParams = {
id: string;
banned: boolean;
};
+3
View File
@@ -0,0 +1,3 @@
export interface INonce {
nonce: string;
}
+6
View File
@@ -0,0 +1,6 @@
import { INonce } from "./Nonce.Model";
export interface IPayload {
nonce: INonce;
signature: string;
}
+28
View File
@@ -0,0 +1,28 @@
export interface IService {
id?: string;
companyId: string;
categoryId: number;
name: string;
description: string;
length: number;
price: number;
banned?: boolean;
}
export type PaginateServicesParams = {
companyId?: string;
banned?: boolean;
page: number;
limit: number;
};
export type PaginateServicesResults = {
data: any[];
page: number;
pages: number;
};
export type SetServiceBannedParams = {
id: string;
banned: boolean;
};
+54
View File
@@ -0,0 +1,54 @@
export type SysAdminPaginateUsersParams = {
page: number;
limit: number;
name?: string;
lastName?: string;
email?: string;
isVerified?: boolean;
createdFrom?: string;
createdTo?: string;
sortBy?: "name" | "createdAt";
sortOrder?: "asc" | "desc";
};
export type PaginateUsersResults = {
data: any[];
page: number;
pages: number;
};
export type SysAdminUpdateProfileParams = {
userId: string;
firstName?: string;
lastName?: string;
street?: string;
streetNumber?: string;
builingFloor?: string;
buildingApartament?: string;
block?: string;
city?: string;
state?: string;
country?: string;
zipCode?: string;
phoneCountryCode?: string;
phoneAreaCode?: string;
phoneNumber?: string;
};
export type SysAdminSetVerifiedParams = {
userId: string;
isVerified: boolean;
};
export type SysAdminDeleteUserParams = {
userId: string;
};
export type SysAdminOrganizationsStatusParams = {
userId: string;
};
export type SysAdminUserOrganizationsResult = {
clientIn: { companyId: string; companyName: string }[];
collaboratorIn: { companyId: string; companyName: string }[];
};
+38
View File
@@ -0,0 +1,38 @@
import { IPayload } from "./Payload.Model";
export type FindWapServerParams = {
id?: string;
name?: string;
description?: string;
countBots?: number;
maxBots?: number;
active?: boolean;
countBotsFrom?: number;
countBotsTo?: number;
};
export interface IWapServer {
id?: string;
name?: string;
description?: string;
ipv4: string;
ipv6: string;
countBots: number;
maxBots: number;
active: boolean;
}
export type PaginateWapServerParams = FindWapServerParams & {
page: number;
limit: number;
};
export type PaginateWapServerResults = {
data: IWapServer[];
page: number;
pages: number;
};
export type SysAdminGetWapServerParams = PaginateWapServerParams & {
payload: IPayload;
};
+10
View File
@@ -0,0 +1,10 @@
import { Router } from "express";
import { paginate, setBanned, update } from "../controllers/companies.controller";
const router = Router();
router.post("/paginate", paginate);
router.post("/update", update);
router.post("/set-banned", setBanned);
export default router;
+9
View File
@@ -0,0 +1,9 @@
import { Router } from "express";
import { paginate, setBanned } from "../controllers/services.controller";
const router = Router();
router.post("/paginate", paginate);
router.post("/set-banned", setBanned);
export default router;
+13
View File
@@ -0,0 +1,13 @@
import { Router } from "express";
import { UsersController } from "../controllers/users.controller";
const router = Router();
const usersController = new UsersController();
router.post("/paginate", usersController.paginateUsers);
router.post("/update", usersController.updateProfile);
router.post("/set-verified", usersController.setVerifiedStatus);
router.post("/organizations-status", usersController.organizationsStatus);
router.post("/delete", usersController.deleteUser);
export default router;
+9
View File
@@ -0,0 +1,9 @@
import { Router } from "express";
import { WapController } from "../controllers/wap.controller";
const router = Router();
const wapController = new WapController();
router.post("/paginate", wapController.getServers);
export default router;
+10
View File
@@ -0,0 +1,10 @@
import app from "./app";
import dotenv from "dotenv";
dotenv.config();
const PORT = process.env.PORT || 3002;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
@@ -0,0 +1,37 @@
import axios from "axios";
import { getSysAdminNonce } from "../helpers/GetSysAdminNonce";
import { getPayload } from "../helpers/GetPayload";
import { getApiHost } from "../helpers/GetApiHost";
import {
PaginateCompaniesParams,
PaginateCompaniesResults,
SetCompanyBannedParams,
UpdateCompanyParams,
} from "../models/Companies.Model";
export const paginateCompanies = async (params: PaginateCompaniesParams): Promise<PaginateCompaniesResults> => {
const nonce = await getSysAdminNonce();
const result = await axios.post(`${getApiHost()}/sysadmin/companies/paginate`, {
...params,
payload: getPayload(nonce),
});
return result.data;
};
export const updateCompany = async (params: UpdateCompanyParams): Promise<any> => {
const nonce = await getSysAdminNonce();
const result = await axios.post(`${getApiHost()}/sysadmin/companies/update`, {
...params,
payload: getPayload(nonce),
});
return result.data;
};
export const setCompanyBanned = async (params: SetCompanyBannedParams): Promise<any> => {
const nonce = await getSysAdminNonce();
const result = await axios.post(`${getApiHost()}/sysadmin/companies/set-banned`, {
...params,
payload: getPayload(nonce),
});
return result.data;
};
+27
View File
@@ -0,0 +1,27 @@
import axios from "axios";
import { getSysAdminNonce } from "../helpers/GetSysAdminNonce";
import { getPayload } from "../helpers/GetPayload";
import { getApiHost } from "../helpers/GetApiHost";
import {
PaginateServicesParams,
PaginateServicesResults,
SetServiceBannedParams,
} from "../models/Services.Model";
export const paginateServices = async (params: PaginateServicesParams): Promise<PaginateServicesResults> => {
const nonce = await getSysAdminNonce();
const result = await axios.post(`${getApiHost()}/sysadmin/services/paginate`, {
...params,
payload: getPayload(nonce),
});
return result.data;
};
export const setServiceBanned = async (params: SetServiceBannedParams): Promise<any> => {
const nonce = await getSysAdminNonce();
const result = await axios.post(`${getApiHost()}/sysadmin/services/set-banned`, {
...params,
payload: getPayload(nonce),
});
return result.data;
};
+75
View File
@@ -0,0 +1,75 @@
import { getSysAdminNonce } from "../helpers/GetSysAdminNonce";
import { getApiHost } from "../helpers/GetApiHost";
import axios from "axios";
import { getPayload } from "../helpers/GetPayload";
import {
SysAdminPaginateUsersParams,
PaginateUsersResults,
SysAdminUpdateProfileParams,
SysAdminSetVerifiedParams,
SysAdminDeleteUserParams,
SysAdminOrganizationsStatusParams,
SysAdminUserOrganizationsResult,
} from "../models/Users.Model";
export class UsersService {
public async paginateUsers(filters: SysAdminPaginateUsersParams): Promise<PaginateUsersResults> {
const nonce = await getSysAdminNonce();
const postData = { ...filters, ...{ payload: getPayload(nonce) } };
const response = await axios.post(`${getApiHost()}/sysadmin/users/paginate`, postData, {
headers: { "Content-Type": "application/json" },
timeout: 5000,
});
return response.data;
}
public async updateProfile(data: SysAdminUpdateProfileParams): Promise<any> {
const nonce = await getSysAdminNonce();
const postData = { ...data, ...{ payload: getPayload(nonce) } };
const response = await axios.post(`${getApiHost()}/sysadmin/users/update`, postData, {
headers: { "Content-Type": "application/json" },
timeout: 5000,
});
return response.data;
}
public async setVerifiedStatus(data: SysAdminSetVerifiedParams): Promise<any> {
const nonce = await getSysAdminNonce();
const postData = { ...data, ...{ payload: getPayload(nonce) } };
const response = await axios.post(`${getApiHost()}/sysadmin/users/set-verified`, postData, {
headers: { "Content-Type": "application/json" },
timeout: 5000,
});
return response.data;
}
public async deleteUser(data: SysAdminDeleteUserParams): Promise<any> {
const nonce = await getSysAdminNonce();
const postData = { ...data, ...{ payload: getPayload(nonce) } };
const response = await axios.post(`${getApiHost()}/sysadmin/users/delete`, postData, {
headers: { "Content-Type": "application/json" },
timeout: 10000, // Slightly longer timeout for cascading deletes
});
return response.data;
}
public async organizationsStatus(data: SysAdminOrganizationsStatusParams): Promise<SysAdminUserOrganizationsResult> {
const nonce = await getSysAdminNonce();
const postData = { ...data, ...{ payload: getPayload(nonce) } };
const response = await axios.post(`${getApiHost()}/sysadmin/users/organizations-status`, postData, {
headers: { "Content-Type": "application/json" },
timeout: 5000,
});
return response.data;
}
}
+23
View File
@@ -0,0 +1,23 @@
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";
export class WapService {
public async getWapServers(filters: PaginateWapServerParams): Promise<PaginateWapServerResults> {
const nonce = await getSysAdminNonce();
const postData = { ...filters, ...{ payload: getPayload(nonce) } };
const response = await axios.post(`${getApiHost()}/sysadmin/wapserver/get`, postData, {
headers: {
"Content-Type": "application/json",
},
timeout: 5000,
});
const resultado: PaginateWapServerResults = response.data;
return resultado;
}
}
+28
View File
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"lib": ["es6", "es2017", "esnext.asynciterable"],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": ["node_modules"],
"include": ["./src/**/*.ts"]
}