Merge branch 'develop' into mahjong
This commit is contained in:
@@ -14,9 +14,9 @@ export type FanoutTimelineName =
|
||||
| `homeTimeline:${string}`
|
||||
| `homeTimelineWithFiles:${string}` // only notes with files are included
|
||||
// local timeline
|
||||
| 'localTimeline' // replies are not included
|
||||
| 'localTimelineWithFiles' // only non-reply notes with files are included
|
||||
| 'localTimelineWithReplies' // only replies are included
|
||||
| `localTimeline` // replies are not included
|
||||
| `localTimelineWithFiles` // only non-reply notes with files are included
|
||||
| `localTimelineWithReplies` // only replies are included
|
||||
| `localTimelineWithReplyTo:${string}` // Only replies to specific local user are included. Parameter is reply user id.
|
||||
|
||||
// antenna
|
||||
|
@@ -263,10 +263,8 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||
}
|
||||
}
|
||||
|
||||
if (!user.host) {
|
||||
if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', meta.prohibitedWords)) {
|
||||
throw new NoteCreateService.ContainsProhibitedWordsError();
|
||||
}
|
||||
if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', meta.prohibitedWords)) {
|
||||
throw new NoteCreateService.ContainsProhibitedWordsError();
|
||||
}
|
||||
|
||||
const inSilencedInstance = this.utilityService.isSilencedHost(meta.silencedHosts, user.host);
|
||||
|
@@ -12,11 +12,11 @@ import type { Config } from '@/config.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js';
|
||||
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
|
||||
import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, RelationshipQueue, SystemQueue, WebhookDeliverQueue } from './QueueModule.js';
|
||||
import type { DbJobData, DeliverJobData, RelationshipJobData, ThinUser } from '../queue/types.js';
|
||||
import type httpSignature from '@peertube/http-signature';
|
||||
import type * as Bull from 'bullmq';
|
||||
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
|
||||
|
||||
@Injectable()
|
||||
export class QueueService {
|
||||
|
@@ -31,7 +31,7 @@ export class ApMfmService {
|
||||
|
||||
const parsed = mfm.parse(srcMfm);
|
||||
|
||||
if (!apAppend && parsed.every(n => ['text', 'unicodeEmoji', 'emojiCode', 'mention', 'hashtag', 'url'].includes(n.type))) {
|
||||
if (!apAppend && parsed?.every(n => ['text', 'unicodeEmoji', 'emojiCode', 'mention', 'hashtag', 'url'].includes(n.type))) {
|
||||
noMisskeyContent = true;
|
||||
}
|
||||
|
||||
|
9
packages/backend/src/misc/fastify-hook-handlers.ts
Normal file
9
packages/backend/src/misc/fastify-hook-handlers.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { onRequestHookHandler } from 'fastify';
|
||||
|
||||
export const handleRequestRedirectToOmitSearch: onRequestHookHandler = (request, reply, done) => {
|
||||
const index = request.url.indexOf('?');
|
||||
if (~index) {
|
||||
reply.redirect(301, request.url.slice(0, index));
|
||||
}
|
||||
done();
|
||||
};
|
@@ -34,7 +34,7 @@ export class RelationshipProcessorService {
|
||||
|
||||
@bindThis
|
||||
public async processFollow(job: Bull.Job<RelationshipJobData>): Promise<string> {
|
||||
this.logger.info(`${job.data.from.id} is trying to follow ${job.data.to.id} ${job.data.withReplies ? 'with replies' : 'without replies'}`);
|
||||
this.logger.info(`${job.data.from.id} is trying to follow ${job.data.to.id} ${job.data.withReplies ? "with replies" : "without replies"}`);
|
||||
await this.userFollowingService.follow(job.data.from, job.data.to, {
|
||||
requestId: job.data.requestId,
|
||||
silent: job.data.silent,
|
||||
|
@@ -27,6 +27,7 @@ import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { isMimeImage } from '@/misc/is-mime-image.js';
|
||||
import { correctFilename } from '@/misc/correct-filename.js';
|
||||
import { handleRequestRedirectToOmitSearch } from '@/misc/fastify-hook-handlers.js';
|
||||
import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify';
|
||||
|
||||
const _filename = fileURLToPath(import.meta.url);
|
||||
@@ -67,20 +68,23 @@ export class FileServerService {
|
||||
done();
|
||||
});
|
||||
|
||||
fastify.get('/files/app-default.jpg', (request, reply) => {
|
||||
const file = fs.createReadStream(`${_dirname}/assets/dummy.png`);
|
||||
reply.header('Content-Type', 'image/jpeg');
|
||||
reply.header('Cache-Control', 'max-age=31536000, immutable');
|
||||
return reply.send(file);
|
||||
});
|
||||
fastify.register((fastify, options, done) => {
|
||||
fastify.addHook('onRequest', handleRequestRedirectToOmitSearch);
|
||||
fastify.get('/files/app-default.jpg', (request, reply) => {
|
||||
const file = fs.createReadStream(`${_dirname}/assets/dummy.png`);
|
||||
reply.header('Content-Type', 'image/jpeg');
|
||||
reply.header('Cache-Control', 'max-age=31536000, immutable');
|
||||
return reply.send(file);
|
||||
});
|
||||
|
||||
fastify.get<{ Params: { key: string; } }>('/files/:key', async (request, reply) => {
|
||||
return await this.sendDriveFile(request, reply)
|
||||
.catch(err => this.errorHandler(request, reply, err));
|
||||
});
|
||||
fastify.get<{ Params: { key: string; } }>('/files/:key/*', async (request, reply) => {
|
||||
return await this.sendDriveFile(request, reply)
|
||||
.catch(err => this.errorHandler(request, reply, err));
|
||||
fastify.get<{ Params: { key: string; } }>('/files/:key', async (request, reply) => {
|
||||
return await this.sendDriveFile(request, reply)
|
||||
.catch(err => this.errorHandler(request, reply, err));
|
||||
});
|
||||
fastify.get<{ Params: { key: string; } }>('/files/:key/*', async (request, reply) => {
|
||||
return await reply.redirect(301, `${this.config.url}/files/${request.params.key}`);
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
fastify.get<{
|
||||
|
@@ -37,12 +37,12 @@ export class NodeinfoServerService {
|
||||
@bindThis
|
||||
public getLinks() {
|
||||
return [{
|
||||
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1',
|
||||
href: this.config.url + nodeinfo2_1path,
|
||||
}, {
|
||||
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0',
|
||||
href: this.config.url + nodeinfo2_0path,
|
||||
}];
|
||||
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1',
|
||||
href: this.config.url + nodeinfo2_1path
|
||||
}, {
|
||||
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0',
|
||||
href: this.config.url + nodeinfo2_0path,
|
||||
}];
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@@ -25,8 +25,8 @@ export const meta = {
|
||||
items: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
} as const;
|
||||
|
||||
|
@@ -71,7 +71,7 @@ export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
withReplies: { type: 'boolean' },
|
||||
withReplies: { type: 'boolean' }
|
||||
},
|
||||
required: ['userId'],
|
||||
} as const;
|
||||
|
@@ -6,7 +6,7 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import { safeForSql } from '@/misc/safe-for-sql.js';
|
||||
import { safeForSql } from "@/misc/safe-for-sql.js";
|
||||
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
@@ -14,7 +14,7 @@ export const meta = {
|
||||
tags: ['account'],
|
||||
|
||||
requireCredential: true,
|
||||
kind: 'read:account',
|
||||
kind: "read:account",
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
|
@@ -38,9 +38,9 @@ export const meta = {
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
items: {
|
||||
type: 'string',
|
||||
type: 'string'
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@@ -35,7 +35,7 @@ export const meta = {
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
items: {
|
||||
type: 'string',
|
||||
type: 'string'
|
||||
},
|
||||
},
|
||||
isAuthorized: {
|
||||
|
@@ -22,7 +22,7 @@ export const meta = {
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
},
|
||||
}
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@@ -22,7 +22,7 @@ export const meta = {
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
},
|
||||
}
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@@ -22,8 +22,8 @@ export const meta = {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
@@ -31,7 +31,7 @@ export const meta = {
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@@ -33,7 +33,7 @@ export const meta = {
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
format: 'misskey:id'
|
||||
},
|
||||
userId: {
|
||||
type: 'string',
|
||||
@@ -45,7 +45,7 @@ export const meta = {
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: webhookEventTypes,
|
||||
},
|
||||
}
|
||||
},
|
||||
url: { type: 'string' },
|
||||
secret: { type: 'string' },
|
||||
|
@@ -23,7 +23,7 @@ export const meta = {
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
format: 'misskey:id'
|
||||
},
|
||||
userId: {
|
||||
type: 'string',
|
||||
@@ -35,7 +35,7 @@ export const meta = {
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: webhookEventTypes,
|
||||
},
|
||||
}
|
||||
},
|
||||
url: { type: 'string' },
|
||||
secret: { type: 'string' },
|
||||
@@ -43,8 +43,8 @@ export const meta = {
|
||||
latestSentAt: { type: 'string', format: 'date-time', nullable: true },
|
||||
latestStatus: { type: 'integer', nullable: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@@ -30,7 +30,7 @@ export const meta = {
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
format: 'misskey:id'
|
||||
},
|
||||
userId: {
|
||||
type: 'string',
|
||||
@@ -42,7 +42,7 @@ export const meta = {
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: webhookEventTypes,
|
||||
},
|
||||
}
|
||||
},
|
||||
url: { type: 'string' },
|
||||
secret: { type: 'string' },
|
||||
|
@@ -47,7 +47,7 @@ export const meta = {
|
||||
bothWithRepliesAndWithFiles: {
|
||||
message: 'Specifying both withReplies and withFiles is not supported',
|
||||
code: 'BOTH_WITH_REPLIES_AND_WITH_FILES',
|
||||
id: 'dfaa3eb7-8002-4cb7-bcc4-1095df46656f',
|
||||
id: 'dfaa3eb7-8002-4cb7-bcc4-1095df46656f'
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
@@ -18,7 +18,7 @@ export const meta = {
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
format: 'misskey:id'
|
||||
},
|
||||
required: {
|
||||
type: 'boolean',
|
||||
@@ -34,8 +34,8 @@ export const meta = {
|
||||
default: 'hello',
|
||||
nullable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@@ -34,6 +34,7 @@ import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
|
||||
import type { ChannelsRepository, ClipsRepository, FlashsRepository, GalleryPostsRepository, MiMeta, NotesRepository, PagesRepository, ReversiGamesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import { deepClone } from '@/misc/clone.js';
|
||||
import { handleRequestRedirectToOmitSearch } from '@/misc/fastify-hook-handlers.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { FlashEntityService } from '@/core/entities/FlashEntityService.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
@@ -253,11 +254,16 @@ export class ClientServerService {
|
||||
|
||||
//#region vite assets
|
||||
if (this.config.clientManifestExists) {
|
||||
fastify.register(fastifyStatic, {
|
||||
root: viteOut,
|
||||
prefix: '/vite/',
|
||||
maxAge: ms('30 days'),
|
||||
decorateReply: false,
|
||||
fastify.register((fastify, options, done) => {
|
||||
fastify.register(fastifyStatic, {
|
||||
root: viteOut,
|
||||
prefix: '/vite/',
|
||||
maxAge: ms('30 days'),
|
||||
immutable: true,
|
||||
decorateReply: false,
|
||||
});
|
||||
fastify.addHook('onRequest', handleRequestRedirectToOmitSearch);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
const port = (process.env.VITE_PORT ?? '5173');
|
||||
@@ -292,11 +298,16 @@ export class ClientServerService {
|
||||
decorateReply: false,
|
||||
});
|
||||
|
||||
fastify.register(fastifyStatic, {
|
||||
root: tarball,
|
||||
prefix: '/tarball/',
|
||||
immutable: true,
|
||||
decorateReply: false,
|
||||
fastify.register((fastify, options, done) => {
|
||||
fastify.register(fastifyStatic, {
|
||||
root: tarball,
|
||||
prefix: '/tarball/',
|
||||
maxAge: ms('30 days'),
|
||||
immutable: true,
|
||||
decorateReply: false,
|
||||
});
|
||||
fastify.addHook('onRequest', handleRequestRedirectToOmitSearch);
|
||||
done();
|
||||
});
|
||||
|
||||
fastify.get('/favicon.ico', async (request, reply) => {
|
||||
|
Reference in New Issue
Block a user