From 60656cd6c944b90959874cdccbb2c076dc771af2 Mon Sep 17 00:00:00 2001 From: Skyler Calaman <54462713+Blckbrry-Pi@users.noreply.github.com> Date: Sun, 31 Mar 2024 20:42:23 -0400 Subject: [PATCH] feat(users): `users` profile pictures --- .../migration.sql | 2 ++ modules/users/db/schema.prisma | 10 ++++---- modules/users/module.json | 24 +++++++++++++++++-- modules/users/scripts/create_user.ts | 10 ++++++-- modules/users/scripts/get_user.ts | 6 ++++- modules/users/utils/pfp.ts | 15 +++--------- modules/users/utils/types.ts | 1 + tests/basic/backend.json | 5 +++- 8 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 modules/users/db/migrations/20240522003232_initial_setup/migration.sql diff --git a/modules/users/db/migrations/20240522003232_initial_setup/migration.sql b/modules/users/db/migrations/20240522003232_initial_setup/migration.sql new file mode 100644 index 00000000..ec8b0212 --- /dev/null +++ b/modules/users/db/migrations/20240522003232_initial_setup/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "avatarUploadId" UUID; diff --git a/modules/users/db/schema.prisma b/modules/users/db/schema.prisma index 16bdf151..c5bafd5c 100644 --- a/modules/users/db/schema.prisma +++ b/modules/users/db/schema.prisma @@ -4,8 +4,10 @@ datasource db { } model User { - id String @id @default(uuid()) @db.Uuid - username String @unique - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + id String @id @default(uuid()) @db.Uuid + username String @unique + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + avatarUploadId String? @db.Uuid } diff --git a/modules/users/module.json b/modules/users/module.json index c21c8260..fb4c3390 100644 --- a/modules/users/module.json +++ b/modules/users/module.json @@ -8,12 +8,14 @@ ], "authors": [ "rivet-gg", - "NathanFlurry" + "NathanFlurry", + "Blckbrry-Pi" ], "status": "stable", "dependencies": { "rate_limit": {}, - "tokens": {} + "tokens": {}, + "uploads": {} }, "scripts": { "get_user": { @@ -31,6 +33,16 @@ "create_user_token": { "name": "Create User Token", "description": "Create a token for a user to authenticate future requests." + }, + "set_profile_picture": { + "name": "Set Profile Picture", + "description": "Set the profile picture for a user.", + "public": true + }, + "prepare_profile_picture": { + "name": "Start Profile Picture Upload", + "description": "Allow the user to begin uploading a profile picture.", + "public": true } }, "errors": { @@ -39,6 +51,14 @@ }, "unknown_identity_type": { "name": "Unknown Identity Type" + }, + "invalid_mime_type": { + "name": "Invalid MIME Type", + "description": "The MIME type for the supposed PFP isn't an image" + }, + "file_too_large": { + "name": "File Too Large", + "description": "The file is larger than the configured maximum size for a profile picture" } } } \ No newline at end of file diff --git a/modules/users/scripts/create_user.ts b/modules/users/scripts/create_user.ts index 59ef9e12..a30f14ee 100644 --- a/modules/users/scripts/create_user.ts +++ b/modules/users/scripts/create_user.ts @@ -6,7 +6,7 @@ export interface Request { } export interface Response { - user: User; + user: Omit; } export async function run( @@ -20,10 +20,16 @@ export async function run( data: { username: req.username ?? generateUsername(), }, + select: { + id: true, + username: true, + createdAt: true, + updatedAt: true, + }, }); return { - user, + user: user, }; } diff --git a/modules/users/scripts/get_user.ts b/modules/users/scripts/get_user.ts index 968b3ebb..df6f758f 100644 --- a/modules/users/scripts/get_user.ts +++ b/modules/users/scripts/get_user.ts @@ -1,5 +1,6 @@ import { ScriptContext } from "../module.gen.ts"; import { User } from "../utils/types.ts"; +import { withPfpUrls } from "../utils/pfp.ts"; export interface Request { userIds: string[]; @@ -20,5 +21,8 @@ export async function run( orderBy: { username: "desc" }, }); - return { users }; + + const usersWithPfps = await withPfpUrls(ctx, users); + + return { users: usersWithPfps }; } diff --git a/modules/users/utils/pfp.ts b/modules/users/utils/pfp.ts index 99e62d74..57c18530 100644 --- a/modules/users/utils/pfp.ts +++ b/modules/users/utils/pfp.ts @@ -4,23 +4,14 @@ import { User } from "./types.ts"; const EXPIRY_SECS = 60 * 60 * 24; // 1 day type UserWithUploadidInfo = Omit & { avatarUploadId: string | null }; -type FileRef = { uploadId: string; path: string }; - -function getFileRefs(users: UserWithUploadidInfo[]) { - const pairs: FileRef[] = []; - for (const { avatarUploadId: uploadId } of users) { - if (uploadId) { - pairs.push({ uploadId: uploadId, path: "profile-picture" }); - } - } - return pairs; -} export async function withPfpUrls( ctx: T, users: UserWithUploadidInfo[], ): Promise { - const fileRefs = getFileRefs(users); + const fileRefs = users + .filter(user => user.avatarUploadId) + .map(user => ({ uploadId: user.avatarUploadId!, path: "profile-picture" })); const { files } = await ctx.modules.uploads.getPublicFileUrls({ files: fileRefs, diff --git a/modules/users/utils/types.ts b/modules/users/utils/types.ts index 78c900cb..583ed283 100644 --- a/modules/users/utils/types.ts +++ b/modules/users/utils/types.ts @@ -3,4 +3,5 @@ export interface User { username: string; createdAt: Date; updatedAt: Date; + profilePictureUrl: string | null; } diff --git a/tests/basic/backend.json b/tests/basic/backend.json index 18adff1f..fbb2f443 100644 --- a/tests/basic/backend.json +++ b/tests/basic/backend.json @@ -20,7 +20,10 @@ "registry": "local" }, "users": { - "registry": "local" + "registry": "local", + "config": { + "maxProfilePictureBytes": 1048576 + } }, "uploads": { "registry": "local",