summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/mastodon/endpoints/status.ts
diff options
context:
space:
mode:
authorJulia <julia@insertdomain.name>2025-05-29 00:07:38 +0000
committerJulia <julia@insertdomain.name>2025-05-29 00:07:38 +0000
commit6b554c178b81f13f83a69b19d44b72b282a0c119 (patch)
treef5537f1a56323a4dd57ba150b3cb84a2d8b5dc63 /packages/backend/src/server/api/mastodon/endpoints/status.ts
parentmerge: Security fixes (!970) (diff)
parentbump version for release (diff)
downloadsharkey-6b554c178b81f13f83a69b19d44b72b282a0c119.tar.gz
sharkey-6b554c178b81f13f83a69b19d44b72b282a0c119.tar.bz2
sharkey-6b554c178b81f13f83a69b19d44b72b282a0c119.zip
merge: release 2025.4.2 (!1051)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1051 Approved-by: Hazelnoot <acomputerdog@gmail.com> Approved-by: Marie <github@yuugi.dev> Approved-by: Julia <julia@insertdomain.name>
Diffstat (limited to 'packages/backend/src/server/api/mastodon/endpoints/status.ts')
-rw-r--r--packages/backend/src/server/api/mastodon/endpoints/status.ts606
1 files changed, 241 insertions, 365 deletions
diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts
index 4c49a6a293..22b8a911ca 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/status.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts
@@ -4,12 +4,11 @@
*/
import querystring, { ParsedUrlQueryInput } from 'querystring';
+import { Injectable } from '@nestjs/common';
import { emojiRegexAtStartToEnd } from '@/misc/emoji-regex.js';
-import { getErrorData, MastodonLogger } from '@/server/api/mastodon/MastodonLogger.js';
-import { parseTimelineArgs, TimelineArgs, toBoolean, toInt } from '@/server/api/mastodon/timelineArgs.js';
-import { AuthenticateService } from '@/server/api/AuthenticateService.js';
-import { convertAttachment, convertPoll, MastoConverters } from '../converters.js';
-import { getAccessToken, getClient, MastodonApiServerService } from '../MastodonApiServerService.js';
+import { parseTimelineArgs, TimelineArgs, toBoolean, toInt } from '@/server/api/mastodon/argsUtils.js';
+import { MastodonClientService } from '@/server/api/mastodon/MastodonClientService.js';
+import { convertAttachment, convertPoll, MastodonConverters } from '../MastodonConverters.js';
import type { Entity } from 'megalodon';
import type { FastifyInstance } from 'fastify';
@@ -18,167 +17,112 @@ function normalizeQuery(data: Record<string, unknown>) {
return querystring.parse(str);
}
+@Injectable()
export class ApiStatusMastodon {
constructor(
- private readonly fastify: FastifyInstance,
- private readonly mastoConverters: MastoConverters,
- private readonly logger: MastodonLogger,
- private readonly authenticateService: AuthenticateService,
- private readonly mastodon: MastodonApiServerService,
+ private readonly mastoConverters: MastodonConverters,
+ private readonly clientService: MastodonClientService,
) {}
- public getStatus() {
- this.fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id', async (_request, reply) => {
- try {
- const { client, me } = await this.mastodon.getAuthClient(_request);
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const data = await client.getStatus(_request.params.id);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/statuses/${_request.params.id}`, data);
- reply.code(_request.is404 ? 404 : 401).send(data);
+ public register(fastify: FastifyInstance): void {
+ fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.getStatus(_request.params.id);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ // Fixup - Discord ignores CWs and renders the entire post.
+ if (response.sensitive && _request.headers['user-agent']?.match(/\bDiscordbot\//)) {
+ response.content = '(preview disabled for sensitive content)';
+ response.media_attachments = [];
}
+
+ return reply.send(response);
});
- }
- public getStatusSource() {
- this.fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id/source', async (_request, reply) => {
- const BASE_URL = `${_request.protocol}://${_request.host}`;
- const accessTokens = _request.headers.authorization;
- const client = getClient(BASE_URL, accessTokens);
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const data = await client.getStatusSource(_request.params.id);
- reply.send(data.data);
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/statuses/${_request.params.id}/source`, data);
- reply.code(_request.is404 ? 404 : 401).send(data);
- }
+ fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id/source', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const client = this.clientService.getClient(_request);
+ const data = await client.getStatusSource(_request.params.id);
+
+ return reply.send(data.data);
});
- }
- public getContext() {
- this.fastify.get<{ Params: { id?: string }, Querystring: TimelineArgs }>('/v1/statuses/:id/context', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const { data } = await client.getStatusContext(_request.params.id, parseTimelineArgs(_request.query));
- const ancestors = await Promise.all(data.ancestors.map(async status => await this.mastoConverters.convertStatus(status, me)));
- const descendants = await Promise.all(data.descendants.map(async status => await this.mastoConverters.convertStatus(status, me)));
- reply.send({ ancestors, descendants });
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/statuses/${_request.params.id}/context`, data);
- reply.code(_request.is404 ? 404 : 401).send(data);
- }
+ fastify.get<{ Params: { id?: string }, Querystring: TimelineArgs }>('/v1/statuses/:id/context', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const { data } = await client.getStatusContext(_request.params.id, parseTimelineArgs(_request.query));
+ const ancestors = await Promise.all(data.ancestors.map(async (status: Entity.Status) => await this.mastoConverters.convertStatus(status, me)));
+ const descendants = await Promise.all(data.descendants.map(async (status: Entity.Status) => await this.mastoConverters.convertStatus(status, me)));
+ const response = { ancestors, descendants };
+
+ return reply.send(response);
});
- }
- public getHistory() {
- this.fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id/history', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const [user] = await this.authenticateService.authenticate(getAccessToken(_request.headers.authorization));
- const edits = await this.mastoConverters.getEdits(_request.params.id, user);
- reply.send(edits);
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/statuses/${_request.params.id}/history`, data);
- reply.code(401).send(data);
- }
+ fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id/history', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const user = await this.clientService.getAuth(_request);
+ const edits = await this.mastoConverters.getEdits(_request.params.id, user);
+
+ return reply.send(edits);
});
- }
- public getReblogged() {
- this.fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id/reblogged_by', async (_request, reply) => {
- const BASE_URL = `${_request.protocol}://${_request.host}`;
- const accessTokens = _request.headers.authorization;
- const client = getClient(BASE_URL, accessTokens);
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const data = await client.getStatusRebloggedBy(_request.params.id);
- reply.send(await Promise.all(data.data.map(async (account: Entity.Account) => await this.mastoConverters.convertAccount(account))));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/statuses/${_request.params.id}/reblogged_by`, data);
- reply.code(401).send(data);
- }
+ fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id/reblogged_by', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const client = this.clientService.getClient(_request);
+ const data = await client.getStatusRebloggedBy(_request.params.id);
+ const response = await Promise.all(data.data.map((account: Entity.Account) => this.mastoConverters.convertAccount(account)));
+
+ return reply.send(response);
});
- }
- public getFavourites() {
- this.fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id/favourited_by', async (_request, reply) => {
- const BASE_URL = `${_request.protocol}://${_request.host}`;
- const accessTokens = _request.headers.authorization;
- const client = getClient(BASE_URL, accessTokens);
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const data = await client.getStatusFavouritedBy(_request.params.id);
- reply.send(await Promise.all(data.data.map(async (account: Entity.Account) => await this.mastoConverters.convertAccount(account))));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/statuses/${_request.params.id}/favourited_by`, data);
- reply.code(401).send(data);
- }
+ fastify.get<{ Params: { id?: string } }>('/v1/statuses/:id/favourited_by', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const client = this.clientService.getClient(_request);
+ const data = await client.getStatusFavouritedBy(_request.params.id);
+ const response = await Promise.all(data.data.map((account: Entity.Account) => this.mastoConverters.convertAccount(account)));
+
+ return reply.send(response);
});
- }
- public getMedia() {
- this.fastify.get<{ Params: { id?: string } }>('/v1/media/:id', async (_request, reply) => {
- const BASE_URL = `${_request.protocol}://${_request.host}`;
- const accessTokens = _request.headers.authorization;
- const client = getClient(BASE_URL, accessTokens);
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const data = await client.getMedia(_request.params.id);
- reply.send(convertAttachment(data.data));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/media/${_request.params.id}`, data);
- reply.code(401).send(data);
- }
+ fastify.get<{ Params: { id?: string } }>('/v1/media/:id', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const client = this.clientService.getClient(_request);
+ const data = await client.getMedia(_request.params.id);
+ const response = convertAttachment(data.data);
+
+ return reply.send(response);
});
- }
- public getPoll() {
- this.fastify.get<{ Params: { id?: string } }>('/v1/polls/:id', async (_request, reply) => {
- const BASE_URL = `${_request.protocol}://${_request.host}`;
- const accessTokens = _request.headers.authorization;
- const client = getClient(BASE_URL, accessTokens);
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const data = await client.getPoll(_request.params.id);
- reply.send(convertPoll(data.data));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/polls/${_request.params.id}`, data);
- reply.code(401).send(data);
- }
+ fastify.get<{ Params: { id?: string } }>('/v1/polls/:id', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const client = this.clientService.getClient(_request);
+ const data = await client.getPoll(_request.params.id);
+ const response = convertPoll(data.data);
+
+ return reply.send(response);
});
- }
- public votePoll() {
- this.fastify.post<{ Params: { id?: string }, Body: { choices?: number[] } }>('/v1/polls/:id/votes', async (_request, reply) => {
- const BASE_URL = `${_request.protocol}://${_request.host}`;
- const accessTokens = _request.headers.authorization;
- const client = getClient(BASE_URL, accessTokens);
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- if (!_request.body.choices) return reply.code(400).send({ error: 'Missing required payload "choices"' });
- const data = await client.votePoll(_request.params.id, _request.body.choices);
- reply.send(convertPoll(data.data));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/polls/${_request.params.id}/votes`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string }, Body: { choices?: number[] } }>('/v1/polls/:id/votes', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+ if (!_request.body.choices) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required payload "choices"' });
+
+ const client = this.clientService.getClient(_request);
+ const data = await client.votePoll(_request.params.id, _request.body.choices);
+ const response = convertPoll(data.data);
+
+ return reply.send(response);
});
- }
- public postStatus() {
- this.fastify.post<{
+ fastify.post<{
Body: {
media_ids?: string[],
poll?: {
@@ -202,63 +146,58 @@ export class ApiStatusMastodon {
}
}>('/v1/statuses', async (_request, reply) => {
let body = _request.body;
- try {
- const { client, me } = await this.mastodon.getAuthClient(_request);
- if ((!body.poll && body['poll[options][]']) || (!body.media_ids && body['media_ids[]'])
- ) {
- body = normalizeQuery(body);
- }
- const text = body.status ??= ' ';
- const removed = text.replace(/@\S+/g, '').replace(/\s|/g, '');
- const isDefaultEmoji = emojiRegexAtStartToEnd.test(removed);
- const isCustomEmoji = /^:[a-zA-Z0-9@_]+:$/.test(removed);
- if ((body.in_reply_to_id && isDefaultEmoji) || (body.in_reply_to_id && isCustomEmoji)) {
- const a = await client.createEmojiReaction(
- body.in_reply_to_id,
- removed,
- );
- reply.send(a.data);
- }
- if (body.in_reply_to_id && removed === '/unreact') {
- const id = body.in_reply_to_id;
- const post = await client.getStatus(id);
- const react = post.data.emoji_reactions.filter(e => e.me)[0].name;
- const data = await client.deleteEmojiReaction(id, react);
- reply.send(data.data);
- }
- if (!body.media_ids) body.media_ids = undefined;
- if (body.media_ids && !body.media_ids.length) body.media_ids = undefined;
-
- if (body.poll && !body.poll.options) {
- return reply.code(400).send({ error: 'Missing required payload "poll.options"' });
- }
- if (body.poll && !body.poll.expires_in) {
- return reply.code(400).send({ error: 'Missing required payload "poll.expires_in"' });
- }
+ if ((!body.poll && body['poll[options][]']) || (!body.media_ids && body['media_ids[]'])
+ ) {
+ body = normalizeQuery(body);
+ }
+ const text = body.status ??= ' ';
+ const removed = text.replace(/@\S+/g, '').replace(/\s|/g, '');
+ const isDefaultEmoji = emojiRegexAtStartToEnd.test(removed);
+ const isCustomEmoji = /^:[a-zA-Z0-9@_]+:$/.test(removed);
- const options = {
- ...body,
- sensitive: toBoolean(body.sensitive),
- poll: body.poll ? {
- options: body.poll.options!, // eslint-disable-line @typescript-eslint/no-non-null-assertion
- expires_in: toInt(body.poll.expires_in)!, // eslint-disable-line @typescript-eslint/no-non-null-assertion
- multiple: toBoolean(body.poll.multiple),
- hide_totals: toBoolean(body.poll.hide_totals),
- } : undefined,
- };
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ if ((body.in_reply_to_id && isDefaultEmoji) || (body.in_reply_to_id && isCustomEmoji)) {
+ const a = await client.createEmojiReaction(
+ body.in_reply_to_id,
+ removed,
+ );
+ return reply.send(a.data);
+ }
+ if (body.in_reply_to_id && removed === '/unreact') {
+ const id = body.in_reply_to_id;
+ const post = await client.getStatus(id);
+ const react = post.data.emoji_reactions.filter((e: Entity.Emoji) => e.me)[0].name;
+ const data = await client.deleteEmojiReaction(id, react);
+ return reply.send(data.data);
+ }
+ if (!body.media_ids) body.media_ids = undefined;
+ if (body.media_ids && !body.media_ids.length) body.media_ids = undefined;
- const data = await client.postStatus(text, options);
- reply.send(await this.mastoConverters.convertStatus(data.data as Entity.Status, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error('POST /v1/statuses', data);
- reply.code(401).send(data);
+ if (body.poll && !body.poll.options) {
+ return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required payload "poll.options"' });
+ }
+ if (body.poll && !body.poll.expires_in) {
+ return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required payload "poll.expires_in"' });
}
+
+ const options = {
+ ...body,
+ sensitive: toBoolean(body.sensitive),
+ poll: body.poll ? {
+ options: body.poll.options!, // eslint-disable-line @typescript-eslint/no-non-null-assertion
+ expires_in: toInt(body.poll.expires_in)!, // eslint-disable-line @typescript-eslint/no-non-null-assertion
+ multiple: toBoolean(body.poll.multiple),
+ hide_totals: toBoolean(body.poll.hide_totals),
+ } : undefined,
+ };
+
+ const data = await client.postStatus(text, options);
+ const response = await this.mastoConverters.convertStatus(data.data as Entity.Status, me);
+
+ return reply.send(response);
});
- }
- public updateStatus() {
- this.fastify.put<{
+ fastify.put<{
Params: { id: string },
Body: {
status?: string,
@@ -273,201 +212,138 @@ export class ApiStatusMastodon {
},
}
}>('/v1/statuses/:id', async (_request, reply) => {
- try {
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const body = _request.body;
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const body = _request.body;
- if (!body.media_ids || !body.media_ids.length) {
- body.media_ids = undefined;
- }
+ if (!body.media_ids || !body.media_ids.length) {
+ body.media_ids = undefined;
+ }
- const options = {
- ...body,
- sensitive: toBoolean(body.sensitive),
- poll: body.poll ? {
- options: body.poll.options,
- expires_in: toInt(body.poll.expires_in),
- multiple: toBoolean(body.poll.multiple),
- hide_totals: toBoolean(body.poll.hide_totals),
- } : undefined,
- };
+ const options = {
+ ...body,
+ sensitive: toBoolean(body.sensitive),
+ poll: body.poll ? {
+ options: body.poll.options,
+ expires_in: toInt(body.poll.expires_in),
+ multiple: toBoolean(body.poll.multiple),
+ hide_totals: toBoolean(body.poll.hide_totals),
+ } : undefined,
+ };
- const data = await client.editStatus(_request.params.id, options);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}`, data);
- reply.code(401).send(data);
- }
+ const data = await client.editStatus(_request.params.id, options);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public addFavourite() {
- this.fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/favourite', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.createEmojiReaction(_request.params.id, '❤');
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/favorite`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/favourite', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.createEmojiReaction(_request.params.id, '❤');
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public rmFavourite() {
- this.fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/unfavourite', async (_request, reply) => {
- try {
- const { client, me } = await this.mastodon.getAuthClient(_request);
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const data = await client.deleteEmojiReaction(_request.params.id, '❤');
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`GET /v1/statuses/${_request.params.id}/unfavorite`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/unfavourite', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.deleteEmojiReaction(_request.params.id, '❤');
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public reblogStatus() {
- this.fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/reblog', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.reblogStatus(_request.params.id);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/reblog`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/reblog', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.reblogStatus(_request.params.id);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public unreblogStatus() {
- this.fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/unreblog', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.unreblogStatus(_request.params.id);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/unreblog`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/unreblog', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.unreblogStatus(_request.params.id);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public bookmarkStatus() {
- this.fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/bookmark', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.bookmarkStatus(_request.params.id);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/bookmark`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/bookmark', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.bookmarkStatus(_request.params.id);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public unbookmarkStatus() {
- this.fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/unbookmark', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.unbookmarkStatus(_request.params.id);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/unbookmark`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/unbookmark', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.unbookmarkStatus(_request.params.id);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
+ fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/pin', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
- public pinStatus() {
- this.fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/pin', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.pinStatus(_request.params.id);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/pin`, data);
- reply.code(401).send(data);
- }
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.pinStatus(_request.params.id);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public unpinStatus() {
- this.fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/unpin', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.unpinStatus(_request.params.id);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/unpin`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string } }>('/v1/statuses/:id/unpin', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.unpinStatus(_request.params.id);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public reactStatus() {
- this.fastify.post<{ Params: { id?: string, name?: string } }>('/v1/statuses/:id/react/:name', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- if (!_request.params.name) return reply.code(400).send({ error: 'Missing required parameter "name"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.createEmojiReaction(_request.params.id, _request.params.name);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/react/${_request.params.name}`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string, name?: string } }>('/v1/statuses/:id/react/:name', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+ if (!_request.params.name) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "name"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.createEmojiReaction(_request.params.id, _request.params.name);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public unreactStatus() {
- this.fastify.post<{ Params: { id?: string, name?: string } }>('/v1/statuses/:id/unreact/:name', async (_request, reply) => {
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- if (!_request.params.name) return reply.code(400).send({ error: 'Missing required parameter "name"' });
- const { client, me } = await this.mastodon.getAuthClient(_request);
- const data = await client.deleteEmojiReaction(_request.params.id, _request.params.name);
- reply.send(await this.mastoConverters.convertStatus(data.data, me));
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`POST /v1/statuses/${_request.params.id}/unreact/${_request.params.name}`, data);
- reply.code(401).send(data);
- }
+ fastify.post<{ Params: { id?: string, name?: string } }>('/v1/statuses/:id/unreact/:name', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+ if (!_request.params.name) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "name"' });
+
+ const { client, me } = await this.clientService.getAuthClient(_request);
+ const data = await client.deleteEmojiReaction(_request.params.id, _request.params.name);
+ const response = await this.mastoConverters.convertStatus(data.data, me);
+
+ return reply.send(response);
});
- }
- public deleteStatus() {
- this.fastify.delete<{ Params: { id?: string } }>('/v1/statuses/:id', async (_request, reply) => {
- const BASE_URL = `${_request.protocol}://${_request.host}`;
- const accessTokens = _request.headers.authorization;
- const client = getClient(BASE_URL, accessTokens);
- try {
- if (!_request.params.id) return reply.code(400).send({ error: 'Missing required parameter "id"' });
- const data = await client.deleteStatus(_request.params.id);
- reply.send(data.data);
- } catch (e) {
- const data = getErrorData(e);
- this.logger.error(`DELETE /v1/statuses/${_request.params.id}`, data);
- reply.code(401).send(data);
- }
+ fastify.delete<{ Params: { id?: string } }>('/v1/statuses/:id', async (_request, reply) => {
+ if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
+
+ const client = this.clientService.getClient(_request);
+ const data = await client.deleteStatus(_request.params.id);
+
+ return reply.send(data.data);
});
}
}