feat(nextcloud-status): Cloud-Formular zeigt nur deutsche Meldungen, Bildadresse auch per http (j9f)
- Vorabpruefung im Browser, API-Kennungen werden zu de/en-Texten - Beschriftung Bildadresse mit neuem Hinweis zu http und https Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,16 +97,43 @@ export function logoSrc(
|
||||
return instance.logoUrl ?? null;
|
||||
}
|
||||
|
||||
/** Liest die NestJS-Fehlermeldung aus dem Antwortkoerper, faellt sonst auf einen Standardtext zurueck. */
|
||||
async function readErrorMessage(res: Response, fallback: string): Promise<string> {
|
||||
/**
|
||||
* Fehler der Cloud-Routen mit Statuscode und stabiler Kennung (quick-261008-j9f,
|
||||
* D-05). `code` ist `body.code` der API (z. B. `logoFetchInternal`) oder, bei
|
||||
* Meldungen der globalen Eingabepruefung, die Kennung als Meldungstext; sonst
|
||||
* `null`. Die Oberflaeche zeigt nie `message`, sondern uebersetzt die Kennung
|
||||
* (siehe `cloud-form-errors.ts`); `message` bleibt fuer andere Aufrufer lesbar.
|
||||
*/
|
||||
export class NextcloudFormError extends Error {
|
||||
public readonly status: number;
|
||||
public readonly code: string | null;
|
||||
|
||||
constructor(status: number, code: string | null, message: string) {
|
||||
super(message);
|
||||
this.name = 'NextcloudFormError';
|
||||
this.status = status;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
/** Liest Kennung und Meldung aus dem Antwortkoerper; ohne lesbaren Koerper gilt der Standardtext. */
|
||||
async function readError(res: Response, fallback: string): Promise<NextcloudFormError> {
|
||||
let code: string | null = null;
|
||||
let message = fallback;
|
||||
try {
|
||||
const body = await res.json();
|
||||
if (typeof body?.message === 'string') return body.message;
|
||||
if (Array.isArray(body?.message) && body.message.length > 0) return String(body.message[0]);
|
||||
if (typeof body?.code === 'string') code = body.code;
|
||||
if (typeof body?.message === 'string') {
|
||||
message = body.message;
|
||||
} else if (Array.isArray(body?.message) && body.message.length > 0) {
|
||||
message = String(body.message[0]);
|
||||
// Meldungen der Eingabepruefung sind Kennungen (nur Buchstaben, klein beginnend).
|
||||
if (code === null && /^[a-z][A-Za-z]*$/.test(message)) code = message;
|
||||
}
|
||||
} catch {
|
||||
/* Antwort war kein JSON — Standardtext bleibt */
|
||||
}
|
||||
return fallback;
|
||||
return new NextcloudFormError(res.status, code, message);
|
||||
}
|
||||
|
||||
export interface NextcloudInstancePayload {
|
||||
@@ -128,7 +155,7 @@ export async function createInstance(
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to create nextcloud instance'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to create nextcloud instance');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
@@ -143,27 +170,27 @@ export async function updateInstance(
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to update nextcloud instance'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to update nextcloud instance');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** DELETE /instances/:id — Cloud entfernen (nur Verwalten). */
|
||||
export async function deleteInstance(id: string): Promise<void> {
|
||||
const res = await fetch(`${BASE}/${id}`, { method: 'DELETE', credentials: 'include' });
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to delete nextcloud instance'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to delete nextcloud instance');
|
||||
}
|
||||
|
||||
/** POST /instances/check — "Jetzt pruefen" fuer die ganze Liste, liefert die frische Liste. */
|
||||
export async function checkAll(): Promise<NextcloudList> {
|
||||
const res = await fetch(`${BASE}/check`, { method: 'POST', credentials: 'include' });
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to check nextcloud instances'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to check nextcloud instances');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** POST /instances/:id/check — eine Cloud sofort pruefen, liefert die aktualisierte Kachel. */
|
||||
export async function checkOne(id: string): Promise<NextcloudInstance> {
|
||||
const res = await fetch(`${BASE}/${id}/check`, { method: 'POST', credentials: 'include' });
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to check nextcloud instance'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to check nextcloud instance');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
@@ -176,21 +203,21 @@ export async function uploadLogo(id: string, file: File): Promise<NextcloudInsta
|
||||
credentials: 'include',
|
||||
body: form,
|
||||
});
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to upload logo'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to upload logo');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** DELETE /instances/:id/logo — hochgeladenes Logo entfernen (nur Verwalten). */
|
||||
export async function removeLogo(id: string): Promise<NextcloudInstance> {
|
||||
const res = await fetch(`${BASE}/${id}/logo`, { method: 'DELETE', credentials: 'include' });
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to remove logo'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to remove logo');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** POST /instances/:id/subscription — Glocke "Benachrichtigen" einschalten (jeder mit Modulzugriff). */
|
||||
export async function subscribe(id: string): Promise<void> {
|
||||
const res = await fetch(`${BASE}/${id}/subscription`, { method: 'POST', credentials: 'include' });
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to subscribe'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to subscribe');
|
||||
}
|
||||
|
||||
/** DELETE /instances/:id/subscription — Glocke ausschalten. */
|
||||
@@ -199,7 +226,7 @@ export async function unsubscribe(id: string): Promise<void> {
|
||||
method: 'DELETE',
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to unsubscribe'));
|
||||
if (!res.ok) throw await readError(res, 'Failed to unsubscribe');
|
||||
}
|
||||
|
||||
/** Ein abgewiesener Aufruf der Meldungsabfrage; `status` ist der HTTP-Status (401, 403 ...). */
|
||||
|
||||
Reference in New Issue
Block a user