2025-03-22 02:34:03 +01:00
|
|
|
import {
|
|
|
|
|
Account as AccountSchema,
|
|
|
|
|
Relationship as RelationshipSchema,
|
2025-05-01 16:27:34 +02:00
|
|
|
RolePermission,
|
2025-03-22 02:34:03 +01:00
|
|
|
zBoolean,
|
2025-03-22 18:04:47 +01:00
|
|
|
} from "@versia/client/schemas";
|
2025-06-15 23:50:34 +02:00
|
|
|
import { ApiError } from "@versia-server/kit";
|
|
|
|
|
import {
|
|
|
|
|
apiRoute,
|
|
|
|
|
auth,
|
|
|
|
|
handleZodError,
|
|
|
|
|
qsQuery,
|
|
|
|
|
} from "@versia-server/kit/api";
|
|
|
|
|
import { Relationship } from "@versia-server/kit/db";
|
2025-07-07 03:42:35 +02:00
|
|
|
import { describeRoute, resolver, validator } from "hono-openapi";
|
|
|
|
|
import { z } from "zod/v4";
|
2025-06-15 04:38:20 +02:00
|
|
|
import { rateLimit } from "../../../../../middlewares/rate-limit.ts";
|
2023-09-23 04:28:00 +02:00
|
|
|
|
2025-03-29 03:30:06 +01:00
|
|
|
export default apiRoute((app) =>
|
|
|
|
|
app.get(
|
|
|
|
|
"/api/v1/accounts/relationships",
|
|
|
|
|
describeRoute({
|
|
|
|
|
summary: "Check relationships to other accounts",
|
|
|
|
|
description:
|
|
|
|
|
"Find out whether a given account is followed, blocked, muted, etc.",
|
|
|
|
|
externalDocs: {
|
|
|
|
|
url: "https://docs.joinmastodon.org/methods/accounts/#relationships",
|
|
|
|
|
},
|
|
|
|
|
tags: ["Accounts"],
|
|
|
|
|
responses: {
|
|
|
|
|
200: {
|
|
|
|
|
description: "Relationships",
|
|
|
|
|
content: {
|
|
|
|
|
"application/json": {
|
|
|
|
|
schema: resolver(z.array(RelationshipSchema)),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
401: ApiError.missingAuthentication().schema,
|
|
|
|
|
422: ApiError.validationFailed().schema,
|
|
|
|
|
},
|
|
|
|
|
}),
|
2025-03-27 20:12:00 +01:00
|
|
|
rateLimit(10),
|
2024-12-30 19:18:31 +01:00
|
|
|
auth({
|
|
|
|
|
auth: true,
|
|
|
|
|
scopes: ["read:follows"],
|
2025-03-22 18:04:47 +01:00
|
|
|
permissions: [RolePermission.ManageOwnFollows],
|
2024-12-30 19:18:31 +01:00
|
|
|
}),
|
|
|
|
|
qsQuery(),
|
2025-03-29 03:30:06 +01:00
|
|
|
validator(
|
|
|
|
|
"query",
|
|
|
|
|
z.object({
|
|
|
|
|
id: z
|
|
|
|
|
.array(AccountSchema.shape.id)
|
|
|
|
|
.min(1)
|
|
|
|
|
.max(10)
|
2025-07-07 03:42:35 +02:00
|
|
|
.or(AccountSchema.shape.id)
|
|
|
|
|
.meta({
|
2025-03-29 03:30:06 +01:00
|
|
|
description:
|
|
|
|
|
"Check relationships for the provided account IDs.",
|
|
|
|
|
example: [
|
|
|
|
|
"f137ce6f-ff5e-4998-b20f-0361ba9be007",
|
|
|
|
|
"8424c654-5d03-4a1b-bec8-4e87db811b5d",
|
|
|
|
|
],
|
|
|
|
|
}),
|
2025-07-07 03:42:35 +02:00
|
|
|
with_suspended: zBoolean.default(false).meta({
|
2025-02-13 01:31:15 +01:00
|
|
|
description:
|
2025-03-29 03:30:06 +01:00
|
|
|
"Whether relationships should be returned for suspended users",
|
|
|
|
|
example: false,
|
2025-02-13 01:31:15 +01:00
|
|
|
}),
|
|
|
|
|
}),
|
2025-03-29 03:30:06 +01:00
|
|
|
handleZodError,
|
|
|
|
|
),
|
|
|
|
|
async (context) => {
|
|
|
|
|
const { user } = context.get("auth");
|
2024-08-27 20:14:10 +02:00
|
|
|
|
2025-03-29 03:30:06 +01:00
|
|
|
// TODO: Implement with_suspended
|
2025-07-07 03:42:35 +02:00
|
|
|
const { id } = context.req.valid("query");
|
2024-08-27 20:14:10 +02:00
|
|
|
|
2025-03-29 03:30:06 +01:00
|
|
|
const relationships = await Relationship.fromOwnerAndSubjects(
|
|
|
|
|
user,
|
2025-07-07 03:42:35 +02:00
|
|
|
Array.isArray(id) ? id : [id],
|
2025-03-29 03:30:06 +01:00
|
|
|
);
|
2024-08-27 20:14:10 +02:00
|
|
|
|
2025-03-29 03:30:06 +01:00
|
|
|
relationships.sort(
|
|
|
|
|
(a, b) =>
|
2025-07-07 03:42:35 +02:00
|
|
|
id.indexOf(a.data.subjectId) - id.indexOf(b.data.subjectId),
|
2025-03-29 03:30:06 +01:00
|
|
|
);
|
2024-08-27 20:14:10 +02:00
|
|
|
|
2025-03-29 03:30:06 +01:00
|
|
|
return context.json(
|
|
|
|
|
relationships.map((r) => r.toApi()),
|
|
|
|
|
200,
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
2024-08-19 20:06:38 +02:00
|
|
|
);
|