feat(api): Benutzernamen (Profil-Tabelle, /api/profil, Pflicht beim Hochladen und Veröffentlichen)
- Schema: Tabelle `profiles` (Zeilen-ID = Konto-ID, `username` und `usernameKey`
je 20 Zeichen, Unique-Index `username_key` auf `usernameKey`, rowSecurity an,
keine Tabellenrechte) im Setup-Skript.
- Neues Modul `deploy/api/profiles.js`: `POST /api/profil` legt das Profil an
oder ändert es (Zeilenrecht genau read("any"), Sperre je Konto). Muster,
Sperrliste und Schlüssel (`usernameKey`) stehen in `common.js`; vergeben ->
409 `usernameTaken`, auch wenn erst der Unique-Index bei einem Rennen
entscheidet. Dazu die MSG-Texte `usernameInvalid`, `usernameReserved`,
`usernameTaken`, `usernameRequired`.
- `POST /api/logos/hochladen` und `POST /api/veroeffentlichen` antworten 403
`usernameRequired`, wenn das Konto kein Profil hat (`hasProfile`, nach der
Anmeldung und vor allen anderen Prüfungen).
- Fake-Appwrite: Tabelle `profiles` mit Unique-Index (409), `addProfile`,
`holdNext`. API-Dienst besteht jetzt aus sechs Dateien (READMEs).
- Client: die vier API-Texte in `API_MESSAGES` und `en.ts` (Gleichlauf mit MSG).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a65c075004
commit
19c8151c7e
15 files changed
+980
-53
No files matched your search
+5
-1
@@ -6,7 +6,8 @@
|
||||
* app.js hängt die Routen an und gibt Anmeldung, Sperre je Schlüssel, das gemeinsame Rate-Limit und das Log mit.
|
||||
*
|
||||
* POST /api/logos/hochladen Nutzer-JWT {name, displayName?, mono?, fileId}
|
||||
* 401 · 400 Validierung, Datei fehlt, kein PNG, größer als 1 MiB, Maße nicht 8 × 8 bis 720 × 250 · 403 Datei nicht
|
||||
* 401 · 403 `usernameRequired` (das Konto hat noch keinen Benutzernamen; vor allen anderen Prüfungen) · 400 Validierung,
|
||||
* Datei fehlt, kein PNG, größer als 1 MiB, Maße nicht 8 × 8 bis 720 × 250 · 403 Datei nicht
|
||||
* meine / falscher Bucket / Datei gesperrt (kein read("any")) · 409 Datei schon für ein Logo verwendet · 429 schon
|
||||
* 30 Logos · 201 {id} (id = Zeilen-ID des Logos, ein Hash aus Konto und Datei, nicht die Datei-ID)
|
||||
* Nach dem Festlegen der Datei auf read("any") wird ihr Anfang noch einmal geprüft (der Hochlader kann sie dann nicht
|
||||
@@ -57,6 +58,7 @@ const {
|
||||
checkFileExists,
|
||||
checkFileOwnership,
|
||||
} = require('./common.js');
|
||||
const { hasProfile } = require('./profiles.js');
|
||||
|
||||
const TABLE_LOGOS = 'logos';
|
||||
const TABLE_LIKES = 'logo_likes';
|
||||
@@ -230,6 +232,8 @@ function createLogoRoutes({ appwrite, salt, say, withLock, rateLimit, requireUse
|
||||
|
||||
async function uploadLogo({ req, raw }) {
|
||||
const user = await requireUser(req);
|
||||
// Ohne Benutzernamen geht nichts weiter: vor allen anderen Prüfungen, es wird nichts angelegt oder angefasst.
|
||||
if (!(await hasProfile(appwrite, user.id))) throw new HttpError(403, MSG.usernameRequired);
|
||||
const validation = validateLogoUpload(parseJsonObject(raw));
|
||||
if (!validation.ok) throw new HttpError(400, validation.message);
|
||||
const data = validation.data;
|
||||
|
||||
Reference in new issue
Block a user