feat: store node logo/favicon in postgres instead of S3

- Add logoData and faviconData columns to nodes table
- Create /api/admin/node/upload endpoint for direct DB storage
- Create /api/node/logo and /api/node/favicon endpoints to serve images
- Update admin page to use new upload endpoint
- Remove dependency on admin's personal S3 storage for node assets
This commit is contained in:
Christomatt
2026-02-01 16:29:39 +01:00
parent 0cea2e9e1f
commit 90dfd62434
17 changed files with 913 additions and 90 deletions
+28 -16
View File
@@ -33,29 +33,41 @@ export async function PATCH(req: NextRequest) {
bannerUrl: data.bannerUrl,
logoUrl: data.logoUrl,
faviconUrl: data.faviconUrl,
logoData: data.logoData,
faviconData: data.faviconData,
accentColor: data.accentColor,
isNsfw: data.isNsfw ?? false,
turnstileSiteKey: data.turnstileSiteKey,
turnstileSecretKey: data.turnstileSecretKey,
}).returning();
} else {
const updateData: Record<string, unknown> = {
name: data.name,
description: data.description,
longDescription: data.longDescription,
rules: data.rules,
bannerUrl: data.bannerUrl,
logoUrl: data.logoUrl,
faviconUrl: data.faviconUrl,
accentColor: data.accentColor,
isNsfw: data.isNsfw ?? node.isNsfw,
turnstileSiteKey: data.turnstileSiteKey !== undefined ? data.turnstileSiteKey : node.turnstileSiteKey,
turnstileSecretKey: data.turnstileSecretKey !== undefined ? data.turnstileSecretKey : node.turnstileSecretKey,
// Fix domain drift: ensure the DB matches the current environment
domain: domain,
updatedAt: new Date(),
};
// Only update logoData/faviconData if explicitly provided
if (data.logoData !== undefined) {
updateData.logoData = data.logoData;
}
if (data.faviconData !== undefined) {
updateData.faviconData = data.faviconData;
}
[node] = await db.update(nodes)
.set({
name: data.name,
description: data.description,
longDescription: data.longDescription,
rules: data.rules,
bannerUrl: data.bannerUrl,
logoUrl: data.logoUrl,
faviconUrl: data.faviconUrl,
accentColor: data.accentColor,
isNsfw: data.isNsfw ?? node.isNsfw,
turnstileSiteKey: data.turnstileSiteKey !== undefined ? data.turnstileSiteKey : node.turnstileSiteKey,
turnstileSecretKey: data.turnstileSecretKey !== undefined ? data.turnstileSecretKey : node.turnstileSecretKey,
// Fix domain drift: ensure the DB matches the current environment
domain: domain,
updatedAt: new Date(),
})
.set(updateData)
.where(eq(nodes.id, node.id))
.returning();
}