add meshcentral skeletons in UI

This commit is contained in:
bachhungcb 2026-03-23 22:08:52 +07:00
parent df49bde2c4
commit b36b4b1113
4 changed files with 1399 additions and 0 deletions

1086
INTEGRATION_GUIDE_VI.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,3 +15,6 @@ export * as permissionService from "./permission.service";
// Role API Services
export * as roleService from "./role.service";
// Mesh Central API Services
export * as meshCentralService from "./meshcentral.service";

View File

@ -0,0 +1,310 @@
// services/meshcentral.service.ts
export interface MeshCentralConfig {
serverUrl: string;
username: string;
password: string;
domain?: string;
}
export interface DeviceGroup {
_id: string;
name: string;
desc: string;
mtype: number; // 1: FreeAgent, 2: IntelAMT, 3: Mixed
}
export interface Device {
_id: string;
name: string;
meshid: string;
host: string;
state: string; // online, offline, unknown
rname?: string; // remote name
}
export class MeshCentralService {
private ws: WebSocket | null = null;
private messageId = 1;
private pendingRequests = new Map<number, {
resolve: (value: any) => void;
reject: (error: any) => void;
timeout: ReturnType<typeof setTimeout>;
}>();
private messageHandlers = new Map<string, (data: any) => void>();
constructor(private config: MeshCentralConfig) {}
/**
* Kết nối đến MeshCentral Server
*/
async connect(): Promise<void> {
return new Promise((resolve, reject) => {
try {
const wsUrl = `${this.config.serverUrl.replace(/^http/, 'ws')}/control.ashx`;
this.ws = new WebSocket(wsUrl);
this.ws.onopen = () => {
console.log('Connected to MeshCentral');
this.authenticate().then(resolve).catch(reject);
};
this.ws.onmessage = (event) => this.handleMessage(event.data);
this.ws.onerror = (error) => {
console.error('WebSocket error:', error);
reject(error);
};
this.ws.onclose = () => {
console.log('Disconnected from MeshCentral');
this.ws = null;
};
} catch (error) {
reject(error);
}
});
}
/**
* Xác thực với server
*/
private async authenticate(): Promise<void> {
const authMessage = {
action: 'authCookie',
username: this.config.username,
password: this.config.password,
domain: this.config.domain || ''
};
return this.sendMessage(authMessage);
}
/**
* Gửi message chờ response
*/
private async sendMessage(message: any): Promise<any> {
return new Promise((resolve, reject) => {
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
reject(new Error('WebSocket not connected'));
return;
}
const msgId = this.messageId++;
message.sessionid = msgId;
const timeout = setTimeout(() => {
this.pendingRequests.delete(msgId);
reject(new Error('Request timeout'));
}, 30000); // 30 seconds timeout
this.pendingRequests.set(msgId, { resolve, reject, timeout });
try {
this.ws.send(JSON.stringify(message));
} catch (error) {
this.pendingRequests.delete(msgId);
clearTimeout(timeout);
reject(error);
}
});
}
/**
* Xử incoming messages
*/
private handleMessage(data: string): void {
try {
const message = JSON.parse(data);
// Handle response to pending request
if (message.sessionid && this.pendingRequests.has(message.sessionid)) {
const { resolve, reject, timeout } = this.pendingRequests.get(message.sessionid)!;
this.pendingRequests.delete(message.sessionid);
clearTimeout(timeout);
if (message.error) {
reject(new Error(message.error));
} else {
resolve(message);
}
}
// Handle event handlers
if (message.action && this.messageHandlers.has(message.action)) {
const handler = this.messageHandlers.get(message.action)!;
handler(message);
}
} catch (error) {
console.error('Error parsing message:', error);
}
}
/**
* Đăng handler cho event
*/
on(action: string, handler: (data: any) => void): void {
this.messageHandlers.set(action, handler);
}
/**
* === TẠIDEVICE GROUP ===
* Tạo một device group (Mesh) mới
*/
async createDeviceGroup(name: string, desc: string = ''): Promise<DeviceGroup> {
const response = await this.sendMessage({
action: 'createmesh',
meshname: name,
meshdesc: desc,
meshtype: 2 // 2 = Window
});
if (response.error) {
throw new Error(`Failed to create device group: ${response.error}`);
}
return response.meshid;
}
/**
* Lấy danh sách device groups
*/
async getDeviceGroups(): Promise<DeviceGroup[]> {
const response = await this.sendMessage({
action: 'meshes'
});
return response.meshes || [];
}
/**
* === THÊM DEVICE ===
* Lấy Agent invite link đ install trên device
*/
async getAgentInviteLink(meshId: string, platform: string = 'linux'): Promise<string> {
const response = await this.sendMessage({
action: 'getmesh',
meshid: meshId
});
// Agent download URL format:
// /meshagents?id=<meshid>&installflags=<flags>&exeType=<type>
const flags = 0; // Windows install flags
return `/meshagents?id=4&meshid=${meshId}&installflags=${flags}`;
}
/**
* Lấy danh sách devices trong group
*/
async getDevices(meshId: string): Promise<Device[]> {
const response = await this.sendMessage({
action: 'getmesh',
meshid: meshId
});
return response.nodes || [];
}
/**
* === QUẢN DEVICE ===
* hiệu hóa/kích hoạt device
*/
async setDeviceState(deviceId: string, enabled: boolean): Promise<void> {
await this.sendMessage({
action: 'changedevice',
nodeid: deviceId,
enabled: enabled
});
}
/**
* Xóa device khỏi group
*/
async removeDevice(deviceId: string): Promise<void> {
await this.sendMessage({
action: 'removenode',
nodeids: [deviceId]
});
}
/**
* === QUẢN NGƯỜI DÙNG ===
* Tạo user mới
*/
async createUser(username: string, password: string, email?: string): Promise<any> {
const response = await this.sendMessage({
action: 'createuser',
username: username,
password: password,
email: email || ''
});
return response;
}
/**
* Gán quyền truy cập device group cho user
* rights: bitmask của permissions
* - 1: Edit mesh
* - 2: Manage users
* - 4: Manage computers
* - 8: Remote control
* - 16: Agent console
* - 32: Server files
* - 64: Wake device
* - 128: Set notes
* - 256: Remote view only
*/
async addUserToMesh(meshId: string, username: string, rights: number): Promise<void> {
await this.sendMessage({
action: 'editmesh',
meshid: meshId,
usernames: [username],
rights: rights
});
}
/**
* === ĐIỀU KHIỂN THIẾT BỊ ===
* Gửi command đến device
*/
async sendDeviceCommand(deviceId: string, command: string, parameters?: any): Promise<any> {
return this.sendMessage({
action: 'runcommand',
nodeid: deviceId,
command: command,
params: parameters || {}
});
}
/**
* Khởi đng lại device
*/
async rebootDevice(deviceId: string): Promise<void> {
await this.sendMessage({
action: 'poweraction',
nodeid: deviceId,
actiontype: 1 // 1 = reboot
});
}
/**
* Tắt device
*/
async shutdownDevice(deviceId: string): Promise<void> {
await this.sendMessage({
action: 'poweraction',
nodeid: deviceId,
actiontype: 2 // 2 = shutdown
});
}
/**
* Disconnect user session từ MeshCentral
*/
disconnect(): void {
if (this.ws) {
this.ws.close();
this.ws = null;
}
this.pendingRequests.clear();
this.messageHandlers.clear();
}
}