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

Commit 4c28f2b

Browse files
Blckbrry-PiNathanFlurry
authored andcommitted
feat(users): users profile pictures
1 parent f19ed2c commit 4c28f2b

File tree

8 files changed

+51
-22
lines changed

8 files changed

+51
-22
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "User" ADD COLUMN "avatarUploadId" UUID;

modules/users/db/schema.prisma

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ datasource db {
44
}
55

66
model User {
7-
id String @id @default(uuid()) @db.Uuid
8-
username String @unique
9-
createdAt DateTime @default(now())
10-
updatedAt DateTime @updatedAt
7+
id String @id @default(uuid()) @db.Uuid
8+
username String @unique
9+
createdAt DateTime @default(now())
10+
updatedAt DateTime @updatedAt
11+
12+
avatarUploadId String? @db.Uuid
1113
}

modules/users/module.json

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
],
99
"authors": [
1010
"rivet-gg",
11-
"NathanFlurry"
11+
"NathanFlurry",
12+
"Blckbrry-Pi"
1213
],
1314
"status": "stable",
1415
"dependencies": {
1516
"rate_limit": {},
16-
"tokens": {}
17+
"tokens": {},
18+
"uploads": {}
1719
},
1820
"scripts": {
1921
"get_user": {
@@ -31,6 +33,16 @@
3133
"create_user_token": {
3234
"name": "Create User Token",
3335
"description": "Create a token for a user to authenticate future requests."
36+
},
37+
"set_profile_picture": {
38+
"name": "Set Profile Picture",
39+
"description": "Set the profile picture for a user.",
40+
"public": true
41+
},
42+
"prepare_profile_picture": {
43+
"name": "Start Profile Picture Upload",
44+
"description": "Allow the user to begin uploading a profile picture.",
45+
"public": true
3446
}
3547
},
3648
"errors": {
@@ -39,6 +51,14 @@
3951
},
4052
"unknown_identity_type": {
4153
"name": "Unknown Identity Type"
54+
},
55+
"invalid_mime_type": {
56+
"name": "Invalid MIME Type",
57+
"description": "The MIME type for the supposed PFP isn't an image"
58+
},
59+
"file_too_large": {
60+
"name": "File Too Large",
61+
"description": "The file is larger than the configured maximum size for a profile picture"
4262
}
4363
}
4464
}

modules/users/scripts/create_user.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export interface Request {
66
}
77

88
export interface Response {
9-
user: User;
9+
user: Omit<User, "profilePictureUrl">;
1010
}
1111

1212
export async function run(
@@ -20,10 +20,16 @@ export async function run(
2020
data: {
2121
username: req.username ?? generateUsername(),
2222
},
23+
select: {
24+
id: true,
25+
username: true,
26+
createdAt: true,
27+
updatedAt: true,
28+
},
2329
});
2430

2531
return {
26-
user,
32+
user: user,
2733
};
2834
}
2935

modules/users/scripts/get_user.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ScriptContext } from "../module.gen.ts";
22
import { User } from "../utils/types.ts";
3+
import { withPfpUrls } from "../utils/pfp.ts";
34

45
export interface Request {
56
userIds: string[];
@@ -20,5 +21,8 @@ export async function run(
2021
orderBy: { username: "desc" },
2122
});
2223

23-
return { users };
24+
25+
const usersWithPfps = await withPfpUrls(ctx, users);
26+
27+
return { users: usersWithPfps };
2428
}

modules/users/utils/pfp.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,14 @@ import { User } from "./types.ts";
44
const EXPIRY_SECS = 60 * 60 * 24; // 1 day
55

66
type UserWithUploadidInfo = Omit<User, "profilePictureUrl"> & { avatarUploadId: string | null };
7-
type FileRef = { uploadId: string; path: string };
8-
9-
function getFileRefs(users: UserWithUploadidInfo[]) {
10-
const pairs: FileRef[] = [];
11-
for (const { avatarUploadId: uploadId } of users) {
12-
if (uploadId) {
13-
pairs.push({ uploadId: uploadId, path: "profile-picture" });
14-
}
15-
}
16-
return pairs;
17-
}
187

198
export async function withPfpUrls<T extends ModuleContext>(
209
ctx: T,
2110
users: UserWithUploadidInfo[],
2211
): Promise<User[]> {
23-
const fileRefs = getFileRefs(users);
12+
const fileRefs = users
13+
.filter(user => user.avatarUploadId)
14+
.map(user => ({ uploadId: user.avatarUploadId!, path: "profile-picture" }));
2415

2516
const { files } = await ctx.modules.uploads.getPublicFileUrls({
2617
files: fileRefs,

modules/users/utils/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export interface User {
33
username: string;
44
createdAt: Date;
55
updatedAt: Date;
6+
profilePictureUrl: string | null;
67
}

tests/basic/backend.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
"registry": "local"
2121
},
2222
"users": {
23-
"registry": "local"
23+
"registry": "local",
24+
"config": {
25+
"maxProfilePictureBytes": 1048576
26+
}
2427
},
2528
"uploads": {
2629
"registry": "local",

0 commit comments

Comments
 (0)