fix(favorites): Symbol-Adresse auch speichern, wenn nur der Browser sie laden kann

- API: ausdrueckliche iconUrl wird nur auf Form (http/https, <= 2048) geprueft
  und auch gespeichert, wenn der Server sie nicht abrufen kann; keine 422 mehr
- Erkennung: Seite mit Fehlerstatus, aber HTML mit <link rel=icon>, liefert
  diesen Verweis (docuvita); og:image einer Fehlerseite zaehlt nicht
- Kachel: Proxy -> iconUrl direkt im Browser (no-referrer, nur http/https) ->
  Origin-Favicon -> Buchstabe
- Meldung iconUrlUnreachable (de/en) entfernt, Hinweis zum Vorrang angepasst

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 15:34:58 +02:00
parent 7188c5b958
commit b15c74632b
12 changed files with 307 additions and 112 deletions
+7 -11
View File
@@ -7,10 +7,9 @@
* 260923-lrr — eigenes Symbol hochladen, Zwischenspeicher nach Aenderung
* erneuern: `FavoriteLink` traegt jetzt `uploadedIconMime`/`iconVersion`
* (optional, weil Testdaten und aeltere Antworten sie nicht tragen).
* `createFavorite`/`updateFavorite` uebersetzen ein 422 (Abrufprobe der API
* fuer eine nicht abrufbare Logo-Adresse) in `FavoriteRequestError`, damit
* das Widget eine sprachrichtige Meldung zeigen kann, statt der bisherigen
* generischen `Error`. `uploadFavoriteIcon`/`removeFavoriteIcon` sind neu,
* `FavoriteRequestError` traegt den Grund einer abgewiesenen Symbol-Datei
* (Widget bildet ihn auf eine sprachrichtige Meldung ab). 260929-lh3: die
* 422-Abrufprobe fuer Logo-Adressen ist entfallen. `uploadFavoriteIcon`/`removeFavoriteIcon` sind neu,
* Muster `uploadDashboardImage`/`deleteDashboardImage` (dashboard-images-api.ts).
*/
@@ -34,7 +33,6 @@ export interface FavoriteLink {
/** Grund einer abgewiesenen Favoriten-Anfrage (260923-lrr). */
export type FavoriteErrorReason =
| 'iconUrlUnreachable'
| 'iconTooLarge'
| 'iconInvalidType'
| 'iconUploadFailed';
@@ -72,8 +70,9 @@ export async function fetchFavorites(widgetId: string): Promise<FavoriteLink[]>
/**
* Create a new favorite link.
* Server-side icon discovery runs automatically if iconUrl is not provided.
* 260923-lrr: eine explizite `iconUrl`, die sich serverseitig nicht laden
* laesst, ergibt 422 -> `FavoriteRequestError('iconUrlUnreachable')`.
* 260929-lh3: eine ausdrueckliche `iconUrl` wird auch gespeichert, wenn der
* Server sie nicht abrufen kann (die Kachel laedt sie dann im Browser); die
* frueheren 422-Antworten gibt es nicht mehr.
*/
export async function createFavorite(payload: {
widgetId: string;
@@ -87,7 +86,6 @@ export async function createFavorite(payload: {
credentials: 'include',
body: JSON.stringify(payload),
});
if (res.status === 422) throw new FavoriteRequestError('iconUrlUnreachable');
if (!res.ok) throw new Error('Failed to create favorite');
return res.json();
@@ -96,8 +94,7 @@ export async function createFavorite(payload: {
/**
* Update an existing favorite link.
* Pass iconUrl: null to clear a stored icon.
* 260923-lrr: eine neue, nicht abrufbare `iconUrl` ergibt ebenso 422 ->
* `FavoriteRequestError('iconUrlUnreachable')`.
* 260929-lh3: wie `createFavorite` — keine 422-Abweisung wegen Abrufbarkeit mehr.
*/
export async function updateFavorite(
id: string,
@@ -109,7 +106,6 @@ export async function updateFavorite(
credentials: 'include',
body: JSON.stringify(payload),
});
if (res.status === 422) throw new FavoriteRequestError('iconUrlUnreachable');
if (!res.ok) throw new Error('Failed to update favorite');
return res.json();