fix(ui): encode every id in API paths (client-side path traversal)
Follow-up to a7609ff for the whole frontend: all 30 API helpers in
src/lib now pass path values through encodeURIComponent, so an id taken
from the URL can never leave its own path segment and make the page call
another endpoint with the viewer's token.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
a7609ff3f8
commit
fc887d8431
30 files changed
+90
-90
No files matched your search
@@ -13,12 +13,12 @@ export function createApiKey(input: CreateApiKeyInput): Promise<CreatedApiKey> {
|
||||
}
|
||||
|
||||
export function updateApiKeyAllowedIps(id: string, allowedIps: string[]): Promise<ApiKey> {
|
||||
return apiFetch<ApiKey>(`/api-keys/${id}`, {
|
||||
return apiFetch<ApiKey>(`/api-keys/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify({ allowedIps }),
|
||||
});
|
||||
}
|
||||
|
||||
export function revokeApiKey(id: string): Promise<ApiKey> {
|
||||
return apiFetch<ApiKey>(`/api-keys/${id}/revoke`, { method: "POST" });
|
||||
return apiFetch<ApiKey>(`/api-keys/${encodeURIComponent(id)}/revoke`, { method: "POST" });
|
||||
}
|
||||
@@ -15,7 +15,7 @@ export function fetchApiaries(filter: ApiaryFilter = {}): Promise<Apiary[]> {
|
||||
}
|
||||
|
||||
export function fetchApiary(id: string): Promise<Apiary> {
|
||||
return apiFetch<Apiary>(`/apiaries/${id}`);
|
||||
return apiFetch<Apiary>(`/apiaries/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function createApiary(input: ApiaryInput): Promise<Apiary> {
|
||||
@@ -26,16 +26,16 @@ export function createApiary(input: ApiaryInput): Promise<Apiary> {
|
||||
}
|
||||
|
||||
export function updateApiary(id: string, input: Partial<ApiaryInput>): Promise<Apiary> {
|
||||
return apiFetch<Apiary>(`/apiaries/${id}`, {
|
||||
return apiFetch<Apiary>(`/apiaries/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function deactivateApiary(id: string): Promise<Apiary> {
|
||||
return apiFetch<Apiary>(`/apiaries/${id}/deactivate`, { method: "POST" });
|
||||
return apiFetch<Apiary>(`/apiaries/${encodeURIComponent(id)}/deactivate`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function reactivateApiary(id: string): Promise<Apiary> {
|
||||
return apiFetch<Apiary>(`/apiaries/${id}/reactivate`, { method: "POST" });
|
||||
return apiFetch<Apiary>(`/apiaries/${encodeURIComponent(id)}/reactivate`, { method: "POST" });
|
||||
}
|
||||
@@ -9,14 +9,14 @@ export function updateAutomationRule(
|
||||
id: string,
|
||||
input: UpdateAutomationRuleInput,
|
||||
): Promise<AutomationRule> {
|
||||
return apiFetch<AutomationRule>(`/automation-rules/${id}`, {
|
||||
return apiFetch<AutomationRule>(`/automation-rules/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function resetAutomationRuleSequence(id: string): Promise<AutomationRule> {
|
||||
return apiFetch<AutomationRule>(`/automation-rules/${id}/reset-sequence`, {
|
||||
return apiFetch<AutomationRule>(`/automation-rules/${encodeURIComponent(id)}/reset-sequence`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
@@ -16,7 +16,7 @@ export function fetchBottlingBatches(
|
||||
}
|
||||
|
||||
export function fetchBottlingBatch(id: string): Promise<BottlingBatch> {
|
||||
return apiFetch<BottlingBatch>(`/bottling-batches/${id}`);
|
||||
return apiFetch<BottlingBatch>(`/bottling-batches/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function createBottlingBatch(
|
||||
@@ -32,14 +32,14 @@ export function updateBottlingBatch(
|
||||
id: string,
|
||||
input: UpdateBottlingBatchInput,
|
||||
): Promise<BottlingBatch> {
|
||||
return apiFetch<BottlingBatch>(`/bottling-batches/${id}`, {
|
||||
return apiFetch<BottlingBatch>(`/bottling-batches/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteBottlingBatch(id: string): Promise<{ id: string }> {
|
||||
return apiFetch<{ id: string }>(`/bottling-batches/${id}`, {
|
||||
return apiFetch<{ id: string }>(`/bottling-batches/${encodeURIComponent(id)}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
@@ -24,11 +24,11 @@ export function fetchColonies(filter: ColonyFilter = {}): Promise<Colony[]> {
|
||||
}
|
||||
|
||||
export function fetchColony(id: string): Promise<Colony> {
|
||||
return apiFetch<Colony>(`/colonies/${id}`);
|
||||
return apiFetch<Colony>(`/colonies/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function fetchColonyHistory(id: string): Promise<ColonyHistory> {
|
||||
return apiFetch<ColonyHistory>(`/colonies/${id}/history`);
|
||||
return apiFetch<ColonyHistory>(`/colonies/${encodeURIComponent(id)}/history`);
|
||||
}
|
||||
|
||||
export function createColony(input: CreateColonyInput): Promise<Colony> {
|
||||
@@ -39,37 +39,37 @@ export function createColony(input: CreateColonyInput): Promise<Colony> {
|
||||
}
|
||||
|
||||
export function updateColony(id: string, input: UpdateColonyInput): Promise<Colony> {
|
||||
return apiFetch<Colony>(`/colonies/${id}`, {
|
||||
return apiFetch<Colony>(`/colonies/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function moveColony(id: string, input: MoveColonyInput): Promise<Colony> {
|
||||
return apiFetch<Colony>(`/colonies/${id}/move`, {
|
||||
return apiFetch<Colony>(`/colonies/${encodeURIComponent(id)}/move`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function splitColony(id: string, input: SplitColonyInput): Promise<Colony> {
|
||||
return apiFetch<Colony>(`/colonies/${id}/split`, {
|
||||
return apiFetch<Colony>(`/colonies/${encodeURIComponent(id)}/split`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function mergeColony(id: string, input: MergeColonyInput): Promise<Colony> {
|
||||
return apiFetch<Colony>(`/colonies/${id}/merge`, {
|
||||
return apiFetch<Colony>(`/colonies/${encodeURIComponent(id)}/merge`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function dissolveColony(id: string): Promise<Colony> {
|
||||
return apiFetch<Colony>(`/colonies/${id}/dissolve`, { method: "POST" });
|
||||
return apiFetch<Colony>(`/colonies/${encodeURIComponent(id)}/dissolve`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function reactivateColony(id: string): Promise<Colony> {
|
||||
return apiFetch<Colony>(`/colonies/${id}/reactivate`, { method: "POST" });
|
||||
return apiFetch<Colony>(`/colonies/${encodeURIComponent(id)}/reactivate`, { method: "POST" });
|
||||
}
|
||||
@@ -30,17 +30,17 @@ export function updateDocument(
|
||||
id: string,
|
||||
input: UpdateDocumentInput,
|
||||
): Promise<DocumentSummary> {
|
||||
return apiFetch<DocumentSummary>(`/documents/${id}`, {
|
||||
return apiFetch<DocumentSummary>(`/documents/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteDocument(id: string): Promise<void> {
|
||||
return apiFetch<void>(`/documents/${id}`, { method: "DELETE" });
|
||||
return apiFetch<void>(`/documents/${encodeURIComponent(id)}`, { method: "DELETE" });
|
||||
}
|
||||
|
||||
export async function downloadDocument(id: string, fileName: string): Promise<void> {
|
||||
const { blob, filename } = await apiFetchBlob(`/documents/${id}/download`, fileName);
|
||||
const { blob, filename } = await apiFetchBlob(`/documents/${encodeURIComponent(id)}/download`, fileName);
|
||||
downloadBlob(blob, filename);
|
||||
}
|
||||
@@ -14,7 +14,7 @@ export function fetchEquipmentList(filter: EquipmentFilter = {}): Promise<Equipm
|
||||
}
|
||||
|
||||
export function fetchEquipment(id: string): Promise<Equipment> {
|
||||
return apiFetch<Equipment>(`/equipment/${id}`);
|
||||
return apiFetch<Equipment>(`/equipment/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function createEquipment(input: CreateEquipmentInput): Promise<Equipment> {
|
||||
@@ -28,7 +28,7 @@ export function updateEquipment(
|
||||
id: string,
|
||||
input: UpdateEquipmentInput,
|
||||
): Promise<Equipment> {
|
||||
return apiFetch<Equipment>(`/equipment/${id}`, {
|
||||
return apiFetch<Equipment>(`/equipment/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ export function fetchExtractions(): Promise<Extraction[]> {
|
||||
}
|
||||
|
||||
export function fetchExtraction(id: string): Promise<Extraction> {
|
||||
return apiFetch<Extraction>(`/extractions/${id}`);
|
||||
return apiFetch<Extraction>(`/extractions/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function createExtraction(input: CreateExtractionInput): Promise<Extraction> {
|
||||
@@ -20,7 +20,7 @@ export function updateExtraction(
|
||||
id: string,
|
||||
input: UpdateExtractionInput,
|
||||
): Promise<Extraction> {
|
||||
return apiFetch<Extraction>(`/extractions/${id}`, {
|
||||
return apiFetch<Extraction>(`/extractions/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -8,11 +8,11 @@ import {
|
||||
} from "./types";
|
||||
|
||||
export function fetchColonyFeedings(colonyId: string): Promise<Feeding[]> {
|
||||
return apiFetch<Feeding[]>(`/colonies/${colonyId}/feedings`);
|
||||
return apiFetch<Feeding[]>(`/colonies/${encodeURIComponent(colonyId)}/feedings`);
|
||||
}
|
||||
|
||||
export function fetchColonyFeedingsSummary(colonyId: string): Promise<FeedingSummaryEntry[]> {
|
||||
return apiFetch<FeedingSummaryEntry[]>(`/colonies/${colonyId}/feedings/summary`);
|
||||
return apiFetch<FeedingSummaryEntry[]>(`/colonies/${encodeURIComponent(colonyId)}/feedings/summary`);
|
||||
}
|
||||
|
||||
export function createFeeding(
|
||||
@@ -30,7 +30,7 @@ export function updateFeeding(
|
||||
id: string,
|
||||
input: UpdateFeedingInput,
|
||||
): Promise<Feeding> {
|
||||
return apiFetch<Feeding>(`/feedings/${id}`, {
|
||||
return apiFetch<Feeding>(`/feedings/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ export function fetchHarvests(): Promise<Harvest[]> {
|
||||
}
|
||||
|
||||
export function fetchHarvest(id: string): Promise<Harvest> {
|
||||
return apiFetch<Harvest>(`/harvests/${id}`);
|
||||
return apiFetch<Harvest>(`/harvests/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function createHarvest(
|
||||
@@ -22,7 +22,7 @@ export function createHarvest(
|
||||
}
|
||||
|
||||
export function updateHarvest(id: string, input: UpdateHarvestInput): Promise<Harvest> {
|
||||
return apiFetch<Harvest>(`/harvests/${id}`, {
|
||||
return apiFetch<Harvest>(`/harvests/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -24,11 +24,11 @@ export function fetchHoneyBatches(filter: HoneyBatchFilter = {}): Promise<HoneyB
|
||||
}
|
||||
|
||||
export function fetchHoneyBatch(id: string): Promise<HoneyBatch> {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/${id}`);
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function fetchHoneyBatchTraceability(id: string): Promise<Traceability> {
|
||||
return apiFetch<Traceability>(`/honey-batches/${id}/traceability`);
|
||||
return apiFetch<Traceability>(`/honey-batches/${encodeURIComponent(id)}/traceability`);
|
||||
}
|
||||
|
||||
export function createHoneyBatch(input: CreateHoneyBatchInput): Promise<HoneyBatch> {
|
||||
@@ -42,7 +42,7 @@ export function updateHoneyBatch(
|
||||
id: string,
|
||||
input: UpdateHoneyBatchInput,
|
||||
): Promise<HoneyBatch> {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/${id}`, {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
@@ -52,7 +52,7 @@ export function updateHoneyMeasurement(
|
||||
measurementId: string,
|
||||
input: UpdateHoneyMeasurementInput,
|
||||
): Promise<HoneyBatch> {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/measurements/${measurementId}`, {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/measurements/${encodeURIComponent(measurementId)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
@@ -62,7 +62,7 @@ export function addHoneyMeasurement(
|
||||
id: string,
|
||||
input: CreateHoneyMeasurementInput,
|
||||
): Promise<HoneyBatch> {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/${id}/measurements`, {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/${encodeURIComponent(id)}/measurements`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
@@ -72,20 +72,20 @@ export function relocateHoneyBatch(
|
||||
id: string,
|
||||
input: RelocateHoneyBatchInput,
|
||||
): Promise<HoneyBatch> {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/${id}/relocate`, {
|
||||
return apiFetch<HoneyBatch>(`/honey-batches/${encodeURIComponent(id)}/relocate`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchHoneyBatchRelocations(id: string): Promise<HoneyBatchRelocation[]> {
|
||||
return apiFetch<HoneyBatchRelocation[]>(`/honey-batches/${id}/relocations`);
|
||||
return apiFetch<HoneyBatchRelocation[]>(`/honey-batches/${encodeURIComponent(id)}/relocations`);
|
||||
}
|
||||
|
||||
export function fetchHoneyBatchContainerAllocations(
|
||||
id: string,
|
||||
): Promise<HoneyBatchContainerAllocation[]> {
|
||||
return apiFetch<HoneyBatchContainerAllocation[]>(`/honey-batches/${id}/containers`);
|
||||
return apiFetch<HoneyBatchContainerAllocation[]>(`/honey-batches/${encodeURIComponent(id)}/containers`);
|
||||
}
|
||||
|
||||
export function setHoneyBatchContainerAllocation(
|
||||
@@ -94,7 +94,7 @@ export function setHoneyBatchContainerAllocation(
|
||||
amount: number,
|
||||
): Promise<HoneyBatchContainerAllocation> {
|
||||
return apiFetch<HoneyBatchContainerAllocation>(
|
||||
`/honey-batches/${id}/containers/${containerId}`,
|
||||
`/honey-batches/${encodeURIComponent(id)}/containers/${encodeURIComponent(containerId)}`,
|
||||
{ method: "PUT", body: JSON.stringify({ amount }) },
|
||||
);
|
||||
}
|
||||
@@ -103,7 +103,7 @@ export function removeHoneyBatchContainerAllocation(
|
||||
id: string,
|
||||
containerId: string,
|
||||
): Promise<void> {
|
||||
return apiFetch<void>(`/honey-batches/${id}/containers/${containerId}`, {
|
||||
return apiFetch<void>(`/honey-batches/${encodeURIComponent(id)}/containers/${encodeURIComponent(containerId)}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
@@ -4,5 +4,5 @@ import { ImportEntity, ImportReport } from "./types";
|
||||
export function importCsv(entity: ImportEntity, file: File): Promise<ImportReport> {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
return apiFetchFormData<ImportReport>(`/import/${entity}`, formData);
|
||||
return apiFetchFormData<ImportReport>(`/import/${encodeURIComponent(entity)}`, formData);
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from "./types";
|
||||
|
||||
export function fetchColonyInspections(colonyId: string): Promise<Inspection[]> {
|
||||
return apiFetch<Inspection[]>(`/colonies/${colonyId}/inspections`);
|
||||
return apiFetch<Inspection[]>(`/colonies/${encodeURIComponent(colonyId)}/inspections`);
|
||||
}
|
||||
|
||||
export function createInspection(
|
||||
@@ -27,7 +27,7 @@ export function updateInspection(
|
||||
id: string,
|
||||
input: UpdateInspectionInput,
|
||||
): Promise<Inspection> {
|
||||
return apiFetch<Inspection>(`/inspections/${id}`, {
|
||||
return apiFetch<Inspection>(`/inspections/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
@@ -37,7 +37,7 @@ export function createTaskFromInspection(
|
||||
id: string,
|
||||
input: CreateTaskFromInspectionInput,
|
||||
): Promise<InspectionTask> {
|
||||
return apiFetch<InspectionTask>(`/inspections/${id}/create-task`, {
|
||||
return apiFetch<InspectionTask>(`/inspections/${encodeURIComponent(id)}/create-task`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -17,14 +17,14 @@ export function updateLabelTemplate(
|
||||
id: string,
|
||||
input: UpdateLabelTemplateInput,
|
||||
): Promise<LabelTemplate> {
|
||||
return apiFetch<LabelTemplate>(`/label-templates/${id}`, {
|
||||
return apiFetch<LabelTemplate>(`/label-templates/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function deactivateLabelTemplate(id: string): Promise<LabelTemplate> {
|
||||
return apiFetch<LabelTemplate>(`/label-templates/${id}`, { method: "DELETE" });
|
||||
return apiFetch<LabelTemplate>(`/label-templates/${encodeURIComponent(id)}`, { method: "DELETE" });
|
||||
}
|
||||
|
||||
export async function printLabels(
|
||||
@@ -34,7 +34,7 @@ export async function printLabels(
|
||||
): Promise<void> {
|
||||
const query = startPosition && startPosition > 1 ? `?startPosition=${startPosition}` : "";
|
||||
const { blob, filename } = await apiFetchBlob(
|
||||
`/label-templates/${templateId}/print/${bottlingBatchId}${query}`,
|
||||
`/label-templates/${encodeURIComponent(templateId)}/print/${encodeURIComponent(bottlingBatchId)}${query}`,
|
||||
"etiketten.pdf",
|
||||
);
|
||||
downloadBlob(blob, filename);
|
||||
|
||||
@@ -6,5 +6,5 @@ export function fetchNotifications(unreadOnly = false): Promise<Notification[]>
|
||||
}
|
||||
|
||||
export function markNotificationRead(id: string): Promise<Notification> {
|
||||
return apiFetch<Notification>(`/notifications/${id}/read`, { method: "POST" });
|
||||
return apiFetch<Notification>(`/notifications/${encodeURIComponent(id)}/read`, { method: "POST" });
|
||||
}
|
||||
@@ -14,7 +14,7 @@ export function fetchProducts(filter: ProductFilter = {}): Promise<Product[]> {
|
||||
}
|
||||
|
||||
export function fetchProduct(id: string): Promise<Product> {
|
||||
return apiFetch<Product>(`/products/${id}`);
|
||||
return apiFetch<Product>(`/products/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function createProduct(input: CreateProductInput): Promise<Product> {
|
||||
@@ -25,7 +25,7 @@ export function createProduct(input: CreateProductInput): Promise<Product> {
|
||||
}
|
||||
|
||||
export function updateProduct(id: string, input: UpdateProductInput): Promise<Product> {
|
||||
return apiFetch<Product>(`/products/${id}`, {
|
||||
return apiFetch<Product>(`/products/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -9,11 +9,11 @@ export type QrEntityType =
|
||||
| "bottling-batches";
|
||||
|
||||
export async function fetchQrCodeSvg(entityType: QrEntityType, id: string): Promise<Blob> {
|
||||
const { blob } = await apiFetchBlob(`/qr/${entityType}/${id}.svg`, `${entityType}.svg`);
|
||||
const { blob } = await apiFetchBlob(`/qr/${encodeURIComponent(entityType)}/${encodeURIComponent(id)}.svg`, `${entityType}.svg`);
|
||||
return blob;
|
||||
}
|
||||
|
||||
export async function fetchQrLink(entityType: QrEntityType, id: string): Promise<string> {
|
||||
const { url } = await apiFetch<{ url: string }>(`/qr/${entityType}/${id}/link`);
|
||||
const { url } = await apiFetch<{ url: string }>(`/qr/${encodeURIComponent(entityType)}/${encodeURIComponent(id)}/link`);
|
||||
return url;
|
||||
}
|
||||
@@ -24,15 +24,15 @@ export function fetchQueens(filter: QueenFilter = {}): Promise<Queen[]> {
|
||||
}
|
||||
|
||||
export function fetchQueen(id: string): Promise<Queen> {
|
||||
return apiFetch<Queen>(`/queens/${id}`);
|
||||
return apiFetch<Queen>(`/queens/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function fetchQueenHistory(id: string): Promise<QueenColonyHistoryEntry[]> {
|
||||
return apiFetch<QueenColonyHistoryEntry[]>(`/queens/${id}/history`);
|
||||
return apiFetch<QueenColonyHistoryEntry[]>(`/queens/${encodeURIComponent(id)}/history`);
|
||||
}
|
||||
|
||||
export function fetchQueenLineage(id: string): Promise<QueenLineage> {
|
||||
return apiFetch<QueenLineage>(`/queens/${id}/lineage`);
|
||||
return apiFetch<QueenLineage>(`/queens/${encodeURIComponent(id)}/lineage`);
|
||||
}
|
||||
|
||||
export function createQueen(input: CreateQueenInput): Promise<Queen> {
|
||||
@@ -43,28 +43,28 @@ export function createQueen(input: CreateQueenInput): Promise<Queen> {
|
||||
}
|
||||
|
||||
export function updateQueen(id: string, input: UpdateQueenInput): Promise<Queen> {
|
||||
return apiFetch<Queen>(`/queens/${id}`, {
|
||||
return apiFetch<Queen>(`/queens/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function assignQueenColony(id: string, input: AssignColonyInput): Promise<Queen> {
|
||||
return apiFetch<Queen>(`/queens/${id}/assign-colony`, {
|
||||
return apiFetch<Queen>(`/queens/${encodeURIComponent(id)}/assign-colony`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchQueenEvaluations(id: string): Promise<QueenEvaluation[]> {
|
||||
return apiFetch<QueenEvaluation[]>(`/queens/${id}/evaluations`);
|
||||
return apiFetch<QueenEvaluation[]>(`/queens/${encodeURIComponent(id)}/evaluations`);
|
||||
}
|
||||
|
||||
export function updateQueenEvaluation(
|
||||
evaluationId: string,
|
||||
input: UpdateQueenEvaluationInput,
|
||||
): Promise<QueenEvaluation> {
|
||||
return apiFetch<QueenEvaluation>(`/queens/evaluations/${evaluationId}`, {
|
||||
return apiFetch<QueenEvaluation>(`/queens/evaluations/${encodeURIComponent(evaluationId)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
@@ -74,7 +74,7 @@ export function addQueenEvaluation(
|
||||
id: string,
|
||||
input: CreateQueenEvaluationInput,
|
||||
): Promise<QueenEvaluation> {
|
||||
return apiFetch<QueenEvaluation>(`/queens/${id}/evaluations`, {
|
||||
return apiFetch<QueenEvaluation>(`/queens/${encodeURIComponent(id)}/evaluations`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -22,16 +22,16 @@ export function createRole(input: CreateRoleInput): Promise<RoleSummary> {
|
||||
}
|
||||
|
||||
export function updateRole(id: string, input: UpdateRoleInput): Promise<RoleSummary> {
|
||||
return apiFetch<RoleSummary>(`/roles/${id}`, {
|
||||
return apiFetch<RoleSummary>(`/roles/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function deactivateRole(id: string): Promise<RoleSummary> {
|
||||
return apiFetch<RoleSummary>(`/roles/${id}/deactivate`, { method: "POST" });
|
||||
return apiFetch<RoleSummary>(`/roles/${encodeURIComponent(id)}/deactivate`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function reactivateRole(id: string): Promise<RoleSummary> {
|
||||
return apiFetch<RoleSummary>(`/roles/${id}/reactivate`, { method: "POST" });
|
||||
return apiFetch<RoleSummary>(`/roles/${encodeURIComponent(id)}/reactivate`, { method: "POST" });
|
||||
}
|
||||
@@ -10,7 +10,7 @@ export function fetchStock(
|
||||
path: StockBatchPath,
|
||||
id: string,
|
||||
): Promise<BatchStock> {
|
||||
return apiFetch<BatchStock>(`/${path}/${encodeURIComponent(id)}/stock`);
|
||||
return apiFetch<BatchStock>(`/${encodeURIComponent(path)}/${encodeURIComponent(id)}/stock`);
|
||||
}
|
||||
|
||||
export function withdrawStock(
|
||||
@@ -19,7 +19,7 @@ export function withdrawStock(
|
||||
input: WithdrawInput,
|
||||
): Promise<BatchStock> {
|
||||
return apiFetch<BatchStock>(
|
||||
`/${path}/${encodeURIComponent(id)}/withdrawals`,
|
||||
`/${encodeURIComponent(path)}/${encodeURIComponent(id)}/withdrawals`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
@@ -33,7 +33,7 @@ export function correctStock(
|
||||
input: CorrectInput,
|
||||
): Promise<BatchStock> {
|
||||
return apiFetch<BatchStock>(
|
||||
`/${path}/${encodeURIComponent(id)}/corrections`,
|
||||
`/${encodeURIComponent(path)}/${encodeURIComponent(id)}/corrections`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
|
||||
@@ -26,7 +26,7 @@ export function updateStorageContainer(
|
||||
id: string,
|
||||
input: UpdateStorageContainerInput,
|
||||
): Promise<StorageContainer> {
|
||||
return apiFetch<StorageContainer>(`/storage-containers/${id}`, {
|
||||
return apiFetch<StorageContainer>(`/storage-containers/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
@@ -47,7 +47,7 @@ export function updateStockItem(
|
||||
id: string,
|
||||
input: UpdateStockItemInput,
|
||||
): Promise<StockItem> {
|
||||
return apiFetch<StockItem>(`/stock-items/${id}`, {
|
||||
return apiFetch<StockItem>(`/stock-items/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
@@ -57,7 +57,7 @@ export function addStockMovement(
|
||||
id: string,
|
||||
input: CreateStockMovementInput,
|
||||
): Promise<StockItem> {
|
||||
return apiFetch<StockItem>(`/stock-items/${id}/movements`, {
|
||||
return apiFetch<StockItem>(`/stock-items/${encodeURIComponent(id)}/movements`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from "./types";
|
||||
|
||||
export function fetchColonySwarmControlChecks(colonyId: string): Promise<SwarmControlCheck[]> {
|
||||
return apiFetch<SwarmControlCheck[]>(`/colonies/${colonyId}/swarm-control-checks`);
|
||||
return apiFetch<SwarmControlCheck[]>(`/colonies/${encodeURIComponent(colonyId)}/swarm-control-checks`);
|
||||
}
|
||||
|
||||
export function createSwarmControlCheck(
|
||||
@@ -25,7 +25,7 @@ export function updateSwarmControlCheck(
|
||||
id: string,
|
||||
input: UpdateSwarmControlCheckInput,
|
||||
): Promise<SwarmControlCheck> {
|
||||
return apiFetch<SwarmControlCheck>(`/swarm-control-checks/${id}`, {
|
||||
return apiFetch<SwarmControlCheck>(`/swarm-control-checks/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -13,12 +13,12 @@ export function createTaskTemplate(input: CreateTaskTemplateInput): Promise<Task
|
||||
}
|
||||
|
||||
export function updateTaskTemplate(id: string, input: UpdateTaskTemplateInput): Promise<TaskTemplate> {
|
||||
return apiFetch<TaskTemplate>(`/task-templates/${id}`, {
|
||||
return apiFetch<TaskTemplate>(`/task-templates/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function deactivateTaskTemplate(id: string): Promise<TaskTemplate> {
|
||||
return apiFetch<TaskTemplate>(`/task-templates/${id}/deactivate`, { method: "POST" });
|
||||
return apiFetch<TaskTemplate>(`/task-templates/${encodeURIComponent(id)}/deactivate`, { method: "POST" });
|
||||
}
|
||||
@@ -17,12 +17,12 @@ export function createTask(input: CreateTaskInput): Promise<Task> {
|
||||
}
|
||||
|
||||
export function updateTask(id: string, input: UpdateTaskInput): Promise<Task> {
|
||||
return apiFetch<Task>(`/tasks/${id}`, {
|
||||
return apiFetch<Task>(`/tasks/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function completeTask(id: string): Promise<Task> {
|
||||
return apiFetch<Task>(`/tasks/${id}/complete`, { method: "POST" });
|
||||
return apiFetch<Task>(`/tasks/${encodeURIComponent(id)}/complete`, { method: "POST" });
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "./types";
|
||||
|
||||
export function fetchColonyTreatments(colonyId: string): Promise<Treatment[]> {
|
||||
return apiFetch<Treatment[]>(`/colonies/${colonyId}/treatments`);
|
||||
return apiFetch<Treatment[]>(`/colonies/${encodeURIComponent(colonyId)}/treatments`);
|
||||
}
|
||||
|
||||
export function fetchWithdrawalStatus(
|
||||
@@ -37,7 +37,7 @@ export function updateTreatment(
|
||||
id: string,
|
||||
input: UpdateTreatmentInput,
|
||||
): Promise<Treatment> {
|
||||
return apiFetch<Treatment>(`/treatments/${id}`, {
|
||||
return apiFetch<Treatment>(`/treatments/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ export function createUser(input: CreateUserInput): Promise<User> {
|
||||
}
|
||||
|
||||
export function updateUser(id: string, input: UpdateUserInput): Promise<User> {
|
||||
return apiFetch<User>(`/users/${id}`, {
|
||||
return apiFetch<User>(`/users/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
@@ -23,20 +23,20 @@ export function resetUserPassword(
|
||||
id: string,
|
||||
password: string,
|
||||
): Promise<User> {
|
||||
return apiFetch<User>(`/users/${id}/reset-password`, {
|
||||
return apiFetch<User>(`/users/${encodeURIComponent(id)}/reset-password`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ password }),
|
||||
});
|
||||
}
|
||||
|
||||
export function deactivateUser(id: string): Promise<User> {
|
||||
return apiFetch<User>(`/users/${id}/deactivate`, { method: "POST" });
|
||||
return apiFetch<User>(`/users/${encodeURIComponent(id)}/deactivate`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function activateUser(id: string): Promise<User> {
|
||||
return apiFetch<User>(`/users/${id}/activate`, { method: "POST" });
|
||||
return apiFetch<User>(`/users/${encodeURIComponent(id)}/activate`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function resetUserMfa(id: string): Promise<User> {
|
||||
return apiFetch<User>(`/users/${id}/mfa/reset`, { method: "POST" });
|
||||
return apiFetch<User>(`/users/${encodeURIComponent(id)}/mfa/reset`, { method: "POST" });
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from "./types";
|
||||
|
||||
export function fetchColonyVarroaMeasurements(colonyId: string): Promise<VarroaMeasurement[]> {
|
||||
return apiFetch<VarroaMeasurement[]>(`/colonies/${colonyId}/varroa-measurements`);
|
||||
return apiFetch<VarroaMeasurement[]>(`/colonies/${encodeURIComponent(colonyId)}/varroa-measurements`);
|
||||
}
|
||||
|
||||
export function createVarroaMeasurement(
|
||||
@@ -25,7 +25,7 @@ export function updateVarroaMeasurement(
|
||||
id: string,
|
||||
input: UpdateVarroaMeasurementInput,
|
||||
): Promise<VarroaMeasurement> {
|
||||
return apiFetch<VarroaMeasurement>(`/varroa-measurements/${id}`, {
|
||||
return apiFetch<VarroaMeasurement>(`/varroa-measurements/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
@@ -2,9 +2,9 @@ import { apiFetch } from "@/lib/auth/api-client";
|
||||
import { ApiaryWeather, Trachtprognose } from "./types";
|
||||
|
||||
export function fetchApiaryWeather(apiaryId: string): Promise<ApiaryWeather> {
|
||||
return apiFetch<ApiaryWeather>(`/apiaries/${apiaryId}/weather`);
|
||||
return apiFetch<ApiaryWeather>(`/apiaries/${encodeURIComponent(apiaryId)}/weather`);
|
||||
}
|
||||
|
||||
export function fetchTrachtprognose(apiaryId: string): Promise<Trachtprognose> {
|
||||
return apiFetch<Trachtprognose>(`/apiaries/${apiaryId}/trachtprognose`);
|
||||
return apiFetch<Trachtprognose>(`/apiaries/${encodeURIComponent(apiaryId)}/trachtprognose`);
|
||||
}
|
||||
@@ -21,12 +21,12 @@ export function updateWebhook(
|
||||
id: string,
|
||||
input: UpdateWebhookInput,
|
||||
): Promise<WebhookSubscription> {
|
||||
return apiFetch<WebhookSubscription>(`/webhooks/${id}`, {
|
||||
return apiFetch<WebhookSubscription>(`/webhooks/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteWebhook(id: string): Promise<void> {
|
||||
return apiFetch<void>(`/webhooks/${id}`, { method: "DELETE" });
|
||||
return apiFetch<void>(`/webhooks/${encodeURIComponent(id)}`, { method: "DELETE" });
|
||||
}
|
||||
@@ -30,7 +30,7 @@ export function updateWinterCheck(
|
||||
id: string,
|
||||
input: Partial<WinterCheckInput>,
|
||||
): Promise<WinterCheck> {
|
||||
return apiFetch<WinterCheck>(`/winter-checks/${id}`, {
|
||||
return apiFetch<WinterCheck>(`/winter-checks/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user