script improvements
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 9s
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 9s
This commit is contained in:
@@ -13,10 +13,12 @@ import {
|
||||
DeleteResult,
|
||||
EnableRequest,
|
||||
OperationResult,
|
||||
RequirementsDeleteResult,
|
||||
RequirementsUploadResult,
|
||||
ScriptInfo,
|
||||
ScriptUploadResponse,
|
||||
StatusForNameResponse,
|
||||
UnitStatus,
|
||||
ScriptWithStatus,
|
||||
StatusForNameResponse
|
||||
} from '../types/scripting';
|
||||
import { SnifferStatusResponse } from '../types/sniffer';
|
||||
|
||||
@@ -168,21 +170,42 @@ export const execFirewallRaw = async (cmd: string): Promise<ExecResult> => {
|
||||
Scripts
|
||||
------------------------- */
|
||||
|
||||
export const fetchScriptsStatusAll = async (): Promise<Record<string, UnitStatus>> => {
|
||||
const res = await api.get<Record<string, UnitStatus>>('/scripts/scripts/status');
|
||||
return res.data;
|
||||
};
|
||||
|
||||
export const fetchScriptStatusForName = async (name: string): Promise<StatusForNameResponse> => {
|
||||
const res = await api.get<StatusForNameResponse>(`/scripts/scripts/${encodeURIComponent(name)}/status`);
|
||||
/**
|
||||
* Fetch the combined scripts + status endpoint.
|
||||
* Returns a list of ScriptWithStatus entries.
|
||||
*/
|
||||
export const fetchScriptsAll = async (): Promise<ScriptWithStatus[]> => {
|
||||
const res = await api.get<ScriptWithStatus[]>('/scripts/scripts');
|
||||
return res.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience: list only the basic ScriptInfo items (no mappings).
|
||||
* This uses the combined endpoint and maps to ScriptInfo[].
|
||||
*/
|
||||
export const listScripts = async (): Promise<ScriptInfo[]> => {
|
||||
const res = await api.get<ScriptInfo[]>('/scripts/scripts');
|
||||
return res.data;
|
||||
const all = await fetchScriptsAll();
|
||||
return all.map((s) => ({ name: s.name, path: s.path }));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get status/mappings for a single script by name.
|
||||
* Because the backend merged status into /scripts, we fetch that and filter.
|
||||
*/
|
||||
export const fetchScriptStatusForName = async (name: string): Promise<StatusForNameResponse> => {
|
||||
const all = await fetchScriptsAll();
|
||||
const found = all.find((s) => s.name === name);
|
||||
if (!found) {
|
||||
// If script not found we still return an empty mapping structure
|
||||
return { name, mappings: [] };
|
||||
}
|
||||
return { name: found.name, mappings: found.mappings || [] };
|
||||
};
|
||||
|
||||
/**
|
||||
* Upload a script (multipart). If a requirements file is provided the backend
|
||||
* will run pip install and return pip output in the response (mandatory install).
|
||||
*/
|
||||
export const uploadScript = async (opts: {
|
||||
name: string;
|
||||
script: File | Blob;
|
||||
@@ -193,19 +216,59 @@ export const uploadScript = async (opts: {
|
||||
fd.append('script', opts.script);
|
||||
if (opts.requirements) fd.append('requirements', opts.requirements as Blob);
|
||||
|
||||
// axios will set multipart/form-data boundary automatically when FormData passed
|
||||
const res = await api.post<ScriptUploadResponse>('/scripts/scripts', fd, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Download the script file as a Blob. Use this blob to create an object URL or read text.
|
||||
*/
|
||||
export const downloadScript = async (name: string): Promise<Blob> => {
|
||||
// expect the backend to return a FileResponse. request as blob to trigger browser download handling.
|
||||
const res = await api.get(`/scripts/scripts/${encodeURIComponent(name)}`, { responseType: 'blob' });
|
||||
return res.data as Blob;
|
||||
};
|
||||
|
||||
/**
|
||||
* Download the requirements.txt for a script as a Blob.
|
||||
* Returns 404 if not present (axios will throw).
|
||||
*/
|
||||
export const downloadRequirements = async (name: string): Promise<Blob> => {
|
||||
const res = await api.get(`/scripts/scripts/${encodeURIComponent(name)}/requirements`, { responseType: 'blob' });
|
||||
return res.data as Blob;
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace / upload requirements for a script. This endpoint ALWAYS runs pip install
|
||||
* and will return pip stdout/stderr on success. On pip failure the backend returns 500.
|
||||
*
|
||||
* Use multipart/form-data so Swagger UI shows a file picker (backend expects UploadFile).
|
||||
*/
|
||||
export const uploadRequirements = async (
|
||||
name: string,
|
||||
requirements: File | Blob,
|
||||
): Promise<RequirementsUploadResult> => {
|
||||
const fd = new FormData();
|
||||
fd.append('requirements', requirements);
|
||||
const res = await api.put<RequirementsUploadResult>(`/scripts/scripts/${encodeURIComponent(name)}/requirements`, fd, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete only the requirements file and attempt to clean up the venv.
|
||||
* Returns summary `{ removed: { requirements_removed, venv_removed }, errors? }`.
|
||||
*/
|
||||
export const deleteRequirements = async (name: string): Promise<RequirementsDeleteResult> => {
|
||||
const res = await api.delete<RequirementsDeleteResult>(`/scripts/scripts/${encodeURIComponent(name)}/requirements`);
|
||||
return res.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a script (and its files / venv). If qnum provided only remove that unit.
|
||||
*/
|
||||
export const deleteScript = async (name: string, qnum?: number | null): Promise<DeleteResult> => {
|
||||
const params: Record<string, any> = {};
|
||||
if (typeof qnum !== 'undefined' && qnum !== null) params.qnum = qnum;
|
||||
@@ -213,13 +276,18 @@ export const deleteScript = async (name: string, qnum?: number | null): Promise<
|
||||
return res.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable a script (creates + starts a systemd unit). Returns OperationResult including service name.
|
||||
*/
|
||||
export const enableScript = async (name: string, req: EnableRequest): Promise<OperationResult> => {
|
||||
const res = await api.post<OperationResult>(`/scripts/scripts/${encodeURIComponent(name)}/enable`, req);
|
||||
return res.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable a script unit (POST with qnum as query param). Returns OperationResult.
|
||||
*/
|
||||
export const disableScript = async (name: string, qnum: number): Promise<OperationResult> => {
|
||||
// backend expects qnum as query param (POST body null)
|
||||
const res = await api.post<OperationResult>(`/scripts/scripts/${encodeURIComponent(name)}/disable`, null, {
|
||||
params: { qnum },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user