Skip to content
This repository has been archived by the owner on Sep 17, 2024. It is now read-only.

Commit

Permalink
feat(users): users profile pictures
Browse files Browse the repository at this point in the history
  • Loading branch information
Blckbrry-Pi authored and NathanFlurry committed Jun 10, 2024
1 parent d55eee1 commit 2f7639a
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "avatarUploadId" UUID;
10 changes: 6 additions & 4 deletions modules/users/db/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
24 changes: 22 additions & 2 deletions modules/users/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
],
"authors": [
"rivet-gg",
"NathanFlurry"
"NathanFlurry",
"Blckbrry-Pi"
],
"status": "stable",
"dependencies": {
"rate_limit": {},
"tokens": {}
"tokens": {},
"uploads": {}
},
"scripts": {
"get_user": {
Expand All @@ -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": {
Expand All @@ -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"
}
}
}
10 changes: 8 additions & 2 deletions modules/users/scripts/create_user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export interface Request {
}

export interface Response {
user: User;
user: Omit<User, "profilePictureUrl">;
}

export async function run(
Expand All @@ -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,
};
}

Expand Down
6 changes: 5 additions & 1 deletion modules/users/scripts/get_user.ts
Original file line number Diff line number Diff line change
@@ -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[];
Expand All @@ -20,5 +21,8 @@ export async function run(
orderBy: { username: "desc" },
});

return { users };

const usersWithPfps = await withPfpUrls(ctx, users);

return { users: usersWithPfps };
}
15 changes: 3 additions & 12 deletions modules/users/utils/pfp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,14 @@ import { User } from "./types.ts";
const EXPIRY_SECS = 60 * 60 * 24; // 1 day

type UserWithUploadidInfo = Omit<User, "profilePictureUrl"> & { 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<T extends ModuleContext>(
ctx: T,
users: UserWithUploadidInfo[],
): Promise<User[]> {
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,
Expand Down
1 change: 1 addition & 0 deletions modules/users/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export interface User {
username: string;
createdAt: Date;
updatedAt: Date;
profilePictureUrl: string | null;
}
5 changes: 4 additions & 1 deletion tests/basic/backend.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"registry": "local"
},
"users": {
"registry": "local"
"registry": "local",
"config": {
"maxProfilePictureBytes": 1048576
}
},
"uploads": {
"registry": "local",
Expand Down

0 comments on commit 2f7639a

Please sign in to comment.