test: avatar and header uploading
This commit is contained in:
parent
8736560e5f
commit
b57ec5e2eb
3 changed files with 53 additions and 4 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ 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';
|
||||||
|
@ -13,6 +13,8 @@ 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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue