ArmoHotspot/backend/src/services/OpnsenseService.ts
Gökhan ÖZARSLAN ced2c9d61b kurulum2
2026-08-16 16:15:01 +03:00

101 lines
3.1 KiB
TypeScript

import axios from 'axios';
import https from 'https';
export class OpnsenseService {
private baseUrl: string;
private apiKey: string;
private apiSecret: string;
private client: any;
constructor(ipAddress: string, apiKey: string, apiSecret: string) {
// Assuming HTTPS access to OPNsense, might need to adjust port if custom
this.baseUrl = `https://${ipAddress}/api`;
this.apiKey = apiKey;
this.apiSecret = apiSecret;
// OPNsense uses basic auth with API Key and Secret
// We ignore SSL errors because OPNsense often has self-signed certs
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
this.client = axios.create({
baseURL: this.baseUrl,
auth: {
username: this.apiKey,
password: this.apiSecret,
},
httpsAgent,
});
}
/**
* Health check to test API connectivity
*/
async testConnection(): Promise<boolean> {
try {
// Fetching core firmware info as a simple ping
const response = await this.client.get('/core/firmware/info');
return response.status === 200;
} catch (error) {
console.error('OPNsense API Connection Error:', error);
return false;
}
}
/**
* Captive Portal: Add or update a voucher/user session
* This allows the hotspot system to authenticate a user automatically via API
*/
async authHotspotUser(zoneId: string, username: string, ipAddress: string): Promise<any> {
try {
// POST /api/captiveportal/session/connect/
const payload = {
zoneid: zoneId,
user: username,
ip: ipAddress,
};
// OPNsense expects URL encoded form data or specific JSON structure depending on the endpoint
// Using generic captiveportal session connect endpoint
const response = await this.client.post(`/captiveportal/session/connect`, payload);
return response.data;
} catch (error) {
console.error('Error authenticating hotspot user:', error);
throw new Error('Could not authenticate hotspot user on OPNsense');
}
}
/**
* Captive Portal: Disconnect a user
*/
async disconnectHotspotUser(zoneId: string, sessionId: string): Promise<any> {
try {
const payload = {
zoneid: zoneId,
sessionid: sessionId
};
const response = await this.client.post(`/captiveportal/session/disconnect`, payload);
return response.data;
} catch (error) {
console.error('Error disconnecting hotspot user:', error);
throw new Error('Could not disconnect hotspot user on OPNsense');
}
}
/**
* Traffic Shaper: Add a rule (e.g. for speed limits)
*/
async addShaperRule(ruleData: any): Promise<any> {
try {
const response = await this.client.post('/trafficshaper/rule/addRule', { rule: ruleData });
// Apply the changes (shaper requires an explicit apply call)
await this.client.post('/trafficshaper/service/reconfigure');
return response.data;
} catch (error) {
console.error('Error adding shaper rule:', error);
throw new Error('Could not add traffic shaper rule on OPNsense');
}
}
}