Skip to content

Commit

Permalink
Refactor API functions to use authorDid instead of user.did for vote,…
Browse files Browse the repository at this point in the history
… post, and comment actions; enhance validation to ensure users can only act on their own content
  • Loading branch information
WillCorrigan committed Dec 22, 2024
1 parent 20d5ccb commit 29690ba
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 17 deletions.
3 changes: 2 additions & 1 deletion packages/frontpage/app/(app)/_components/post-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ export async function PostCard({
<VoteButton
voteAction={async () => {
"use server";
await ensureUser();
const user = await ensureUser();
await createVote({
authorDid: user.did,
subject: {
rkey,
cid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export async function createCommentAction(
parent: comment,
post,
content,
repo: user.did,
authorDid: user.did,
});

revalidatePath(`/post`);
Expand Down Expand Up @@ -83,8 +83,9 @@ export async function commentVoteAction(input: {
rkey: string;
authorDid: DID;
}) {
await ensureUser();
const user = await ensureUser();
await createVote({
authorDid: user.did,
subject: {
rkey: input.rkey,
cid: input.cid,
Expand Down
2 changes: 1 addition & 1 deletion packages/frontpage/app/(app)/post/new/_action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export async function newPostAction(_prevState: unknown, formData: FormData) {

try {
const [{ rkey }, handle] = await Promise.all([
createPost({ title, url }),
createPost({ authorDid: user.did, title, url }),
getVerifiedHandle(user.did),
]);

Expand Down
17 changes: 12 additions & 5 deletions packages/frontpage/lib/api/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import { invariant } from "../utils";
import { TID } from "@atproto/common-web";

export type ApiCreateCommentInput = Omit<atproto.CommentInput, "rkey"> & {
repo: DID;
authorDid: DID;
};

export async function createComment({
parent,
post,
content,
repo,
authorDid,
}: ApiCreateCommentInput) {
const user = await ensureUser();

Expand Down Expand Up @@ -49,7 +49,7 @@ export async function createComment({

const didToNotify = parent ? parent.authorDid : post.authorDid;

if (didToNotify !== repo) {
if (didToNotify !== authorDid) {
await createNotification({
commentId: dbCreatedComment.id,
did: didToNotify,
Expand All @@ -62,12 +62,19 @@ export async function createComment({
}
}

export async function deleteComment({ rkey }: db.DeleteCommentInput) {
export async function deleteComment({
authorDid,
rkey,
}: db.DeleteCommentInput) {
const user = await ensureUser();

if (user.did !== authorDid) {
throw new DataLayerError("You can only delete your own comments");
}

try {
console.log("deleteComment", rkey);
await atproto.deleteComment(user.did, rkey);
await atproto.deleteComment(authorDid, rkey);
await db.deleteComment({ authorDid: user.did, rkey });
} catch (e) {
throw new DataLayerError(`Failed to delete comment: ${e}`);
Expand Down
20 changes: 17 additions & 3 deletions packages/frontpage/lib/api/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,25 @@ import { DataLayerError } from "../data/error";
import { sendDiscordMessage } from "../discord";
import { invariant } from "../utils";
import { TID } from "@atproto/common-web";
import { DID } from "../data/atproto/did";

export type ApiCreatePostInput = {
authorDid: DID;
title: string;
url: string;
};

export async function createPost({ title, url }: ApiCreatePostInput) {
export async function createPost({
authorDid,
title,
url,
}: ApiCreatePostInput) {
const user = await ensureUser();

if (user.did !== authorDid) {
throw new DataLayerError("You can only create posts for yourself");
}

const rkey = TID.next().toString();
try {
const dbCreatedPost = await db.createPost({
Expand Down Expand Up @@ -67,11 +77,15 @@ export async function createPost({ title, url }: ApiCreatePostInput) {
}
}

export async function deletePost({ rkey }: db.DeletePostInput) {
export async function deletePost({ authorDid, rkey }: db.DeletePostInput) {
const user = await ensureUser();

if (authorDid !== user.did) {
throw new DataLayerError("You can only delete your own posts");
}

try {
await atproto.deletePost(user.did, rkey);
await atproto.deletePost(authorDid, rkey);
await db.deletePost({ authorDid: user.did, rkey });
} catch (e) {
throw new DataLayerError(`Failed to delete post: ${e}`);
Expand Down
18 changes: 13 additions & 5 deletions packages/frontpage/lib/api/vote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { invariant } from "../utils";
import { TID } from "@atproto/common-web";

export type ApiCreateVoteInput = {
authorDid: DID;
subject: {
rkey: string;
cid: string;
Expand All @@ -18,14 +19,18 @@ export type ApiCreateVoteInput = {
};
};

export async function createVote({ subject }: ApiCreateVoteInput) {
export async function createVote({ authorDid, subject }: ApiCreateVoteInput) {
const user = await ensureUser();

if (authorDid !== user.did) {
throw new DataLayerError("You can only vote for yourself");
}

const rkey = TID.next().toString();
try {
if (subject.collection == PostCollection) {
const dbCreatedVote = await db.createPostVote({
repo: user.did,
repo: authorDid,
rkey,
subject: {
rkey: subject.rkey,
Expand All @@ -36,7 +41,7 @@ export async function createVote({ subject }: ApiCreateVoteInput) {
invariant(dbCreatedVote, "Failed to insert post vote in database");
} else if (subject.collection == CommentCollection) {
const dbCreatedVote = await db.createCommentVote({
repo: user.did,
repo: authorDid,
rkey,
subject: {
rkey: subject.rkey,
Expand Down Expand Up @@ -65,11 +70,14 @@ export async function createVote({ subject }: ApiCreateVoteInput) {
}
}

export async function deleteVote({ rkey }: db.DeleteVoteInput) {
export async function deleteVote({ authorDid, rkey }: db.DeleteVoteInput) {
const user = await ensureUser();
if (authorDid !== user.did) {
throw new DataLayerError("You can only delete your own votes");
}

try {
await atproto.deleteVote(user.did, rkey);
await atproto.deleteVote(authorDid, rkey);
await db.deleteVote({ authorDid: user.did, rkey });
} catch (e) {
throw new DataLayerError(`Failed to delete vote: ${e}`);
Expand Down

0 comments on commit 29690ba

Please sign in to comment.