Skip to content

Commit

Permalink
block/unblock user
Browse files Browse the repository at this point in the history
  • Loading branch information
dromzeh committed Mar 17, 2024
1 parent 63f191a commit 235cc18
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/v2/db/schema/user/user-blocked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ import {
index,
} from "drizzle-orm/sqlite-core"
import { authUser } from "./user"
import { generateID } from "@/v2/lib/oslo"
import { createInsertSchema, createSelectSchema } from "drizzle-zod"

export const userBlocked = sqliteTable(
tableNames.userBlocked,
{
id: text("id").primaryKey().notNull(),
id: text("id")
.primaryKey()
.notNull()
.$defaultFn(() => {
return generateID()
}),
blockedById: text("blocked_by_id")
.references(() => authUser.id, {
onUpdate: "cascade",
Expand Down
124 changes: 124 additions & 0 deletions src/v2/routes/user/block-user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { AppHandler } from "../handler"
import { getConnection } from "@/v2/db/turso"
import { AuthSessionManager } from "@/v2/lib/managers/auth/user-session-manager"
import { and, eq, or } from "drizzle-orm"
import { userBlocked, userFollowing } from "@/v2/db/schema"
import { createRoute } from "@hono/zod-openapi"
import { GenericResponses } from "@/v2/lib/response-schemas"
import { z } from "@hono/zod-openapi"

const blockUserByIdSchema = z.object({
id: z.string().openapi({
param: {
description: "The id of the user to block.",
in: "path",
name: "id",
required: true,
},
}),
})

const blockUserByIdResponseSchema = z.object({
success: z.literal(true),
})

export const blockUserByIdRoute = createRoute({
path: "/{id}/block",
method: "post",
summary: "Block a user",
description: "Block a user from their ID.",
tags: ["User"],
request: {
params: blockUserByIdSchema,
},
responses: {
200: {
description: "True if the user was blocked.",
content: {
"application/json": {
schema: blockUserByIdResponseSchema,
},
},
},
...GenericResponses,
},
})

export const BlockUserRoute = (handler: AppHandler) => {
handler.openapi(blockUserByIdRoute, async (ctx) => {
const userId = ctx.req.valid("param").id

const { drizzle } = await getConnection(ctx.env)

const authSessionManager = new AuthSessionManager(ctx)
const { user } = await authSessionManager.validateSession()

if (!user) {
return ctx.json(
{
success: false,
message: "Unauthorized",
},
401
)
}

if (userId == user.id) {
return ctx.json(
{
success: false,
message: "You cannot block yourself",
},
400
)
}

const [blockedStatus] = await drizzle
.select({
id: userBlocked.blockedId,
blockedById: userBlocked.blockedById,
})
.from(userBlocked)
.where(eq(userBlocked.blockedId, userId))

if (blockedStatus) {
return ctx.json(
{
success: false,
message: "User already blocked",
},
400
)
}

await drizzle
.delete(userFollowing)
.where(
or(
and(
eq(userFollowing.followerId, user.id),
eq(userFollowing.followingId, userId)
),
and(
eq(userFollowing.followerId, userId),
eq(userFollowing.followingId, user.id)
)
)
)

await drizzle
.insert(userBlocked)
.values({
blockedId: userId,
blockedById: user.id,
})
.execute()

return ctx.json(
{
success: true,
},
200
)
})
}
6 changes: 6 additions & 0 deletions src/v2/routes/user/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { ViewUsersFollowingRoute } from "./user-following"
import { FollowUserRoute } from "./follow-user"
import { UnfollowUserRoute } from "./unfollow-user"

import { BlockUserRoute } from "./block-user"
import { UnblockUserRoute } from "./unblock-user"

const handler = new OpenAPIHono<{ Bindings: Bindings; Variables: Variables }>()

GetUserByIdRoute(handler)
Expand All @@ -20,4 +23,7 @@ ViewUsersFollowingRoute(handler)
FollowUserRoute(handler)
UnfollowUserRoute(handler)

BlockUserRoute(handler)
UnblockUserRoute(handler)

export default handler
110 changes: 110 additions & 0 deletions src/v2/routes/user/unblock-user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { AppHandler } from "../handler"
import { getConnection } from "@/v2/db/turso"
import { AuthSessionManager } from "@/v2/lib/managers/auth/user-session-manager"
import { and, eq } from "drizzle-orm"
import { userBlocked } from "@/v2/db/schema"
import { createRoute } from "@hono/zod-openapi"
import { GenericResponses } from "@/v2/lib/response-schemas"
import { z } from "@hono/zod-openapi"

const unblockUserByIdSchema = z.object({
id: z.string().openapi({
param: {
description: "The id of the user to unblock.",
in: "path",
name: "id",
required: true,
},
}),
})

const unblockUserByIdResponseSchema = z.object({
success: z.literal(true),
})

export const unblockUserByIdRoute = createRoute({
path: "/{id}/block",
method: "post",
summary: "Unblock a user",
description: "Unblock a user from their ID.",
tags: ["User"],
request: {
params: unblockUserByIdSchema,
},
responses: {
200: {
description: "True if the user was unblocked.",
content: {
"application/json": {
schema: unblockUserByIdResponseSchema,
},
},
},
...GenericResponses,
},
})

export const UnblockUserRoute = (handler: AppHandler) => {
handler.openapi(unblockUserByIdRoute, async (ctx) => {
const userId = ctx.req.valid("param").id

const { drizzle } = await getConnection(ctx.env)

const authSessionManager = new AuthSessionManager(ctx)
const { user } = await authSessionManager.validateSession()

if (!user) {
return ctx.json(
{
success: false,
message: "Unauthorized",
},
401
)
}

if (userId == user.id) {
return ctx.json(
{
success: false,
message: "You cannot unblock yourself",
},
400
)
}

const [blockedStatus] = await drizzle
.select({
id: userBlocked.blockedId,
blockedById: userBlocked.blockedById,
})
.from(userBlocked)
.where(
and(
eq(userBlocked.blockedId, userId),
eq(userBlocked.blockedById, user.id)
)
)

if (!blockedStatus) {
return ctx.json(
{
success: false,
message: "You have not blocked this user",
},
400
)
}

await drizzle
.delete(userBlocked)
.where(eq(userBlocked.id, blockedStatus.id))

return ctx.json(
{
success: true,
},
200
)
})
}

0 comments on commit 235cc18

Please sign in to comment.