fix: wrong json subtype

This commit is contained in:
zyoshoka 2023-11-12 13:38:33 +09:00
parent b40e20a207
commit ada1698ead
No known key found for this signature in database
GPG Key ID: 0C2CB8FBA309A5B8
2 changed files with 59 additions and 45 deletions

View File

@ -40,7 +40,7 @@ import { RoleService } from '@/core/RoleService.js';
import { FeedService } from './FeedService.js';
import { UrlPreviewService } from './UrlPreviewService.js';
import { ClientLoggerService } from './ClientLoggerService.js';
import type { FastifyInstance, FastifyPluginOptions, FastifyReply, FastifyRequest } from 'fastify';
import type { FastifyInstance, FastifyPluginOptions, FastifyReply } from 'fastify';
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
@ -416,51 +416,20 @@ export class ClientServerService {
// URL preview endpoint
fastify.get<{ Querystring: { url: string; lang: string; } }>('/url', (request, reply) => this.urlPreviewService.handle(request, reply));
const feedHandler = (
feedType: 'atom' | 'rss' | 'json',
options?: {
withReplies?: boolean;
withFiles?: boolean;
},
) => async (
request: FastifyRequest<{ Params: { user: string; } }>,
reply: FastifyReply,
) => {
const { username, host } = Acct.parse(request.params.user);
const user = await this.usersRepository.findOneBy({
usernameLower: username.toLowerCase(),
host: host ?? IsNull(),
isSuspended: false,
});
const feed = user && await this.feedService.packFeed(user, options);
if (feed) {
reply.header('Content-Type', `application/${feedType}+xml; charset=utf-8`);
if (feedType === 'atom') return feed.atom1();
else if (feedType === 'rss') return feed.rss2();
else return feed.json1();
} else {
reply.code(404);
return;
}
};
// Atom
fastify.get<{ Params: { user: string; } }>('/@:user.atom', feedHandler('atom'));
fastify.get<{ Params: { user: string; } }>('/@:user.with_replies.atom', feedHandler('atom', { withReplies: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.with_files.atom', feedHandler('atom', { withFiles: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.atom', this.feedService.handle('atom'));
fastify.get<{ Params: { user: string; } }>('/@:user.with_replies.atom', this.feedService.handle('atom', { withReplies: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.with_files.atom', this.feedService.handle('atom', { withFiles: true }));
// RSS
fastify.get<{ Params: { user: string; } }>('/@:user.rss', feedHandler('rss'));
fastify.get<{ Params: { user: string; } }>('/@:user.with_replies.rss', feedHandler('rss', { withReplies: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.with_files.rss', feedHandler('rss', { withFiles: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.rss', this.feedService.handle('rss'));
fastify.get<{ Params: { user: string; } }>('/@:user.with_replies.rss', this.feedService.handle('rss', { withReplies: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.with_files.rss', this.feedService.handle('rss', { withFiles: true }));
// JSON
fastify.get<{ Params: { user: string; } }>('/@:user.json', feedHandler('json'));
fastify.get<{ Params: { user: string; } }>('/@:user.with_replies.json', feedHandler('json', { withReplies: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.with_files.json', feedHandler('json', { withFiles: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.json', this.feedService.handle('json'));
fastify.get<{ Params: { user: string; } }>('/@:user.with_replies.json', this.feedService.handle('json', { withReplies: true }));
fastify.get<{ Params: { user: string; } }>('/@:user.with_files.json', this.feedService.handle('json', { withFiles: true }));
//#region SSR (for crawlers)
// User

View File

@ -7,13 +7,15 @@ import { Inject, Injectable } from '@nestjs/common';
import { Equal, In, IsNull, Not } from 'typeorm';
import { Feed } from 'feed';
import { DI } from '@/di-symbols.js';
import type { DriveFilesRepository, NotesRepository, UserProfilesRepository } from '@/models/_.js';
import * as Acct from '@/misc/acct.js';
import type { DriveFilesRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import type { MiUser } from '@/models/User.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import type { FastifyReply, FastifyRequest } from 'fastify';
@Injectable()
export class FeedService {
@ -21,6 +23,9 @@ export class FeedService {
@Inject(DI.config)
private config: Config,
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository,
@ -37,7 +42,7 @@ export class FeedService {
}
@bindThis
public async packFeed(
private async packFeed(
user: MiUser,
options?: {
withReplies?: boolean;
@ -72,6 +77,8 @@ export class FeedService {
take: 20,
});
const optionLink = opts.withReplies ? '.with_replies' : opts.withFiles ? '.with_files' : '';
const feed = new Feed({
id: author.link,
title: `${author.name} (@${user.username}@${this.config.host})`,
@ -81,8 +88,8 @@ export class FeedService {
link: author.link,
image: user.avatarUrl ?? this.userEntityService.getIdenticonUrl(user),
feedLinks: {
json: `${author.link}.json`,
atom: `${author.link}.atom`,
json: `${author.link + optionLink}.json`,
atom: `${author.link + optionLink}.atom`,
},
author,
copyright: user.name ?? user.username,
@ -106,4 +113,42 @@ export class FeedService {
return feed;
}
@bindThis
public handle(
feedType: 'atom' | 'rss' | 'json',
options?: {
withReplies?: boolean;
withFiles?: boolean;
},
) {
return async (
request: FastifyRequest<{ Params: { user: string; } }>,
reply: FastifyReply,
) => {
const { username, host } = Acct.parse(request.params.user);
const user = await this.usersRepository.findOneBy({
usernameLower: username.toLowerCase(),
host: host ?? IsNull(),
isSuspended: false,
});
const feed = user && await this.packFeed(user, options);
if (feed) {
const subtype = feedType === 'atom' || feedType === 'rss'
? `${feedType}+xml`
: feedType;
reply.header('Content-Type', `application/${subtype}; charset=utf-8`);
if (feedType === 'atom') return feed.atom1();
else if (feedType === 'rss') return feed.rss2();
else return feed.json1();
} else {
reply.code(404);
return;
}
};
}
}