refactor(api): ♻️ Remove useless authorization checks

This commit is contained in:
Jesse Wierzbinski 2024-12-30 19:38:41 +01:00
parent dc12b269f5
commit 09f30db83a
No known key found for this signature in database
59 changed files with 103 additions and 839 deletions

View file

@ -54,14 +54,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -81,10 +73,6 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const otherUser = await User.fromId(id);
if (!otherUser) {

View file

@ -65,14 +65,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -100,10 +92,6 @@ export default apiRoute((app) =>
const { user } = context.get("auth");
const { reblogs, notify, languages } = context.req.valid("json");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const otherUser = await User.fromId(id);
if (!otherUser) {

View file

@ -73,14 +73,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {

View file

@ -67,14 +67,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -92,10 +84,6 @@ export default apiRoute((app) =>
const { user } = context.get("auth");
const { comment } = context.req.valid("json");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const otherUser = await User.fromId(id);
if (!otherUser) {

View file

@ -57,14 +57,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -81,10 +73,6 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const otherUser = await User.fromId(id);
if (!otherUser) {

View file

@ -51,14 +51,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -81,11 +73,6 @@ const route = createRoute({
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const otherUser = await User.fromId(id);

View file

@ -57,14 +57,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -79,11 +71,7 @@ const route = createRoute({
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { id } = context.req.valid("param");
const { user: self } = context.get("auth");
if (!self) {
throw new ApiError(401, "Unauthorized");
}
const { user } = context.get("auth");
const otherUser = await User.fromId(id);
@ -93,7 +81,7 @@ export default apiRoute((app) =>
const oppositeRelationship = await Relationship.fromOwnerAndSubject(
otherUser,
self,
user,
);
if (oppositeRelationship.data.following) {
@ -103,7 +91,7 @@ export default apiRoute((app) =>
}
const foundRelationship = await Relationship.fromOwnerAndSubject(
self,
user,
otherUser,
);

View file

@ -48,14 +48,7 @@ const routePost = createRoute({
204: {
description: "Role assigned",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User or role not found",
content: {
@ -92,14 +85,7 @@ const routeDelete = createRoute({
204: {
description: "Role removed",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User or role not found",
content: {
@ -124,10 +110,6 @@ export default apiRoute((app) => {
const { user } = context.get("auth");
const { id, role_id } = context.req.valid("param");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const targetUser = await User.fromId(id);
const role = await Role.fromId(role_id);
@ -163,10 +145,6 @@ export default apiRoute((app) => {
const { user } = context.get("auth");
const { id, role_id } = context.req.valid("param");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const targetUser = await User.fromId(id);
const role = await Role.fromId(role_id);

View file

@ -57,14 +57,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -81,10 +73,6 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const otherUser = await User.fromId(id);
if (!otherUser) {

View file

@ -57,14 +57,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -87,11 +80,7 @@ const route = createRoute({
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { id } = context.req.valid("param");
const { user: self } = context.get("auth");
if (!self) {
throw new ApiError(401, "Unauthorized");
}
const { user } = context.get("auth");
const otherUser = await User.fromId(id);
@ -100,11 +89,11 @@ export default apiRoute((app) =>
}
const foundRelationship = await Relationship.fromOwnerAndSubject(
self,
user,
otherUser,
);
await self.unfollow(otherUser, foundRelationship);
await user.unfollow(otherUser, foundRelationship);
return context.json(foundRelationship.toApi(), 200);
}),

View file

@ -57,14 +57,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -79,21 +72,17 @@ const route = createRoute({
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { id } = context.req.valid("param");
const { user: self } = context.get("auth");
const { user } = context.get("auth");
if (!self) {
throw new ApiError(401, "Unauthorized");
}
const otherUser = await User.fromId(id);
const user = await User.fromId(id);
if (!user) {
if (!otherUser) {
throw new ApiError(404, "User not found");
}
const foundRelationship = await Relationship.fromOwnerAndSubject(
self,
user,
otherUser,
);
if (foundRelationship.data.muting) {

View file

@ -57,14 +57,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "User not found",
content: {
@ -79,11 +72,7 @@ const route = createRoute({
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { id } = context.req.valid("param");
const { user: self } = context.get("auth");
if (!self) {
throw new ApiError(401, "Unauthorized");
}
const { user } = context.get("auth");
const otherUser = await User.fromId(id);
@ -92,7 +81,7 @@ export default apiRoute((app) =>
}
const foundRelationship = await Relationship.fromOwnerAndSubject(
self,
user,
otherUser,
);

View file

@ -4,8 +4,6 @@ import { User, db } from "@versia/kit/db";
import { RolePermissions, type Users } from "@versia/kit/tables";
import { type InferSelectModel, sql } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/accounts/familiar_followers",
@ -64,26 +62,14 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user: self } = context.get("auth");
const { user } = context.get("auth");
const { id: ids } = context.req.valid("query");
if (!self) {
throw new ApiError(401, "Unauthorized");
}
// Find followers of the accounts in "ids", that you also follow
const finalUsers = await Promise.all(
ids.map(async (id) => ({
@ -94,7 +80,7 @@ export default apiRoute((app) =>
SELECT "Users"."id" FROM "Users"
INNER JOIN "Relationships" AS "SelfFollowing"
ON "SelfFollowing"."subjectId" = "Users"."id"
WHERE "SelfFollowing"."ownerId" = ${self.id}
WHERE "SelfFollowing"."ownerId" = ${user.id}
AND "SelfFollowing"."following" = true
AND EXISTS (
SELECT 1 FROM "Relationships" AS "IdsFollowers"

View file

@ -3,8 +3,6 @@ import { createRoute } from "@hono/zod-openapi";
import { Relationship } from "@versia/kit/db";
import { RolePermissions } from "@versia/kit/tables";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/accounts/relationships",
@ -52,30 +50,18 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user: self } = context.get("auth");
const { user } = context.get("auth");
const { id } = context.req.valid("query");
const ids = Array.isArray(id) ? id : [id];
if (!self) {
throw new ApiError(401, "Unauthorized");
}
const relationships = await Relationship.fromOwnerAndSubjects(
self,
user,
ids,
);

View file

@ -12,7 +12,6 @@ import { eq, ilike, not, or, sql } from "drizzle-orm";
import stringComparison from "string-comparison";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/accounts/search",
@ -69,14 +68,6 @@ export const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -84,10 +75,10 @@ export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { q, limit, offset, resolve, following } =
context.req.valid("query");
const { user: self } = context.get("auth");
const { user } = context.get("auth");
if (!self && following) {
throw new ApiError(401, "Unauthorized");
if (!user && following) {
throw new ApiError(401, "Must be authenticated to use 'following'");
}
const { username, domain } = parseUserAddress(q);
@ -95,7 +86,7 @@ export default apiRoute((app) =>
const accounts: User[] = [];
if (resolve && domain) {
const manager = await (self ?? User).getFederationRequester();
const manager = await (user ?? User).getFederationRequester();
const uri = await User.webFinger(manager, username, domain);
@ -112,10 +103,10 @@ export default apiRoute((app) =>
or(
ilike(Users.displayName, `%${q}%`),
ilike(Users.username, `%${q}%`),
following && self
? sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."subjectId" = ${Users.id} AND "Relationships"."ownerId" = ${self.id} AND "Relationships"."following" = true)`
following && user
? sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."subjectId" = ${Users.id} AND "Relationships"."ownerId" = ${user.id} AND "Relationships"."following" = true)`
: undefined,
self ? not(eq(Users.id, self.id)) : undefined,
user ? not(eq(Users.id, user.id)) : undefined,
),
undefined,
limit,

View file

@ -177,14 +177,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
422: {
description: "Validation error",
content: {
@ -220,10 +213,6 @@ export default apiRoute((app) =>
fields_attributes,
} = context.req.valid("json");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const self = user.data;
const sanitizedDisplayName = await sanitizedHtmlStrip(

View file

@ -1,8 +1,6 @@
import { apiRoute, applyConfig, auth } from "@/api";
import { createRoute } from "@hono/zod-openapi";
import { User } from "@versia/kit/db";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/accounts/verify_credentials",
@ -36,14 +34,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -52,10 +42,6 @@ export default apiRoute((app) =>
// TODO: Add checks for disabled/unverified accounts
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
return context.json(user.toApi(true), 200);
}),
);

View file

@ -52,21 +52,18 @@ const route = createRoute({
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user, token } = context.get("auth");
const { token } = context.get("auth");
if (!token) {
throw new ApiError(401, "Unauthorized");
}
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const application = await Application.getFromToken(
token.data.accessToken,
);
if (!application) {
throw new ApiError(401, "Unauthorized");
throw new ApiError(401, "Application not found");
}
return context.json(

View file

@ -4,8 +4,6 @@ import { Timeline, User } from "@versia/kit/db";
import { RolePermissions, Users } from "@versia/kit/tables";
import { and, gt, gte, lt, sql } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/blocks",
@ -55,14 +53,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -72,10 +62,6 @@ export default apiRoute((app) =>
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { objects: blocks, link } = await Timeline.getUserTimeline(
and(
max_id ? lt(Users.id, max_id) : undefined,

View file

@ -89,14 +89,7 @@ const routeGet = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Emoji not found",
content: {
@ -147,14 +140,7 @@ const routePatch = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
403: {
description: "Insufficient credentials",
content: {
@ -202,14 +188,7 @@ const routeDelete = createRoute({
204: {
description: "Emoji deleted",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Emoji not found",
content: {
@ -226,10 +205,6 @@ export default apiRoute((app) => {
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const emoji = await Emoji.fromId(id);
if (!emoji) {
@ -251,10 +226,6 @@ export default apiRoute((app) => {
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const emoji = await Emoji.fromId(id);
if (!emoji) {
@ -340,10 +311,6 @@ export default apiRoute((app) => {
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const emoji = await Emoji.fromId(id);
if (!emoji) {

View file

@ -101,14 +101,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
422: {
description: "Invalid data",
content: {
@ -126,10 +119,6 @@ export default apiRoute((app) =>
context.req.valid("json");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
if (!user.hasPermission(RolePermissions.ManageEmojis) && global) {
throw new ApiError(
401,

View file

@ -4,8 +4,6 @@ import { Note, Timeline } from "@versia/kit/db";
import { Notes, RolePermissions } from "@versia/kit/tables";
import { and, gt, gte, lt, sql } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/favourites",
@ -52,14 +50,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -69,10 +59,6 @@ export default apiRoute((app) =>
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { objects: favourites, link } = await Timeline.getNoteTimeline(
and(
max_id ? lt(Notes.id, max_id) : undefined,

View file

@ -48,14 +48,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Account not found",
content: {
@ -71,10 +64,6 @@ export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { account_id } = context.req.valid("param");
const account = await User.fromId(account_id);

View file

@ -48,14 +48,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Account not found",
content: {
@ -71,10 +64,6 @@ export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { account_id } = context.req.valid("param");
const account = await User.fromId(account_id);

View file

@ -4,8 +4,6 @@ import { Timeline, User } from "@versia/kit/db";
import { RolePermissions, Users } from "@versia/kit/tables";
import { and, gt, gte, lt, sql } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/follow_requests",
@ -52,14 +50,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -69,10 +59,6 @@ export default apiRoute((app) =>
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { objects: followRequests, link } =
await Timeline.getUserTimeline(
and(

View file

@ -5,8 +5,6 @@ import { db } from "@versia/kit/db";
import { Markers, RolePermissions } from "@versia/kit/tables";
import { type SQL, and, eq } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/markers",
@ -72,14 +70,6 @@ const routeGet = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -111,14 +101,6 @@ const routePost = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -129,10 +111,6 @@ export default apiRoute((app) => {
const timeline = Array.isArray(timelines) ? timelines : [];
if (!user) {
throw new ApiError(401, "Unauthorized");
}
if (!timeline) {
return context.json({}, 200);
}
@ -201,10 +179,6 @@ export default apiRoute((app) => {
} = context.req.valid("query");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const markers: ApiMarker = {
home: undefined,
notifications: undefined,

View file

@ -67,14 +67,7 @@ const routePut = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Media not found",
content: {
@ -116,14 +109,6 @@ const routeGet = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});

View file

@ -65,14 +65,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
413: {
description: "File too large",
content: {

View file

@ -4,8 +4,6 @@ import { Timeline, User } from "@versia/kit/db";
import { RolePermissions, Users } from "@versia/kit/tables";
import { and, gt, gte, lt, sql } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/mutes",
@ -54,14 +52,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -70,10 +60,6 @@ export default apiRoute((app) =>
const { max_id, since_id, limit, min_id } = context.req.valid("query");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { objects: mutes, link } = await Timeline.getUserTimeline(
and(
max_id ? lt(Users.id, max_id) : undefined,

View file

@ -70,4 +70,18 @@ describe(meta.route, () => {
expect(output.length).toBe(0);
});
test("should not be able to dismiss other user's notifications", async () => {
const response = await fakeRequest(
meta.route.replace(":id", notifications[0].id),
{
method: "POST",
headers: {
Authorization: `Bearer ${tokens[1].data.accessToken}`,
},
},
);
expect(response.status).toBe(404);
});
});

View file

@ -4,7 +4,6 @@ import { Notification } from "@versia/kit/db";
import { RolePermissions } from "@versia/kit/tables";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/notifications/:id/dismiss",
@ -45,14 +44,6 @@ const route = createRoute({
200: {
description: "Notification dismissed",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -61,13 +52,10 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const notification = await Notification.fromId(id);
if (!notification) {
if (!notification || notification.data.notifiedId !== user.id) {
throw new ApiError(404, "Notification not found");
}

View file

@ -85,4 +85,17 @@ describe(meta.route, () => {
expect(notification.account).toBeDefined();
expect(notification.account?.id).toBe(users[1].id);
});
test("should not be able to view other user's notifications", async () => {
const response = await fakeRequest(
meta.route.replace(":id", notifications[0].id),
{
headers: {
Authorization: `Bearer ${tokens[1].data.accessToken}`,
},
},
);
expect(response.status).toBe(404);
});
});

View file

@ -50,14 +50,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Notification not found",
content: {
@ -74,13 +67,10 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const notification = await Notification.fromId(id, user.id);
if (!notification) {
if (!notification || notification.data.notifiedId !== user.id) {
throw new ApiError(404, "Notification not found");
}

View file

@ -1,8 +1,6 @@
import { apiRoute, applyConfig, auth } from "@/api";
import { createRoute } from "@hono/zod-openapi";
import { RolePermissions } from "@versia/kit/tables";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/notifications/clear",
@ -34,23 +32,12 @@ const route = createRoute({
200: {
description: "Notifications cleared",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
await user.clearAllNotifications();

View file

@ -2,8 +2,6 @@ import { apiRoute, applyConfig, auth } from "@/api";
import { createRoute } from "@hono/zod-openapi";
import { RolePermissions } from "@versia/kit/tables";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/notifications/destroy_multiple",
@ -44,14 +42,6 @@ const route = createRoute({
200: {
description: "Notifications dismissed",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -59,10 +49,6 @@ export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { "ids[]": ids } = context.req.valid("query");
await user.clearSomeNotifications(ids);

View file

@ -4,8 +4,6 @@ import { Notification, Timeline } from "@versia/kit/db";
import { Notifications, RolePermissions } from "@versia/kit/tables";
import { and, eq, gt, gte, inArray, lt, not, sql } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v1/notifications",
@ -115,23 +113,12 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const {
account_id,

View file

@ -2,8 +2,6 @@ import { apiRoute, applyConfig, auth } from "@/api";
import { createRoute } from "@hono/zod-openapi";
import { User } from "@versia/kit/db";
import { RolePermissions } from "@versia/kit/tables";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
ratelimits: {
@ -39,29 +37,17 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user: self } = context.get("auth");
const { user } = context.get("auth");
if (!self) {
throw new ApiError(401, "Unauthorized");
}
await self.update({
await user.update({
avatar: "",
});
return context.json(self.toApi(true), 200);
return context.json(user.toApi(true), 200);
}),
);

View file

@ -2,8 +2,6 @@ import { apiRoute, applyConfig, auth } from "@/api";
import { createRoute } from "@hono/zod-openapi";
import { User } from "@versia/kit/db";
import { RolePermissions } from "@versia/kit/tables";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
ratelimits: {
@ -39,29 +37,17 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user: self } = context.get("auth");
const { user } = context.get("auth");
if (!self) {
throw new ApiError(401, "Unauthorized");
}
await self.update({
await user.update({
header: "",
});
return context.json(self.toApi(true), 200);
return context.json(user.toApi(true), 200);
}),
);

View file

@ -51,14 +51,7 @@ const routeGet = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Role not found",
content: {
@ -94,14 +87,7 @@ const routePatch = createRoute({
204: {
description: "Role updated",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Role not found",
content: {
@ -138,14 +124,7 @@ const routeDelete = createRoute({
204: {
description: "Role deleted",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Role not found",
content: {
@ -167,13 +146,8 @@ const routeDelete = createRoute({
export default apiRoute((app) => {
app.openapi(routeGet, async (context) => {
const { user } = context.get("auth");
const { id } = context.req.valid("param");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const role = await Role.fromId(id);
if (!role) {
@ -189,10 +163,6 @@ export default apiRoute((app) => {
const { permissions, priority, description, icon, name, visible } =
context.req.valid("json");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const role = await Role.fromId(id);
if (!role) {
@ -246,10 +216,6 @@ export default apiRoute((app) => {
const { user } = context.get("auth");
const { id } = context.req.valid("param");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const role = await Role.fromId(id);
if (!role) {

View file

@ -43,14 +43,6 @@ const routeGet = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -82,14 +74,7 @@ const routePost = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
403: {
description: "Forbidden",
content: {
@ -103,12 +88,6 @@ const routePost = createRoute({
export default apiRoute((app) => {
app.openapi(routeGet, async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const roles = await Role.getAll();
return context.json(
@ -122,10 +101,6 @@ export default apiRoute((app) => {
const { description, icon, name, permissions, priority, visible } =
context.req.valid("json");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
// Priority check
const userRoles = await Role.getUserRoles(user.id, user.data.isAdmin);

View file

@ -51,14 +51,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Record not found",
content: {
@ -76,10 +69,6 @@ export default apiRoute((app) =>
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const note = await Note.fromId(id, user?.id);
if (!(note && (await note?.isViewableByUser(user)))) {

View file

@ -59,14 +59,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Record not found",
content: {
@ -85,10 +78,6 @@ export default apiRoute((app) =>
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const note = await Note.fromId(id, user?.id);
if (!(note && (await note?.isViewableByUser(user)))) {

View file

@ -255,7 +255,7 @@ export default apiRoute((app) => {
throw new ApiError(404, "Note not found");
}
if (note.author.id !== user?.id) {
if (note.author.id !== user.id) {
throw new ApiError(401, "Unauthorized");
}
@ -271,10 +271,6 @@ export default apiRoute((app) => {
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const note = await Note.fromId(id, user?.id);
if (!(note && (await note?.isViewableByUser(user)))) {

View file

@ -84,10 +84,6 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const foundStatus = await Note.fromId(id, user?.id);
if (!foundStatus) {

View file

@ -69,14 +69,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Record not found",
content: {
@ -110,10 +103,6 @@ export default apiRoute((app) =>
const { visibility } = context.req.valid("json");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const note = await Note.fromId(id, user.id);
if (!(note && (await note?.isViewableByUser(user)))) {

View file

@ -59,14 +59,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Record not found",
content: {
@ -84,10 +77,6 @@ export default apiRoute((app) =>
const { max_id, min_id, since_id, limit } = context.req.valid("query");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const note = await Note.fromId(id, user.id);
if (!(note && (await note?.isViewableByUser(user)))) {

View file

@ -56,14 +56,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Record not found",
content: {
@ -80,10 +73,6 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const note = await Note.fromId(id, user.id);
if (!(note && (await note?.isViewableByUser(user)))) {

View file

@ -51,14 +51,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Record not found",
content: {
@ -75,10 +68,6 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const note = await Note.fromId(id, user.id);
if (!(note && (await note?.isViewableByUser(user)))) {

View file

@ -75,10 +75,6 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const status = await Note.fromId(id, user.id);
if (!status) {

View file

@ -52,14 +52,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Record not found",
content: {
@ -84,10 +77,6 @@ export default apiRoute((app) =>
const { id } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const note = await Note.fromId(id, user.id);
// Check if user is authorized to view this status (if it's private)

View file

@ -135,14 +135,7 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
422: {
description: "Invalid data",
content: {
@ -158,10 +151,6 @@ export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user, application } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const {
status,
media_ids,

View file

@ -4,8 +4,6 @@ import { Note, Timeline } from "@versia/kit/db";
import { Notes, RolePermissions } from "@versia/kit/tables";
import { and, eq, gt, gte, inArray, lt, or, sql } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
ratelimits: {
@ -62,14 +60,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -79,10 +69,6 @@ export default apiRoute((app) =>
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { objects, link } = await Timeline.getNoteTimeline(
and(
and(

View file

@ -4,7 +4,6 @@ import { Note, Timeline } from "@versia/kit/db";
import { Notes, RolePermissions } from "@versia/kit/tables";
import { and, eq, gt, gte, inArray, lt, or, sql } from "drizzle-orm";
import { z } from "zod";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
ratelimits: {
@ -71,14 +70,6 @@ const route = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});

View file

@ -107,14 +107,7 @@ const routeGet = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Filter not found",
content: {
@ -156,14 +149,7 @@ const routePut = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Filter not found",
content: {
@ -192,14 +178,7 @@ const routeDelete = createRoute({
204: {
description: "Filter deleted",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Filter not found",
content: {
@ -216,10 +195,6 @@ export default apiRoute((app) => {
const { user } = context.get("auth");
const { id } = context.req.valid("param");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const userFilter = await db.query.Filters.findFirst({
where: (filter, { eq, and }): SQL | undefined =>
and(eq(filter.userId, user.id), eq(filter.id, id)),
@ -263,10 +238,6 @@ export default apiRoute((app) => {
keywords_attributes,
} = context.req.valid("json");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
await db
.update(Filters)
.set({
@ -352,10 +323,6 @@ export default apiRoute((app) => {
const { user } = context.get("auth");
const { id } = context.req.valid("param");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
await db
.delete(Filters)
.where(and(eq(Filters.userId, user.id), eq(Filters.id, id)));

View file

@ -4,8 +4,6 @@ import { db } from "@versia/kit/db";
import { FilterKeywords, Filters, RolePermissions } from "@versia/kit/tables";
import type { SQL } from "drizzle-orm";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error";
import { ErrorSchema } from "~/types/api";
export const meta = applyConfig({
route: "/api/v2/filters",
ratelimits: {
@ -93,14 +91,6 @@ const routeGet = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -133,14 +123,6 @@ const routePost = createRoute({
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
});
@ -148,10 +130,6 @@ export default apiRoute((app) => {
app.openapi(routeGet, async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const userFilters = await db.query.Filters.findMany({
where: (filter, { eq }): SQL | undefined =>
eq(filter.userId, user.id),
@ -190,10 +168,6 @@ export default apiRoute((app) => {
keywords_attributes,
} = context.req.valid("json");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const newFilter = (
await db
.insert(Filters)

View file

@ -101,14 +101,14 @@ const route = createRoute({
export default apiRoute((app) =>
app.openapi(route, async (context) => {
const { user: self } = context.get("auth");
const { user } = context.get("auth");
const { q, type, resolve, following, account_id, limit, offset } =
context.req.valid("query");
if (!self && (resolve || offset)) {
if (!user && (resolve || offset)) {
throw new ApiError(
401,
"Usage of resolve or offset requires authentication",
"Usage of 'resolve' or 'offset' requires authentication",
);
}
@ -164,7 +164,7 @@ export default apiRoute((app) =>
if (resolve && domain) {
const manager = await (
self ?? User
user ?? User
).getFederationRequester();
const uri = await User.webFinger(manager, username, domain);
@ -209,9 +209,9 @@ export default apiRoute((app) =>
Users.id,
accountResults.map((hit) => hit),
),
self && following
user && following
? sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."subjectId" = ${
self?.id
user?.id
} AND "Relationships".following = ${!!following} AND "Relationships"."ownerId" = ${
Users.id
})`
@ -231,9 +231,9 @@ export default apiRoute((app) =>
account_id
? eq(Notes.authorId, account_id)
: undefined,
self && following
user && following
? sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."subjectId" = ${
self?.id
user?.id
} AND "Relationships".following = ${!!following} AND "Relationships"."ownerId" = ${
Notes.authorId
})`
@ -242,7 +242,7 @@ export default apiRoute((app) =>
undefined,
undefined,
undefined,
self?.id,
user?.id,
)
: [];
@ -250,7 +250,7 @@ export default apiRoute((app) =>
{
accounts: accounts.map((account) => account.toApi()),
statuses: await Promise.all(
statuses.map((status) => status.toApi(self)),
statuses.map((status) => status.toApi(user)),
),
hashtags: [],
},

View file

@ -40,14 +40,6 @@ export default (plugin: PluginType): void => {
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Account not found",
content: {
@ -62,10 +54,6 @@ export default (plugin: PluginType): void => {
const { id: issuerId } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const issuer = context
.get("pluginConfig")
.providers.find((provider) => provider.id === issuerId);
@ -126,14 +114,6 @@ export default (plugin: PluginType): void => {
204: {
description: "Account unlinked",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Account not found",
content: {
@ -148,10 +128,6 @@ export default (plugin: PluginType): void => {
const { id: issuerId } = context.req.valid("param");
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
// Check if issuer exists
const issuer = context
.get("pluginConfig")

View file

@ -6,7 +6,6 @@ import {
generateRandomCodeVerifier,
} from "oauth4webapi";
import { z } from "zod";
import { ApiError } from "~/classes/errors/api-error.ts";
import { ErrorSchema } from "~/types/api";
import type { PluginType } from "../../index.ts";
import { oauthDiscoveryRequest, oauthRedirectUri } from "../../utils.ts";
@ -40,23 +39,11 @@ export default (plugin: PluginType): void => {
},
},
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
},
},
async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const linkedAccounts = await user.getLinkedOidcAccounts(
context.get("pluginConfig").providers,
);
@ -99,14 +86,6 @@ export default (plugin: PluginType): void => {
302: {
description: "Redirect to OpenID provider",
},
401: {
description: "Unauthorized",
content: {
"application/json": {
schema: ErrorSchema,
},
},
},
404: {
description: "Issuer not found",
content: {
@ -120,10 +99,6 @@ export default (plugin: PluginType): void => {
async (context) => {
const { user } = context.get("auth");
if (!user) {
throw new ApiError(401, "Unauthorized");
}
const { issuer: issuerId } = context.req.valid("json");
const issuer = context

View file

@ -349,8 +349,8 @@ async function parseUrlEncoded(context: Context): Promise<ParsedQs> {
return parsed;
}
export const qsQuery = (): MiddlewareHandler => {
return createMiddleware(async (context, next) => {
export const qsQuery = (): MiddlewareHandler<HonoEnv> => {
return createMiddleware<HonoEnv>(async (context, next) => {
const parsed = parse(new URL(context.req.url).searchParams.toString(), {
parseArrays: true,
interpretNumericEntities: true,