summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api
diff options
context:
space:
mode:
authorMarie <marie@kaifa.ch>2023-10-31 12:31:48 +0100
committerGitHub <noreply@github.com>2023-10-31 12:31:48 +0100
commit20ec6300f5f6512be724c72a21475812cb95cdc2 (patch)
tree7fd20b05a42a2d56362221c6cfd8fd20a16599f0 /packages/backend/src/server/api
parentMerge pull request #115 from transfem-org/dependabot/github_actions/actions/s... (diff)
parentchore: remove console log on verify_credentials (diff)
downloadsharkey-20ec6300f5f6512be724c72a21475812cb95cdc2.tar.gz
sharkey-20ec6300f5f6512be724c72a21475812cb95cdc2.tar.bz2
sharkey-20ec6300f5f6512be724c72a21475812cb95cdc2.zip
merge: mastodon api changes (#120)
Diffstat (limited to 'packages/backend/src/server/api')
-rw-r--r--packages/backend/src/server/api/mastodon/MastodonApiServerService.ts156
-rw-r--r--packages/backend/src/server/api/mastodon/converters.ts333
-rw-r--r--packages/backend/src/server/api/mastodon/endpoints/account.ts94
-rw-r--r--packages/backend/src/server/api/mastodon/endpoints/filter.ts8
-rw-r--r--packages/backend/src/server/api/mastodon/endpoints/notifications.ts9
-rw-r--r--packages/backend/src/server/api/mastodon/endpoints/search.ts108
-rw-r--r--packages/backend/src/server/api/mastodon/endpoints/status.ts74
-rw-r--r--packages/backend/src/server/api/mastodon/endpoints/timeline.ts53
8 files changed, 471 insertions, 364 deletions
diff --git a/packages/backend/src/server/api/mastodon/MastodonApiServerService.ts b/packages/backend/src/server/api/mastodon/MastodonApiServerService.ts
index a8c45b98f7..c0e4ea80dc 100644
--- a/packages/backend/src/server/api/mastodon/MastodonApiServerService.ts
+++ b/packages/backend/src/server/api/mastodon/MastodonApiServerService.ts
@@ -3,16 +3,17 @@ import megalodon, { Entity, MegalodonInterface } from 'megalodon';
import querystring from 'querystring';
import { IsNull } from 'typeorm';
import multer from 'fastify-multer';
-import type { NoteEditRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
+import type { AccessTokensRepository, NoteEditRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import type { Config } from '@/config.js';
import { MetaService } from '@/core/MetaService.js';
-import { convertId, IdConvertType as IdType, convertAccount, convertAnnouncement, convertFilter, convertAttachment, convertFeaturedTag, convertList } from './converters.js';
+import { convertAnnouncement, convertFilter, convertAttachment, convertFeaturedTag, convertList, MastoConverters } from './converters.js';
import { getInstance } from './endpoints/meta.js';
import { ApiAuthMastodon, ApiAccountMastodon, ApiFilterMastodon, ApiNotifyMastodon, ApiSearchMastodon, ApiTimelineMastodon, ApiStatusMastodon } from './endpoints.js';
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
+import { DriveService } from '@/core/DriveService.js';
export function getClient(BASE_URL: string, authorization: string | undefined): MegalodonInterface {
const accessTokenArr = authorization?.split(' ') ?? [null];
@@ -33,10 +34,14 @@ export class MastodonApiServerService {
private userProfilesRepository: UserProfilesRepository,
@Inject(DI.noteEditRepository)
private noteEditRepository: NoteEditRepository,
+ @Inject(DI.accessTokensRepository)
+ private accessTokensRepository: AccessTokensRepository,
@Inject(DI.config)
private config: Config,
private metaService: MetaService,
private userEntityService: UserEntityService,
+ private driveService: DriveService,
+ private mastoConverter: MastoConverters,
) { }
@bindThis
@@ -101,8 +106,8 @@ export class MastodonApiServerService {
},
order: { id: 'ASC' },
});
- const contact = admin == null ? null : convertAccount((await client.getAccount(admin.id)).data);
- reply.send(await getInstance(data.data, contact, this.config, await this.metaService.fetch()));
+ const contact = admin == null ? null : await this.mastoConverter.convertAccount((await client.getAccount(admin.id)).data);
+ reply.send(await getInstance(data.data, contact as Entity.Account, this.config, await this.metaService.fetch()));
} catch (e: any) {
/* console.error(e); */
reply.code(401).send(e.response.data);
@@ -128,7 +133,7 @@ export class MastodonApiServerService {
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.dismissInstanceAnnouncement(
- convertId(_request.body['id'], IdType.SharkeyId),
+ _request.body['id'],
);
reply.send(data.data);
} catch (e: any) {
@@ -202,6 +207,25 @@ export class MastodonApiServerService {
}
});
+ fastify.get('/v1/trends/tags', async (_request, reply) => {
+ const BASE_URL = `${_request.protocol}://${_request.hostname}`;
+ const accessTokens = _request.headers.authorization;
+ const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
+ // displayed without being logged in
+ try {
+ const data = await client.getInstanceTrends();
+ reply.send(data.data);
+ } catch (e: any) {
+ /* console.error(e); */
+ reply.code(401).send(e.response.data);
+ }
+ });
+
+ fastify.get('/v1/trends/links', async (_request, reply) => {
+ // As we do not have any system for news/links this will just return empty
+ reply.send([]);
+ });
+
fastify.post('/v1/apps', async (_request, reply) => {
const BASE_URL = `${_request.protocol}://${_request.hostname}`;
const client = getClient(BASE_URL, ''); // we are using this here, because in private mode some info isnt
@@ -236,7 +260,7 @@ export class MastodonApiServerService {
const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
// displayed without being logged in
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.verifyCredentials());
} catch (e: any) {
/* console.error(e); */
@@ -244,16 +268,69 @@ export class MastodonApiServerService {
}
});
- fastify.patch('/v1/accounts/update_credentials', { preHandler: upload.none() }, async (_request, reply) => {
+ fastify.patch('/v1/accounts/update_credentials', { preHandler: upload.any() }, async (_request, reply) => {
const BASE_URL = `${_request.protocol}://${_request.hostname}`;
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
// displayed without being logged in
try {
+ // Check if there is an Header or Avatar being uploaded, if there is proceed to upload it to the drive of the user and then set it.
+ if (_request.files.length > 0 && accessTokens) {
+ const tokeninfo = await this.accessTokensRepository.findOneBy({ token: accessTokens.replace('Bearer ', '') });
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const avatar = (_request.files as any).find((obj: any) => {
+ return obj.fieldname === 'avatar';
+ });
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const header = (_request.files as any).find((obj: any) => {
+ return obj.fieldname === 'header';
+ });
+
+ if (tokeninfo && avatar) {
+ const upload = await this.driveService.addFile({
+ user: { id: tokeninfo.userId, host: null },
+ path: avatar.path,
+ name: avatar.originalname !== null && avatar.originalname !== 'file' ? avatar.originalname : undefined,
+ sensitive: false,
+ });
+ if (upload.type.startsWith('image/')) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (_request.body as any).avatar = upload.id;
+ }
+ } else if (tokeninfo && header) {
+ const upload = await this.driveService.addFile({
+ user: { id: tokeninfo.userId, host: null },
+ path: header.path,
+ name: header.originalname !== null && header.originalname !== 'file' ? header.originalname : undefined,
+ sensitive: false,
+ });
+ if (upload.type.startsWith('image/')) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (_request.body as any).header = upload.id;
+ }
+ }
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ if ((_request.body as any).fields_attributes) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const fields = (_request.body as any).fields_attributes.map((field: any) => {
+ if (!(field.name.trim() === '' && field.value.trim() === '')) {
+ if (field.name.trim() === '') return reply.code(400).send('Field name can not be empty');
+ if (field.value.trim() === '') return reply.code(400).send('Field value can not be empty');
+ }
+ return {
+ ...field,
+ };
+ });
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (_request.body as any).fields_attributes = fields.filter((field: any) => field.name.trim().length > 0 && field.value.length > 0);
+ }
+
const data = await client.updateCredentials(_request.body!);
- reply.send(convertAccount(data.data));
+ reply.send(await this.mastoConverter.convertAccount(data.data));
} catch (e: any) {
- /* console.error(e); */
+ //console.error(e);
reply.code(401).send(e.response.data);
}
});
@@ -267,7 +344,7 @@ export class MastodonApiServerService {
const data = await client.search((_request.query as any).acct, { type: 'accounts' });
const profile = await this.userProfilesRepository.findOneBy({ userId: data.data.accounts[0].id });
data.data.accounts[0].fields = profile?.fields.map(f => ({ ...f, verified_at: null })) || [];
- reply.send(convertAccount(data.data.accounts[0]));
+ reply.send(await this.mastoConverter.convertAccount(data.data.accounts[0]));
} catch (e: any) {
/* console.error(e); */
reply.code(401).send(e.response.data);
@@ -281,12 +358,12 @@ export class MastodonApiServerService {
// displayed without being logged in
let users;
try {
- let ids = _request.query ? (_request.query as any)['id[]'] : null;
+ let ids = _request.query ? (_request.query as any)['id[]'] ?? (_request.query as any)['id'] : null;
if (typeof ids === 'string') {
ids = [ids];
}
users = ids;
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.getRelationships(users));
} catch (e: any) {
/* console.error(e); */
@@ -302,11 +379,10 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const sharkId = convertId(_request.params.id, IdType.SharkeyId);
+ const sharkId = _request.params.id;
const data = await client.getAccount(sharkId);
- const profile = await this.userProfilesRepository.findOneBy({ userId: sharkId });
- data.data.fields = profile?.fields.map(f => ({ ...f, verified_at: null })) || [];
- reply.send(convertAccount(data.data));
+ const account = await this.mastoConverter.convertAccount(data.data);
+ reply.send(account);
} catch (e: any) {
/* console.error(e);
console.error(e.response.data); */
@@ -319,7 +395,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.getStatuses());
} catch (e: any) {
/* console.error(e);
@@ -347,7 +423,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.getFollowers());
} catch (e: any) {
/* console.error(e);
@@ -361,7 +437,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.getFollowing());
} catch (e: any) {
/* console.error(e);
@@ -375,7 +451,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.getAccountLists(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.getAccountLists(_request.params.id);
reply.send(data.data.map((list) => convertList(list)));
} catch (e: any) {
/* console.error(e);
@@ -389,7 +465,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.addFollow());
} catch (e: any) {
/* console.error(e);
@@ -403,7 +479,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.rmFollow());
} catch (e: any) {
/* console.error(e);
@@ -417,7 +493,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.addBlock());
} catch (e: any) {
/* console.error(e);
@@ -431,7 +507,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.rmBlock());
} catch (e: any) {
/* console.error(e);
@@ -445,7 +521,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.addMute());
} catch (e: any) {
/* console.error(e);
@@ -459,7 +535,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.rmMute());
} catch (e: any) {
/* console.error(e);
@@ -487,7 +563,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.getBookmarks());
} catch (e: any) {
/* console.error(e);
@@ -501,7 +577,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.getFavourites());
} catch (e: any) {
/* console.error(e);
@@ -515,7 +591,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.getMutes());
} catch (e: any) {
/* console.error(e);
@@ -529,7 +605,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.getBlocks());
} catch (e: any) {
/* console.error(e);
@@ -544,7 +620,7 @@ export class MastodonApiServerService {
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getFollowRequests( ((_request.query as any) || { limit: 20 }).limit );
- reply.send(data.data.map((account) => convertAccount(account as Entity.Account)));
+ reply.send(await Promise.all(data.data.map(async (account) => await this.mastoConverter.convertAccount(account as Entity.Account))));
} catch (e: any) {
/* console.error(e);
console.error(e.response.data); */
@@ -557,7 +633,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.acceptFollow());
} catch (e: any) {
/* console.error(e);
@@ -571,7 +647,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const account = new ApiAccountMastodon(_request, client, BASE_URL);
+ const account = new ApiAccountMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await account.rejectFollow());
} catch (e: any) {
/* console.error(e);
@@ -587,7 +663,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const search = new ApiSearchMastodon(_request, client, BASE_URL);
+ const search = new ApiSearchMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await search.SearchV1());
} catch (e: any) {
/* console.error(e);
@@ -601,7 +677,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const search = new ApiSearchMastodon(_request, client, BASE_URL);
+ const search = new ApiSearchMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await search.SearchV2());
} catch (e: any) {
/* console.error(e);
@@ -615,7 +691,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const search = new ApiSearchMastodon(_request, client, BASE_URL);
+ const search = new ApiSearchMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await search.getStatusTrends());
} catch (e: any) {
/* console.error(e);
@@ -629,7 +705,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const search = new ApiSearchMastodon(_request, client, BASE_URL);
+ const search = new ApiSearchMastodon(_request, client, BASE_URL, this.mastoConverter);
reply.send(await search.getSuggestions());
} catch (e: any) {
/* console.error(e);
@@ -756,7 +832,7 @@ export class MastodonApiServerService {
//#endregion
//#region Timelines
- const TLEndpoint = new ApiTimelineMastodon(fastify, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
+ const TLEndpoint = new ApiTimelineMastodon(fastify, this.config, this.mastoConverter);
// GET Endpoints
TLEndpoint.getTL();
@@ -781,7 +857,7 @@ export class MastodonApiServerService {
//#endregion
//#region Status
- const NoteEndpoint = new ApiStatusMastodon(fastify, this.config, this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
+ const NoteEndpoint = new ApiStatusMastodon(fastify, this.mastoConverter);
// GET Endpoints
NoteEndpoint.getStatus();
@@ -813,7 +889,7 @@ export class MastodonApiServerService {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.updateMedia(convertId(_request.params.id, IdType.SharkeyId), _request.body!);
+ const data = await client.updateMedia(_request.params.id, _request.body!);
reply.send(convertAttachment(data.data));
} catch (e: any) {
/* console.error(e); */
diff --git a/packages/backend/src/server/api/mastodon/converters.ts b/packages/backend/src/server/api/mastodon/converters.ts
index cbd2550f92..0383191399 100644
--- a/packages/backend/src/server/api/mastodon/converters.ts
+++ b/packages/backend/src/server/api/mastodon/converters.ts
@@ -1,16 +1,17 @@
-import type { Config } from '@/config.js';
-import { MfmService } from '@/core/MfmService.js';
-import { DI } from '@/di-symbols.js';
-import { Inject } from '@nestjs/common';
+import { Inject, Injectable } from '@nestjs/common';
import { Entity } from 'megalodon';
-import { parse } from 'mfm-js';
-import { GetterService } from '../GetterService.js';
+import mfm from 'mfm-js';
+import { DI } from '@/di-symbols.js';
+import { MfmService } from '@/core/MfmService.js';
+import type { Config } from '@/config.js';
import type { IMentionedRemoteUsers } from '@/models/Note.js';
import type { MiUser } from '@/models/User.js';
-import type { NoteEditRepository, NotesRepository, UsersRepository } from '@/models/_.js';
-import { UserEntityService } from '@/core/entities/UserEntityService.js';
-
-const CHAR_COLLECTION = '0123456789abcdefghijklmnopqrstuvwxyz';
+import type { NoteEditRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
+import { awaitAll } from '@/misc/prelude/await-all.js';
+import { CustomEmojiService } from '@/core/CustomEmojiService.js';
+import { GetterService } from '../GetterService.js';
+import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
+import { IdService } from '@/core/IdService.js';
export enum IdConvertType {
MastodonId,
@@ -18,18 +19,16 @@ export enum IdConvertType {
}
export const escapeMFM = (text: string): string => text
- .replace(/&/g, "&amp;")
- .replace(/</g, "&lt;")
- .replace(/>/g, "&gt;")
- .replace(/"/g, "&quot;")
- .replace(/'/g, "&#39;")
- .replace(/`/g, "&#x60;")
- .replace(/\r?\n/g, "<br>");
+ .replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;')
+ .replace(/'/g, '&#39;')
+ .replace(/`/g, '&#x60;')
+ .replace(/\r?\n/g, '<br>');
+@Injectable()
export class MastoConverters {
- private MfmService: MfmService;
- private GetterService: GetterService;
-
constructor(
@Inject(DI.config)
private config: Config,
@@ -37,19 +36,21 @@ export class MastoConverters {
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
- @Inject(DI.notesRepository)
- private notesRepository: NotesRepository,
+ @Inject(DI.userProfilesRepository)
+ private userProfilesRepository: UserProfilesRepository,
@Inject(DI.noteEditRepository)
private noteEditRepository: NoteEditRepository,
-
- private userEntityService: UserEntityService
+
+ private mfmService: MfmService,
+ private getterService: GetterService,
+ private customEmojiService: CustomEmojiService,
+ private idService: IdService,
+ private driveFileEntityService: DriveFileEntityService,
) {
- this.MfmService = new MfmService(this.config);
- this.GetterService = new GetterService(this.usersRepository, this.notesRepository, this.noteEditRepository, this.userEntityService);
}
- private encode(u: MiUser, m: IMentionedRemoteUsers): MastodonEntity.Mention {
+ private encode(u: MiUser, m: IMentionedRemoteUsers): Entity.Mention {
let acct = u.username;
let acctUrl = `https://${u.host || this.config.host}/@${u.username}`;
let url: string | null = null;
@@ -67,95 +68,223 @@ export class MastoConverters {
};
}
+ public fileType(s: string): 'unknown' | 'image' | 'gifv' | 'video' | 'audio' {
+ if (s === 'image/gif') {
+ return 'gifv';
+ }
+ if (s.includes('image')) {
+ return 'image';
+ }
+ if (s.includes('video')) {
+ return 'video';
+ }
+ if (s.includes('audio')) {
+ return 'audio';
+ }
+ return 'unknown';
+ }
+
+ public encodeFile(f: any): Entity.Attachment {
+ return {
+ id: f.id,
+ type: this.fileType(f.type),
+ url: f.url,
+ remote_url: f.url,
+ preview_url: f.thumbnailUrl,
+ text_url: f.url,
+ meta: {
+ width: f.properties.width,
+ height: f.properties.height
+ },
+ description: f.comment ? f.comment : null,
+ blurhash: f.blurhash ? f.blurhash : null
+ };
+ }
+
public async getUser(id: string): Promise<MiUser> {
- return this.GetterService.getUser(id).then(p => {
+ return this.getterService.getUser(id).then(p => {
return p;
});
}
- public async convertStatus(status: Entity.Status) {
- status.account = convertAccount(status.account);
- const note = await this.GetterService.getNote(status.id);
- status.id = convertId(status.id, IdConvertType.MastodonId);
- if (status.in_reply_to_account_id) status.in_reply_to_account_id = convertId(
- status.in_reply_to_account_id,
- IdConvertType.MastodonId,
- );
- if (status.in_reply_to_id) status.in_reply_to_id = convertId(status.in_reply_to_id, IdConvertType.MastodonId);
- status.media_attachments = status.media_attachments.map((attachment) =>
- convertAttachment(attachment),
- );
- // This will eventually be improved with a rewrite of this file
- const mentions = Promise.all(note.mentions.map(p =>
- this.getUser(p)
- .then(u => this.encode(u, JSON.parse(note.mentionedRemoteUsers)))
- .catch(() => null)))
- .then(p => p.filter(m => m)) as Promise<MastodonEntity.Mention[]>;
- status.mentions = await mentions;
- status.mentions = status.mentions.map((mention) => ({
- ...mention,
- id: convertId(mention.id, IdConvertType.MastodonId),
- }));
- const convertedMFM = this.MfmService.toHtml(parse(status.content), JSON.parse(note.mentionedRemoteUsers));
- status.content = status.content ? convertedMFM?.replace(/&amp;/g, "&").replaceAll(`<span>&</span><a href="${this.config.url}/tags/39;" rel="tag">#39;</a>`, "<span>\'</span>") as string : status.content;
- if (status.poll) status.poll = convertPoll(status.poll);
- if (status.reblog) status.reblog = convertStatus(status.reblog);
-
- return status;
+ private async encodeField(f: Entity.Field): Promise<Entity.Field> {
+ return {
+ name: f.name,
+ value: await this.mfmService.toMastoHtml(mfm.parse(f.value), [], true) ?? escapeMFM(f.value),
+ verified_at: null,
+ };
}
-}
-export function convertId(in_id: string, id_convert_type: IdConvertType): string {
- switch (id_convert_type) {
- case IdConvertType.MastodonId: {
- let out = BigInt(0);
- const lowerCaseId = in_id.toLowerCase();
- for (let i = 0; i < lowerCaseId.length; i++) {
- const charValue = numFromChar(lowerCaseId.charAt(i));
- out += BigInt(charValue) * BigInt(36) ** BigInt(i);
- }
- return out.toString();
- }
-
- case IdConvertType.SharkeyId: {
- let input = BigInt(in_id);
- let outStr = '';
- while (input > BigInt(0)) {
- const remainder = Number(input % BigInt(36));
- outStr = charFromNum(remainder) + outStr;
- input /= BigInt(36);
- }
- const ReversedoutStr = outStr.split('').reduce((acc, char) => char + acc, '');
- return ReversedoutStr;
+ public async convertAccount(account: Entity.Account | MiUser) {
+ const user = await this.getUser(account.id);
+ const profile = await this.userProfilesRepository.findOneBy({ userId: user.id });
+ const emojis = await this.customEmojiService.populateEmojis(user.emojis, user.host ? user.host : this.config.host);
+ const emoji: Entity.Emoji[] = [];
+ Object.entries(emojis).forEach(entry => {
+ const [key, value] = entry;
+ emoji.push({
+ shortcode: key,
+ static_url: value,
+ url: value,
+ visible_in_picker: true,
+ category: undefined,
+ });
+ });
+ const fqn = `${user.username}@${user.host ?? this.config.hostname}`;
+ let acct = user.username;
+ let acctUrl = `https://${user.host || this.config.host}/@${user.username}`;
+ if (user.host) {
+ acct = `${user.username}@${user.host}`;
+ acctUrl = `https://${user.host}/@${user.username}`;
}
-
- default:
- throw new Error('Invalid ID conversion type');
+ return awaitAll({
+ id: account.id,
+ username: user.username,
+ acct: acct,
+ fqn: fqn,
+ display_name: user.name ?? user.username,
+ locked: user.isLocked,
+ created_at: this.idService.parse(user.id).date.toISOString(),
+ followers_count: user.followersCount,
+ following_count: user.followingCount,
+ statuses_count: user.notesCount,
+ note: profile?.description ?? '',
+ url: user.uri ?? acctUrl,
+ avatar: user.avatarUrl ? user.avatarUrl : 'https://dev.joinsharkey.org/static-assets/avatar.png',
+ avatar_static: user.avatarUrl ? user.avatarUrl : 'https://dev.joinsharkey.org/static-assets/avatar.png',
+ header: user.bannerUrl ? user.bannerUrl : 'https://dev.joinsharkey.org/static-assets/transparent.png',
+ header_static: user.bannerUrl ? user.bannerUrl : 'https://dev.joinsharkey.org/static-assets/transparent.png',
+ emojis: emoji,
+ moved: null, //FIXME
+ fields: Promise.all(profile?.fields.map(async p => this.encodeField(p)) ?? []),
+ bot: user.isBot,
+ discoverable: user.isExplorable,
+ });
}
-}
-function numFromChar(character: string): number {
- for (let i = 0; i < CHAR_COLLECTION.length; i++) {
- if (CHAR_COLLECTION.charAt(i) === character) {
- return i;
+ public async getEdits(id: string) {
+ const note = await this.getterService.getNote(id);
+ if (!note) {
+ return {};
+ }
+
+ const noteUser = await this.getUser(note.userId).then(async (p) => await this.convertAccount(p));
+ const edits = await this.noteEditRepository.find({ where: { noteId: note.id }, order: { id: 'ASC' } });
+ const history: Promise<any>[] = [];
+
+ let lastDate = this.idService.parse(note.id).date;
+ for (const edit of edits) {
+ const files = this.driveFileEntityService.packManyByIds(edit.fileIds);
+ const item = {
+ account: noteUser,
+ content: this.mfmService.toMastoHtml(mfm.parse(edit.newText ?? ''), JSON.parse(note.mentionedRemoteUsers)).then(p => p ?? ''),
+ created_at: lastDate.toISOString(),
+ emojis: [],
+ sensitive: files.then(files => files.length > 0 ? files.some((f) => f.isSensitive) : false),
+ spoiler_text: edit.cw ?? '',
+ poll: null,
+ media_attachments: files.then(files => files.length > 0 ? files.map((f) => this.encodeFile(f)) : [])
+ };
+ lastDate = edit.updatedAt;
+ history.push(awaitAll(item));
}
+
+ return await Promise.all(history);
}
- throw new Error('Invalid character in parsed base36 id');
-}
+ private async convertReblog(status: Entity.Status | null): Promise<any> {
+ if (!status) return null;
+ return await this.convertStatus(status);
+ }
+
+ public async convertStatus(status: Entity.Status) {
+ const convertedAccount = this.convertAccount(status.account);
+ const note = await this.getterService.getNote(status.id);
+ const noteUser = await this.getUser(status.account.id);
+
+ const emojis = await this.customEmojiService.populateEmojis(note.emojis, noteUser.host ? noteUser.host : this.config.host);
+ const emoji: Entity.Emoji[] = [];
+ Object.entries(emojis).forEach(entry => {
+ const [key, value] = entry;
+ emoji.push({
+ shortcode: key,
+ static_url: value,
+ url: value,
+ visible_in_picker: true,
+ category: undefined,
+ });
+ });
-function charFromNum(number: number): string {
- if (number >= 0 && number < CHAR_COLLECTION.length) {
- return CHAR_COLLECTION.charAt(number);
- } else {
- throw new Error('Invalid number for base-36 encoding');
+ const mentions = Promise.all(note.mentions.map(p =>
+ this.getUser(p)
+ .then(u => this.encode(u, JSON.parse(note.mentionedRemoteUsers)))
+ .catch(() => null)))
+ .then(p => p.filter(m => m)) as Promise<Entity.Mention[]>;
+
+ const tags = note.tags.map(tag => {
+ return {
+ name: tag,
+ url: `${this.config.url}/tags/${tag}`,
+ } as Entity.Tag;
+ });
+
+ const isQuote = note.renoteId && note.text ? true : false;
+
+ const renote = note.renoteId ? this.getterService.getNote(note.renoteId) : null;
+
+ const quoteUri = Promise.resolve(renote).then(renote => {
+ if (!renote || !isQuote) return null;
+ return renote.url ?? renote.uri ?? `${this.config.url}/notes/${renote.id}`;
+ });
+
+ const content = note.text !== null
+ ? quoteUri.then(quoteUri => this.mfmService.toMastoHtml(mfm.parse(note.text!), JSON.parse(note.mentionedRemoteUsers), false, quoteUri))
+ .then(p => p ?? escapeMFM(note.text!))
+ : '';
+
+ // noinspection ES6MissingAwait
+ return await awaitAll({
+ id: note.id,
+ uri: note.uri ?? `https://${this.config.host}/notes/${note.id}`,
+ url: note.url ?? note.uri ?? `https://${this.config.host}/notes/${note.id}`,
+ account: convertedAccount,
+ in_reply_to_id: note.replyId,
+ in_reply_to_account_id: note.replyUserId,
+ reblog: !isQuote ? await this.convertReblog(status.reblog) : null,
+ content: content,
+ content_type: 'text/x.misskeymarkdown',
+ text: note.text,
+ created_at: status.created_at,
+ emojis: emoji,
+ replies_count: note.repliesCount,
+ reblogs_count: note.renoteCount,
+ favourites_count: status.favourites_count,
+ reblogged: false,
+ favourited: status.favourited,
+ muted: status.muted,
+ sensitive: status.sensitive,
+ spoiler_text: note.cw ? note.cw : '',
+ visibility: status.visibility,
+ media_attachments: status.media_attachments,
+ mentions: mentions,
+ tags: tags,
+ card: null, //FIXME
+ poll: status.poll ?? null,
+ application: null, //FIXME
+ language: null, //FIXME
+ pinned: null,
+ reactions: status.emoji_reactions,
+ emoji_reactions: status.emoji_reactions,
+ bookmarked: false,
+ quote: isQuote ? await this.convertReblog(status.reblog) : null,
+ edited_at: note.updatedAt?.toISOString(),
+ });
}
}
function simpleConvert(data: any) {
// copy the object to bypass weird pass by reference bugs
const result = Object.assign({}, data);
- result.id = convertId(data.id, IdConvertType.MastodonId);
return result;
}
@@ -180,7 +309,6 @@ export function convertFeaturedTag(tag: Entity.FeaturedTag) {
export function convertNotification(notification: Entity.Notification) {
notification.account = convertAccount(notification.account);
- notification.id = convertId(notification.id, IdConvertType.MastodonId);
if (notification.status) notification.status = convertStatus(notification.status);
return notification;
}
@@ -200,19 +328,9 @@ export function convertRelationship(relationship: Entity.Relationship) {
export function convertStatus(status: Entity.Status) {
status.account = convertAccount(status.account);
- status.id = convertId(status.id, IdConvertType.MastodonId);
- if (status.in_reply_to_account_id) status.in_reply_to_account_id = convertId(
- status.in_reply_to_account_id,
- IdConvertType.MastodonId,
- );
- if (status.in_reply_to_id) status.in_reply_to_id = convertId(status.in_reply_to_id, IdConvertType.MastodonId);
status.media_attachments = status.media_attachments.map((attachment) =>
convertAttachment(attachment),
);
- status.mentions = status.mentions.map((mention) => ({
- ...mention,
- id: convertId(mention.id, IdConvertType.MastodonId),
- }));
if (status.poll) status.poll = convertPoll(status.poll);
if (status.reblog) status.reblog = convertStatus(status.reblog);
@@ -224,7 +342,6 @@ export function convertStatusSource(status: Entity.StatusSource) {
}
export function convertConversation(conversation: Entity.Conversation) {
- conversation.id = convertId(conversation.id, IdConvertType.MastodonId);
conversation.accounts = conversation.accounts.map(convertAccount);
if (conversation.last_status) {
conversation.last_status = convertStatus(conversation.last_status);
diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts
index 24ebe0c48b..07d9efb8c1 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/account.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts
@@ -1,7 +1,11 @@
-import { convertId, IdConvertType as IdType, convertAccount, convertRelationship, convertStatus } from '../converters.js';
-import { argsToBools, convertTimelinesArgsId, limitToInt } from './timeline.js';
+import { MastoConverters, convertRelationship } from '../converters.js';
+import { argsToBools, limitToInt } from './timeline.js';
import type { MegalodonInterface } from 'megalodon';
import type { FastifyRequest } from 'fastify';
+import { NoteEditRepository, NotesRepository, UsersRepository } from '@/models/_.js';
+import { UserEntityService } from '@/core/entities/UserEntityService.js';
+import type { Config } from '@/config.js';
+import { Injectable } from '@nestjs/common';
const relationshipModel = {
id: '',
@@ -20,12 +24,13 @@ const relationshipModel = {
note: '',
};
+@Injectable()
export class ApiAccountMastodon {
private request: FastifyRequest;
private client: MegalodonInterface;
private BASE_URL: string;
- constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string) {
+ constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string, private mastoconverter: MastoConverters) {
this.request = request;
this.client = client;
this.BASE_URL = BASE_URL;
@@ -34,23 +39,17 @@ export class ApiAccountMastodon {
public async verifyCredentials() {
try {
const data = await this.client.verifyAccountCredentials();
- const acct = data.data;
- acct.id = convertId(acct.id, IdType.MastodonId);
- acct.display_name = acct.display_name || acct.username;
- acct.url = `${this.BASE_URL}/@${acct.url}`;
- acct.note = acct.note || '';
- acct.avatar_static = acct.avatar;
- acct.header = acct.header || '/static-assets/transparent.png';
- acct.header_static = acct.header || '/static-assets/transparent.png';
- acct.source = {
- note: acct.note,
- fields: acct.fields,
- privacy: '',
- sensitive: false,
- language: '',
- };
- console.log(acct);
- return acct;
+ const acct = await this.mastoconverter.convertAccount(data.data);
+ const newAcct = Object.assign({}, acct, {
+ source: {
+ note: acct.note,
+ fields: acct.fields,
+ privacy: '',
+ sensitive: false,
+ language: '',
+ },
+ });
+ return newAcct;
} catch (e: any) {
/* console.error(e);
console.error(e.response.data); */
@@ -61,7 +60,7 @@ export class ApiAccountMastodon {
public async lookup() {
try {
const data = await this.client.search((this.request.query as any).acct, { type: 'accounts' });
- return convertAccount(data.data.accounts[0]);
+ return this.mastoconverter.convertAccount(data.data.accounts[0]);
} catch (e: any) {
/* console.error(e)
console.error(e.response.data); */
@@ -79,7 +78,7 @@ export class ApiAccountMastodon {
const reqIds = [];
for (let i = 0; i < users.length; i++) {
- reqIds.push(convertId(users[i], IdType.SharkeyId));
+ reqIds.push(users[i]);
}
const data = await this.client.getRelationships(reqIds);
@@ -93,11 +92,8 @@ export class ApiAccountMastodon {
public async getStatuses() {
try {
- const data = await this.client.getAccountStatuses(
- convertId((this.request.params as any).id, IdType.SharkeyId),
- convertTimelinesArgsId(argsToBools(limitToInt(this.request.query as any)))
- );
- return data.data.map((status) => convertStatus(status));
+ const data = await this.client.getAccountStatuses((this.request.params as any).id, argsToBools(limitToInt(this.request.query as any)));
+ return await Promise.all(data.data.map(async (status) => await this.mastoconverter.convertStatus(status)));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@@ -108,10 +104,10 @@ export class ApiAccountMastodon {
public async getFollowers() {
try {
const data = await this.client.getAccountFollowers(
- convertId((this.request.params as any).id, IdType.SharkeyId),
- convertTimelinesArgsId(limitToInt(this.request.query as any)),
+ (this.request.params as any).id,
+ limitToInt(this.request.query as any),
);
- return data.data.map((account) => convertAccount(account));
+ return await Promise.all(data.data.map(async (account) => await this.mastoconverter.convertAccount(account)));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@@ -122,10 +118,10 @@ export class ApiAccountMastodon {
public async getFollowing() {
try {
const data = await this.client.getAccountFollowing(
- convertId((this.request.params as any).id, IdType.SharkeyId),
- convertTimelinesArgsId(limitToInt(this.request.query as any)),
+ (this.request.params as any).id,
+ limitToInt(this.request.query as any),
);
- return data.data.map((account) => convertAccount(account));
+ return await Promise.all(data.data.map(async (account) => await this.mastoconverter.convertAccount(account)));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@@ -135,7 +131,7 @@ export class ApiAccountMastodon {
public async addFollow() {
try {
- const data = await this.client.followAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.followAccount( (this.request.params as any).id );
const acct = convertRelationship(data.data);
acct.following = true;
return acct;
@@ -148,7 +144,7 @@ export class ApiAccountMastodon {
public async rmFollow() {
try {
- const data = await this.client.unfollowAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.unfollowAccount( (this.request.params as any).id );
const acct = convertRelationship(data.data);
acct.following = false;
return acct;
@@ -161,7 +157,7 @@ export class ApiAccountMastodon {
public async addBlock() {
try {
- const data = await this.client.blockAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.blockAccount( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
@@ -172,7 +168,7 @@ export class ApiAccountMastodon {
public async rmBlock() {
try {
- const data = await this.client.unblockAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.unblockAccount( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
@@ -184,7 +180,7 @@ export class ApiAccountMastodon {
public async addMute() {
try {
const data = await this.client.muteAccount(
- convertId((this.request.params as any).id, IdType.SharkeyId),
+ (this.request.params as any).id,
this.request.body as any,
);
return convertRelationship(data.data);
@@ -197,7 +193,7 @@ export class ApiAccountMastodon {
public async rmMute() {
try {
- const data = await this.client.unmuteAccount( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.unmuteAccount( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
@@ -208,8 +204,8 @@ export class ApiAccountMastodon {
public async getBookmarks() {
try {
- const data = await this.client.getBookmarks( convertTimelinesArgsId(limitToInt(this.request.query as any)) );
- return data.data.map((status) => convertStatus(status));
+ const data = await this.client.getBookmarks( limitToInt(this.request.query as any) );
+ return data.data.map((status) => this.mastoconverter.convertStatus(status));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@@ -219,8 +215,8 @@ export class ApiAccountMastodon {
public async getFavourites() {
try {
- const data = await this.client.getFavourites( convertTimelinesArgsId(limitToInt(this.request.query as any)) );
- return data.data.map((status) => convertStatus(status));
+ const data = await this.client.getFavourites( limitToInt(this.request.query as any) );
+ return data.data.map((status) => this.mastoconverter.convertStatus(status));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@@ -230,8 +226,8 @@ export class ApiAccountMastodon {
public async getMutes() {
try {
- const data = await this.client.getMutes( convertTimelinesArgsId(limitToInt(this.request.query as any)) );
- return data.data.map((account) => convertAccount(account));
+ const data = await this.client.getMutes( limitToInt(this.request.query as any) );
+ return data.data.map((account) => this.mastoconverter.convertAccount(account));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@@ -241,8 +237,8 @@ export class ApiAccountMastodon {
public async getBlocks() {
try {
- const data = await this.client.getBlocks( convertTimelinesArgsId(limitToInt(this.request.query as any)) );
- return data.data.map((account) => convertAccount(account));
+ const data = await this.client.getBlocks( limitToInt(this.request.query as any) );
+ return data.data.map((account) => this.mastoconverter.convertAccount(account));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@@ -252,7 +248,7 @@ export class ApiAccountMastodon {
public async acceptFollow() {
try {
- const data = await this.client.acceptFollowRequest( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.acceptFollowRequest( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
@@ -263,7 +259,7 @@ export class ApiAccountMastodon {
public async rejectFollow() {
try {
- const data = await this.client.rejectFollowRequest( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.rejectFollowRequest( (this.request.params as any).id );
return convertRelationship(data.data);
} catch (e: any) {
console.error(e);
diff --git a/packages/backend/src/server/api/mastodon/endpoints/filter.ts b/packages/backend/src/server/api/mastodon/endpoints/filter.ts
index e27bc956fa..212c79b251 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/filter.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/filter.ts
@@ -1,4 +1,4 @@
-import { IdConvertType as IdType, convertId, convertFilter } from '../converters.js';
+import { convertFilter } from '../converters.js';
import type { MegalodonInterface } from 'megalodon';
import type { FastifyRequest } from 'fastify';
@@ -23,7 +23,7 @@ export class ApiFilterMastodon {
public async getFilter() {
try {
- const data = await this.client.getFilter( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.getFilter( (this.request.params as any).id );
return convertFilter(data.data);
} catch (e: any) {
console.error(e);
@@ -45,7 +45,7 @@ export class ApiFilterMastodon {
public async updateFilter() {
try {
const body: any = this.request.body;
- const data = await this.client.updateFilter(convertId((this.request.params as any).id, IdType.SharkeyId), body.pharse, body.context);
+ const data = await this.client.updateFilter((this.request.params as any).id, body.pharse, body.context);
return convertFilter(data.data);
} catch (e: any) {
console.error(e);
@@ -55,7 +55,7 @@ export class ApiFilterMastodon {
public async rmFilter() {
try {
- const data = await this.client.deleteFilter( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.deleteFilter( (this.request.params as any).id );
return data.data;
} catch (e: any) {
console.error(e);
diff --git a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts
index dc801dd053..c4628b58c4 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts
@@ -1,5 +1,4 @@
-import { IdConvertType as IdType, convertId, convertNotification } from '../converters.js';
-import { convertTimelinesArgsId } from './timeline.js';
+import { convertNotification } from '../converters.js';
import type { MegalodonInterface, Entity } from 'megalodon';
import type { FastifyRequest } from 'fastify';
@@ -19,7 +18,7 @@ export class ApiNotifyMastodon {
public async getNotifications() {
try {
- const data = await this.client.getNotifications( convertTimelinesArgsId(toLimitToInt(this.request.query)) );
+ const data = await this.client.getNotifications( toLimitToInt(this.request.query) );
const notifs = data.data;
const processed = notifs.map((n: Entity.Notification) => {
const convertedn = convertNotification(n);
@@ -39,7 +38,7 @@ export class ApiNotifyMastodon {
public async getNotification() {
try {
- const data = await this.client.getNotification( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.getNotification( (this.request.params as any).id );
const notif = convertNotification(data.data);
if (notif.type !== 'follow' && notif.type !== 'follow_request' && notif.type === 'reaction') notif.type = 'favourite';
return notif;
@@ -51,7 +50,7 @@ export class ApiNotifyMastodon {
public async rmNotification() {
try {
- const data = await this.client.dismissNotification( convertId((this.request.params as any).id, IdType.SharkeyId) );
+ const data = await this.client.dismissNotification( (this.request.params as any).id );
return data.data;
} catch (e: any) {
console.error(e);
diff --git a/packages/backend/src/server/api/mastodon/endpoints/search.ts b/packages/backend/src/server/api/mastodon/endpoints/search.ts
index 5c68402ed8..500129c901 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/search.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/search.ts
@@ -1,69 +1,14 @@
-import { Converter } from 'megalodon';
-import { convertAccount, convertStatus } from '../converters.js';
-import { convertTimelinesArgsId, limitToInt } from './timeline.js';
+import { MastoConverters } from '../converters.js';
+import { limitToInt } from './timeline.js';
import type { MegalodonInterface } from 'megalodon';
import type { FastifyRequest } from 'fastify';
-async function getHighlight(
- BASE_URL: string,
- domain: string,
- accessTokens: string | undefined,
-) {
- const accessTokenArr = accessTokens?.split(' ') ?? [null];
- const accessToken = accessTokenArr[accessTokenArr.length - 1];
- try {
- const apicall = await fetch(`${BASE_URL}/api/notes/featured`,
- {
- method: 'POST',
- headers: {
- 'Accept': 'application/json, text/plain, */*',
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ i: accessToken }),
- });
- const api = await apicall.json();
- const data: MisskeyEntity.Note[] = api;
- return data.map((note) => Converter.note(note, domain));
- } catch (e: any) {
- console.log(e);
- console.log(e.response.data);
- return [];
- }
-}
-
-async function getFeaturedUser( BASE_URL: string, host: string, accessTokens: string | undefined, limit: number ) {
- const accessTokenArr = accessTokens?.split(' ') ?? [null];
- const accessToken = accessTokenArr[accessTokenArr.length - 1];
- try {
- const apicall = await fetch(`${BASE_URL}/api/users`,
- {
- method: 'POST',
- headers: {
- 'Accept': 'application/json, text/plain, */*',
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ i: accessToken, limit, origin: 'local', sort: '+follower', state: 'alive' }),
- });
- const api = await apicall.json();
- const data: MisskeyEntity.UserDetail[] = api;
- return data.map((u) => {
- return {
- source: 'past_interactions',
- account: Converter.userDetail(u, host),
- };
- });
- } catch (e: any) {
- console.log(e);
- console.log(e.response.data);
- return [];
- }
-}
export class ApiSearchMastodon {
private request: FastifyRequest;
private client: MegalodonInterface;
private BASE_URL: string;
- constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string) {
+ constructor(request: FastifyRequest, client: MegalodonInterface, BASE_URL: string, private mastoConverter: MastoConverters) {
this.request = request;
this.client = client;
this.BASE_URL = BASE_URL;
@@ -71,7 +16,7 @@ export class ApiSearchMastodon {
public async SearchV1() {
try {
- const query: any = convertTimelinesArgsId(limitToInt(this.request.query as any));
+ const query: any = limitToInt(this.request.query as any);
const type = query.type || '';
const data = await this.client.search(query.q, { type: type, ...query });
return data.data;
@@ -83,14 +28,14 @@ export class ApiSearchMastodon {
public async SearchV2() {
try {
- const query: any = convertTimelinesArgsId(limitToInt(this.request.query as any));
+ const query: any = limitToInt(this.request.query as any);
const type = query.type;
const acct = !type || type === 'accounts' ? await this.client.search(query.q, { type: 'accounts', ...query }) : null;
const stat = !type || type === 'statuses' ? await this.client.search(query.q, { type: 'statuses', ...query }) : null;
const tags = !type || type === 'hashtags' ? await this.client.search(query.q, { type: 'hashtags', ...query }) : null;
const data = {
- accounts: acct?.data.accounts.map((account) => convertAccount(account)) ?? [],
- statuses: stat?.data.statuses.map((status) => convertStatus(status)) ?? [],
+ accounts: await Promise.all(acct?.data.accounts.map(async (account: any) => await this.mastoConverter.convertAccount(account)) ?? []),
+ statuses: await Promise.all(stat?.data.statuses.map(async (status: any) => await this.mastoConverter.convertStatus(status)) ?? []),
hashtags: tags?.data.hashtags ?? [],
};
return data;
@@ -102,30 +47,39 @@ export class ApiSearchMastodon {
public async getStatusTrends() {
try {
- const data = await getHighlight(
- this.BASE_URL,
- this.request.hostname,
- this.request.headers.authorization,
- );
- return data.map((status) => convertStatus(status));
+ const data = await fetch(`${this.BASE_URL}/api/notes/featured`,
+ {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({}),
+ })
+ .then(res => res.json())
+ .then(data => data.map((status: any) => this.mastoConverter.convertStatus(status)));
+ return data;
} catch (e: any) {
console.error(e);
- return e.response.data;
+ return [];
}
}
public async getSuggestions() {
try {
- const data = await getFeaturedUser(
- this.BASE_URL,
- this.request.hostname,
- this.request.headers.authorization,
- (this.request.query as any).limit || 20,
- );
- return data.map((suggestion) => { suggestion.account = convertAccount(suggestion.account); return suggestion; });
+ const data = await fetch(`${this.BASE_URL}/api/users`,
+ {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ i: this.request.headers.authorization?.replace('Bearer ', ''), limit: parseInt((this.request.query as any).limit) || 20, origin: 'local', sort: '+follower', state: 'alive' }),
+ }).then((res) => res.json()).then(data => data.map(((entry: any) => { return { source: 'global', account: entry }; })));
+ return Promise.all(data.map(async (suggestion: any) => { suggestion.account = await this.mastoConverter.convertAccount(suggestion.account); return suggestion; }));
} catch (e: any) {
console.error(e);
- return e.response.data;
+ return [];
}
}
}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts
index 2690a1036f..fe77646af4 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/status.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts
@@ -1,8 +1,8 @@
import querystring from 'querystring';
import { emojiRegexAtStartToEnd } from '@/misc/emoji-regex.js';
-import { convertId, IdConvertType as IdType, convertAccount, convertAttachment, convertPoll, convertStatusSource, MastoConverters } from '../converters.js';
+import { convertAttachment, convertPoll, convertStatusSource, MastoConverters } from '../converters.js';
import { getClient } from '../MastodonApiServerService.js';
-import { convertTimelinesArgsId, limitToInt } from './timeline.js';
+import { limitToInt } from './timeline.js';
import type { Entity } from 'megalodon';
import type { FastifyInstance } from 'fastify';
import type { Config } from '@/config.js';
@@ -18,9 +18,9 @@ export class ApiStatusMastodon {
private fastify: FastifyInstance;
private mastoconverter: MastoConverters;
- constructor(fastify: FastifyInstance, config: Config, usersrepo: UsersRepository, notesrepo: NotesRepository, noteeditrepo: NoteEditRepository, userentity: UserEntityService) {
+ constructor(fastify: FastifyInstance, mastoconverter: MastoConverters) {
this.fastify = fastify;
- this.mastoconverter = new MastoConverters(config, usersrepo, notesrepo, noteeditrepo, userentity);
+ this.mastoconverter = mastoconverter;
}
public async getStatus() {
@@ -29,7 +29,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.getStatus(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.getStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -44,8 +44,8 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.getStatusSource(convertId(_request.params.id, IdType.SharkeyId));
- reply.send(convertStatusSource(data.data));
+ const data = await client.getStatusSource(_request.params.id);
+ reply.send(data.data);
} catch (e: any) {
console.error(e);
reply.code(_request.is404 ? 404 : 401).send(e.response.data);
@@ -60,10 +60,7 @@ export class ApiStatusMastodon {
const client = getClient(BASE_URL, accessTokens);
const query: any = _request.query;
try {
- const data = await client.getStatusContext(
- convertId(_request.params.id, IdType.SharkeyId),
- convertTimelinesArgsId(limitToInt(query)),
- );
+ const data = await client.getStatusContext(_request.params.id, limitToInt(query));
data.data.ancestors = await Promise.all(data.data.ancestors.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status)));
data.data.descendants = await Promise.all(data.data.descendants.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status)));
reply.send(data.data);
@@ -77,7 +74,8 @@ export class ApiStatusMastodon {
public async getHistory() {
this.fastify.get<{ Params: { id: string } }>('/v1/statuses/:id/history', async (_request, reply) => {
try {
- reply.send([]);
+ const edits = await this.mastoconverter.getEdits(_request.params.id);
+ reply.send(edits);
} catch (e: any) {
console.error(e);
reply.code(401).send(e.response.data);
@@ -91,8 +89,8 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.getStatusRebloggedBy(convertId(_request.params.id, IdType.SharkeyId));
- reply.send(data.data.map((account: Entity.Account) => convertAccount(account)));
+ const data = await client.getStatusRebloggedBy(_request.params.id);
+ reply.send(await Promise.all(data.data.map(async (account: Entity.Account) => await this.mastoconverter.convertAccount(account))));
} catch (e: any) {
console.error(e);
reply.code(401).send(e.response.data);
@@ -106,8 +104,8 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.getStatusFavouritedBy(convertId(_request.params.id, IdType.SharkeyId));
- reply.send(data.data.map((account: Entity.Account) => convertAccount(account)));
+ const data = await client.getStatusFavouritedBy(_request.params.id);
+ reply.send(await Promise.all(data.data.map(async (account: Entity.Account) => await this.mastoconverter.convertAccount(account))));
} catch (e: any) {
console.error(e);
reply.code(401).send(e.response.data);
@@ -121,7 +119,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.getMedia(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.getMedia(_request.params.id);
reply.send(convertAttachment(data.data));
} catch (e: any) {
console.error(e);
@@ -136,7 +134,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.getPoll(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.getPoll(_request.params.id);
reply.send(convertPoll(data.data));
} catch (e: any) {
console.error(e);
@@ -152,7 +150,7 @@ export class ApiStatusMastodon {
const client = getClient(BASE_URL, accessTokens);
const body: any = _request.body;
try {
- const data = await client.votePoll(convertId(_request.params.id, IdType.SharkeyId), body.choices);
+ const data = await client.votePoll(_request.params.id, body.choices);
reply.send(convertPoll(data.data));
} catch (e: any) {
console.error(e);
@@ -168,8 +166,6 @@ export class ApiStatusMastodon {
const client = getClient(BASE_URL, accessTokens);
let body: any = _request.body;
try {
- if (body.in_reply_to_id) body.in_reply_to_id = convertId(body.in_reply_to_id, IdType.SharkeyId);
- if (body.quote_id) body.quote_id = convertId(body.quote_id, IdType.SharkeyId);
if (
(!body.poll && body['poll[options][]']) ||
(!body.media_ids && body['media_ids[]'])
@@ -201,9 +197,6 @@ export class ApiStatusMastodon {
}
if (!body.media_ids) body.media_ids = undefined;
if (body.media_ids && !body.media_ids.length) body.media_ids = undefined;
- if (body.media_ids) {
- body.media_ids = (body.media_ids as string[]).map((p) => convertId(p, IdType.SharkeyId));
- }
const { sensitive } = body;
body.sensitive = typeof sensitive === 'string' ? sensitive === 'true' : sensitive;
@@ -241,10 +234,7 @@ export class ApiStatusMastodon {
try {
if (!body.media_ids) body.media_ids = undefined;
if (body.media_ids && !body.media_ids.length) body.media_ids = undefined;
- if (body.media_ids) {
- body.media_ids = (body.media_ids as string[]).map((p) => convertId(p, IdType.SharkeyId));
- }
- const data = await client.editStatus(convertId(_request.params.id, IdType.SharkeyId), body);
+ const data = await client.editStatus(_request.params.id, body);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -259,10 +249,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = (await client.createEmojiReaction(
- convertId(_request.params.id, IdType.SharkeyId),
- '❤',
- )) as any;
+ const data = (await client.createEmojiReaction(_request.params.id, '❤')) as any;
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -277,10 +264,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.deleteEmojiReaction(
- convertId(_request.params.id, IdType.SharkeyId),
- '❤',
- );
+ const data = await client.deleteEmojiReaction(_request.params.id, '❤');
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -295,7 +279,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.reblogStatus(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.reblogStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -310,7 +294,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.unreblogStatus(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.unreblogStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -325,7 +309,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.bookmarkStatus(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.bookmarkStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -340,7 +324,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.unbookmarkStatus(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.unbookmarkStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -355,7 +339,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.pinStatus(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.pinStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -370,7 +354,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.unpinStatus(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.unpinStatus(_request.params.id);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -385,7 +369,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.createEmojiReaction(convertId(_request.params.id, IdType.SharkeyId), _request.params.name);
+ const data = await client.createEmojiReaction(_request.params.id, _request.params.name);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -400,7 +384,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.deleteEmojiReaction(convertId(_request.params.id, IdType.SharkeyId), _request.params.name);
+ const data = await client.deleteEmojiReaction(_request.params.id, _request.params.name);
reply.send(await this.mastoconverter.convertStatus(data.data));
} catch (e: any) {
console.error(e);
@@ -415,7 +399,7 @@ export class ApiStatusMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
- const data = await client.deleteStatus(convertId(_request.params.id, IdType.SharkeyId));
+ const data = await client.deleteStatus(_request.params.id);
reply.send(data.data);
} catch (e: any) {
console.error(e);
diff --git a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts
index e4f510ea2b..f81b63b9ac 100644
--- a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts
+++ b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts
@@ -1,5 +1,5 @@
import { ParsedUrlQuery } from 'querystring';
-import { convertId, IdConvertType as IdType, convertAccount, convertConversation, convertList, MastoConverters } from '../converters.js';
+import { convertConversation, convertList, MastoConverters } from '../converters.js';
import { getClient } from '../MastodonApiServerService.js';
import type { Entity } from 'megalodon';
import type { FastifyInstance } from 'fastify';
@@ -32,20 +32,11 @@ export function argsToBools(q: ParsedUrlQuery) {
return q;
}
-export function convertTimelinesArgsId(q: ParsedUrlQuery) {
- if (typeof q.min_id === 'string') q.min_id = convertId(q.min_id, IdType.SharkeyId);
- if (typeof q.max_id === 'string') q.max_id = convertId(q.max_id, IdType.SharkeyId);
- if (typeof q.since_id === 'string') q.since_id = convertId(q.since_id, IdType.SharkeyId);
- return q;
-}
-
export class ApiTimelineMastodon {
private fastify: FastifyInstance;
- private mastoconverter: MastoConverters;
- constructor(fastify: FastifyInstance, config: Config, usersRepository: UsersRepository, notesRepository: NotesRepository, noteEditRepository: NoteEditRepository, userEntityService: UserEntityService) {
+ constructor(fastify: FastifyInstance, config: Config, private mastoconverter: MastoConverters) {
this.fastify = fastify;
- this.mastoconverter = new MastoConverters(config, usersRepository, notesRepository, noteEditRepository, userEntityService);
}
public async getTL() {
@@ -56,8 +47,8 @@ export class ApiTimelineMastodon {
try {
const query: any = _request.query;
const data = query.local === 'true'
- ? await client.getLocalTimeline(convertTimelinesArgsId(argsToBools(limitToInt(query))))
- : await client.getPublicTimeline(convertTimelinesArgsId(argsToBools(limitToInt(query))));
+ ? await client.getLocalTimeline(argsToBools(limitToInt(query)))
+ : await client.getPublicTimeline(argsToBools(limitToInt(query)));
reply.send(await Promise.all(data.data.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status))));
} catch (e: any) {
console.error(e);
@@ -74,7 +65,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
try {
const query: any = _request.query;
- const data = await client.getHomeTimeline(convertTimelinesArgsId(limitToInt(query)));
+ const data = await client.getHomeTimeline(limitToInt(query));
reply.send(await Promise.all(data.data.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status))));
} catch (e: any) {
console.error(e);
@@ -92,7 +83,7 @@ export class ApiTimelineMastodon {
try {
const query: any = _request.query;
const params: any = _request.params;
- const data = await client.getTagTimeline(params.hashtag, convertTimelinesArgsId(limitToInt(query)));
+ const data = await client.getTagTimeline(params.hashtag, limitToInt(query));
reply.send(await Promise.all(data.data.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status))));
} catch (e: any) {
console.error(e);
@@ -110,7 +101,7 @@ export class ApiTimelineMastodon {
try {
const query: any = _request.query;
const params: any = _request.params;
- const data = await client.getListTimeline(convertId(params.id, IdType.SharkeyId), convertTimelinesArgsId(limitToInt(query)));
+ const data = await client.getListTimeline(params.id, limitToInt(query));
reply.send(await Promise.all(data.data.map(async (status: Entity.Status) => await this.mastoconverter.convertStatus(status))));
} catch (e: any) {
console.error(e);
@@ -127,7 +118,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
try {
const query: any = _request.query;
- const data = await client.getConversationTimeline(convertTimelinesArgsId(limitToInt(query)));
+ const data = await client.getConversationTimeline(limitToInt(query));
reply.send(data.data.map((conversation: Entity.Conversation) => convertConversation(conversation)));
} catch (e: any) {
console.error(e);
@@ -144,7 +135,7 @@ export class ApiTimelineMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
- const data = await client.getList(convertId(params.id, IdType.SharkeyId));
+ const data = await client.getList(params.id);
reply.send(convertList(data.data));
} catch (e: any) {
console.error(e);
@@ -160,8 +151,7 @@ export class ApiTimelineMastodon {
const BASE_URL = `${_request.protocol}://${_request.hostname}`;
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
- const account = await client.verifyAccountCredentials();
- const data = await client.getLists(account.data.id);
+ const data = await client.getLists();
reply.send(data.data.map((list: Entity.List) => convertList(list)));
} catch (e: any) {
console.error(e);
@@ -178,11 +168,8 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
const query: any = _request.query;
- const data = await client.getAccountsInList(
- convertId(params.id, IdType.SharkeyId),
- convertTimelinesArgsId(query),
- );
- reply.send(data.data.map((account: Entity.Account) => convertAccount(account)));
+ const data = await client.getAccountsInList(params.id, query);
+ reply.send(data.data.map((account: Entity.Account) => this.mastoconverter.convertAccount(account)));
} catch (e: any) {
console.error(e);
console.error(e.response.data);
@@ -199,10 +186,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
const query: any = _request.query;
- const data = await client.addAccountsToList(
- convertId(params.id, IdType.SharkeyId),
- (query.accounts_id as string[]).map((id) => convertId(id, IdType.SharkeyId)),
- );
+ const data = await client.addAccountsToList(params.id, query.accounts_id);
reply.send(data.data);
} catch (e: any) {
console.error(e);
@@ -220,10 +204,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
const query: any = _request.query;
- const data = await client.deleteAccountsFromList(
- convertId(params.id, IdType.SharkeyId),
- (query.accounts_id as string[]).map((id) => convertId(id, IdType.SharkeyId)),
- );
+ const data = await client.deleteAccountsFromList(params.id, query.accounts_id);
reply.send(data.data);
} catch (e: any) {
console.error(e);
@@ -258,7 +239,7 @@ export class ApiTimelineMastodon {
const client = getClient(BASE_URL, accessTokens);
const body: any = _request.body;
const params: any = _request.params;
- const data = await client.updateList(convertId(params.id, IdType.SharkeyId), body.title);
+ const data = await client.updateList(params.id, body.title);
reply.send(convertList(data.data));
} catch (e: any) {
console.error(e);
@@ -275,8 +256,8 @@ export class ApiTimelineMastodon {
const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
const params: any = _request.params;
- const data = await client.deleteList(convertId(params.id, IdType.SharkeyId));
- reply.send(data.data);
+ const data = await client.deleteList(params.id);
+ reply.send({});
} catch (e: any) {
console.error(e);
console.error(e.response.data);