test: avatar and header uploading

This commit is contained in:
Mar0xy 2023-10-30 00:27:04 +01:00
parent 8736560e5f
commit b57ec5e2eb
No known key found for this signature in database
GPG key ID: 56569BBE47D2C828
3 changed files with 53 additions and 4 deletions

View file

@ -142,3 +142,7 @@ export function toArray<T>(x: T | T[] | undefined): T[] {
export function toSingle<T>(x: T | T[] | undefined): T | undefined { export function toSingle<T>(x: T | T[] | undefined): T | undefined {
return Array.isArray(x) ? x[0] : x; return Array.isArray(x) ? x[0] : x;
} }
export function toSingleLast<T>(x: T | T[] | undefined): T | undefined {
return Array.isArray(x) ? x.at(-1) : x;
}

View file

@ -3,16 +3,18 @@ import megalodon, { Entity, MegalodonInterface } from 'megalodon';
import querystring from 'querystring'; import querystring from 'querystring';
import { IsNull } from 'typeorm'; import { IsNull } from 'typeorm';
import multer from 'fastify-multer'; 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 { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import { MetaService } from '@/core/MetaService.js'; import { MetaService } from '@/core/MetaService.js';
import { convertAnnouncement, convertFilter, convertAttachment, convertFeaturedTag, convertList, MastoConverters } from './converters.js'; import { convertAnnouncement, convertFilter, convertAttachment, convertFeaturedTag, convertList, MastoConverters } from './converters.js';
import { getInstance } from './endpoints/meta.js'; import { getInstance } from './endpoints/meta.js';
import { ApiAuthMastodon, ApiAccountMastodon, ApiFilterMastodon, ApiNotifyMastodon, ApiSearchMastodon, ApiTimelineMastodon, ApiStatusMastodon } from './endpoints.js'; import { ApiAuthMastodon, ApiAccountMastodon, ApiFilterMastodon, ApiNotifyMastodon, ApiSearchMastodon, ApiTimelineMastodon, ApiStatusMastodon } from './endpoints.js';
import type { FastifyInstance, FastifyPluginOptions } from 'fastify'; import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { DriveService } from '@/core/DriveService.js';
import { toSingleLast } from '@/misc/prelude/array.js';
export function getClient(BASE_URL: string, authorization: string | undefined): MegalodonInterface { export function getClient(BASE_URL: string, authorization: string | undefined): MegalodonInterface {
const accessTokenArr = authorization?.split(' ') ?? [null]; const accessTokenArr = authorization?.split(' ') ?? [null];
@ -33,10 +35,13 @@ export class MastodonApiServerService {
private userProfilesRepository: UserProfilesRepository, private userProfilesRepository: UserProfilesRepository,
@Inject(DI.noteEditRepository) @Inject(DI.noteEditRepository)
private noteEditRepository: NoteEditRepository, private noteEditRepository: NoteEditRepository,
@Inject(DI.accessTokensRepository)
private accessTokensRepository: AccessTokensRepository,
@Inject(DI.config) @Inject(DI.config)
private config: Config, private config: Config,
private metaService: MetaService, private metaService: MetaService,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private driveService: DriveService,
private mastoConverter: MastoConverters, private mastoConverter: MastoConverters,
) { } ) { }
@ -245,16 +250,46 @@ 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 BASE_URL = `${_request.protocol}://${_request.hostname}`;
const accessTokens = _request.headers.authorization; const accessTokens = _request.headers.authorization;
const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
// displayed without being logged in // displayed without being logged in
try { try {
if (_request.files.length > 0) {
const tokeninfo = await this.accessTokensRepository.findOneBy({ token: accessTokens });
console.error(tokeninfo);
if (tokeninfo && (_request.files as any)['avatar']) {
const file = toSingleLast((_request.files as any)['avatar']);
const user = await this.usersRepository.findOneBy({ id: tokeninfo.userId });
const upload = await this.driveService.addFile({
user: { id: tokeninfo.userId, host: user ? user.host : null },
path: file.path,
name: file.originalname !== null && file.originalname !== 'file' ? file.originalname : undefined,
sensitive: false,
});
if (upload.type.startsWith('image/')) {
(_request.body as any).avatar = upload.id;
}
}
if (tokeninfo && (_request.files as any)['header']) {
const file = toSingleLast((_request.files as any)['header']);
const user = await this.usersRepository.findOneBy({ id: tokeninfo.userId });
const upload = await this.driveService.addFile({
user: { id: tokeninfo.userId, host: user ? user.host : null },
path: file.path,
name: file.originalname !== null && file.originalname !== 'file' ? file.originalname : undefined,
sensitive: false,
});
if (upload.type.startsWith('image/')) {
(_request.body as any).header = upload.id;
}
}
}
const data = await client.updateCredentials(_request.body!); const data = await client.updateCredentials(_request.body!);
reply.send(await this.mastoConverter.convertAccount(data.data)); reply.send(await this.mastoConverter.convertAccount(data.data));
} catch (e: any) { } catch (e: any) {
/* console.error(e); */ //console.error(e);
reply.code(401).send(e.response.data); reply.code(401).send(e.response.data);
} }
}); });

View file

@ -238,6 +238,16 @@ export default class Misskey implements MegalodonInterface {
description: options.note description: options.note
}) })
} }
if (options.avatar) {
params = Object.assign(params, {
avatarId: options.avatar
})
}
if (options.header) {
params = Object.assign(params, {
bannerId: options.header
})
}
if (options.locked !== undefined) { if (options.locked !== undefined) {
params = Object.assign(params, { params = Object.assign(params, {
isLocked: options.locked.toString() === 'true' ? true : false isLocked: options.locked.toString() === 'true' ? true : false