add meshcentral skeletons in UI
This commit is contained in:
parent
df49bde2c4
commit
b36b4b1113
1086
INTEGRATION_GUIDE_VI.md
Normal file
1086
INTEGRATION_GUIDE_VI.md
Normal file
File diff suppressed because it is too large
Load Diff
0
src/routes/_auth/rooms/$roomName/connect/index.tsx
Normal file
0
src/routes/_auth/rooms/$roomName/connect/index.tsx
Normal 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";
|
||||
310
src/services/meshcentral.service.ts
Normal file
310
src/services/meshcentral.service.ts
Normal 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 và 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ử lý 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 ký 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 LÝ DEVICE ===
|
||||
* Vô 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 LÝ 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();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user