lint and type fixes
This commit is contained in:
parent
54071efaea
commit
6ac37b4d6c
84 changed files with 188 additions and 374 deletions
|
|
@ -178,15 +178,13 @@ export class GlobalModule implements OnApplicationShutdown {
|
|||
// Wait for all potential DB queries
|
||||
await allSettled();
|
||||
// And then disconnect from DB
|
||||
await Promise.all([
|
||||
this.db.destroy(),
|
||||
this.redisClient.disconnect(),
|
||||
this.redisForPub.disconnect(),
|
||||
this.redisForSub.disconnect(),
|
||||
this.redisForTimelines.disconnect(),
|
||||
this.redisForReactions.disconnect(),
|
||||
this.redisForRateLimit.disconnect(),
|
||||
]);
|
||||
await this.db.destroy();
|
||||
this.redisClient.disconnect();
|
||||
this.redisForPub.disconnect();
|
||||
this.redisForSub.disconnect();
|
||||
this.redisForTimelines.disconnect();
|
||||
this.redisForReactions.disconnect();
|
||||
this.redisForRateLimit.disconnect();
|
||||
}
|
||||
|
||||
async onApplicationShutdown(signal: string): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -139,6 +139,24 @@ export class ApLogService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all logged inbox activities from a user or users
|
||||
* @param userIds IDs of the users to delete
|
||||
*/
|
||||
public async deleteInboxLogs(userIds: string | string[]): Promise<number> {
|
||||
if (Array.isArray(userIds)) {
|
||||
const logsDeleted = await this.apInboxLogsRepository.delete({
|
||||
authUserId: In(userIds),
|
||||
});
|
||||
return logsDeleted.affected ?? 0;
|
||||
} else {
|
||||
const logsDeleted = await this.apInboxLogsRepository.delete({
|
||||
authUserId: userIds,
|
||||
});
|
||||
return logsDeleted.affected ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all expired AP logs and garbage-collects the AP context cache.
|
||||
* Returns the total number of deleted rows.
|
||||
|
|
|
|||
|
|
@ -571,7 +571,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
if (this.meta.enableStatsForFederatedInstances) {
|
||||
if (this.userEntityService.isRemoteUser(user)) {
|
||||
this.federatedInstanceService.fetchOrRegister(user.host).then(async i => {
|
||||
if (note.renote && note.text || !note.renote) {
|
||||
if (!this.isRenote(note) || this.isQuote(note)) {
|
||||
this.updateNotesCountQueue.enqueue(i.id, 1);
|
||||
}
|
||||
if (this.meta.enableChartsForFederatedInstances) {
|
||||
|
|
@ -583,17 +583,12 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
|
||||
// ハッシュタグ更新
|
||||
if (data.visibility === 'public' || data.visibility === 'home') {
|
||||
if (user.isBot && this.meta.enableBotTrending) {
|
||||
this.hashtagService.updateHashtags(user, tags);
|
||||
} else if (!user.isBot) {
|
||||
if (!user.isBot || this.meta.enableBotTrending) {
|
||||
this.hashtagService.updateHashtags(user, tags);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.renote && data.text) {
|
||||
// Increment notes count (user)
|
||||
this.incNotesCountOfUser(user);
|
||||
} else if (!data.renote) {
|
||||
if (!this.isRenote(note) || this.isQuote(note)) {
|
||||
// Increment notes count (user)
|
||||
this.incNotesCountOfUser(user);
|
||||
}
|
||||
|
|
@ -631,7 +626,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
});
|
||||
}
|
||||
|
||||
if (data.renote && data.text == null && data.renote.userId !== user.id && !user.isBot) {
|
||||
if (this.isRenote(data) && !this.isQuote(data) && data.renote.userId !== user.id && !user.isBot) {
|
||||
this.incRenoteCount(data.renote);
|
||||
}
|
||||
|
||||
|
|
@ -706,13 +701,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
},
|
||||
});
|
||||
|
||||
const [
|
||||
userIdsWhoMeMuting,
|
||||
] = data.renote.userId ? await Promise.all([
|
||||
this.cacheService.userMutingsCache.fetch(data.renote.userId),
|
||||
]) : [new Set<string>()];
|
||||
|
||||
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
||||
const muted = data.renote.userId && isUserRelated(note, await this.cacheService.userMutingsCache.fetch(data.renote.userId));
|
||||
|
||||
if (!isThreadMuted && !muted) {
|
||||
nm.push(data.renote.userId, type);
|
||||
|
|
@ -848,13 +837,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
},
|
||||
});
|
||||
|
||||
const [
|
||||
userIdsWhoMeMuting,
|
||||
] = u.id ? await Promise.all([
|
||||
this.cacheService.userMutingsCache.fetch(u.id),
|
||||
]) : [new Set<string>()];
|
||||
|
||||
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
||||
const muted = u.id && isUserRelated(note, await this.cacheService.userMutingsCache.fetch(u.id));
|
||||
|
||||
if (isThreadMuted || muted) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
import type { Response } from 'node-fetch';
|
||||
|
||||
// TODO throw identifiable or unrecoverable errors
|
||||
|
||||
export function validateContentTypeSetAsActivityPub(response: Response): void {
|
||||
const contentType = (response.headers.get('content-type') ?? '').toLowerCase();
|
||||
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ export class ApPersonService implements OnModuleInit, OnApplicationShutdown {
|
|||
|
||||
const host = this.utilityService.punyHost(uri);
|
||||
if (host === this.utilityService.toPuny(this.config.host)) {
|
||||
// TODO convert to unrecoverable error
|
||||
throw new StatusError(`cannot resolve local user: ${uri}`, 400, 'cannot resolve local user');
|
||||
}
|
||||
|
||||
|
|
@ -570,7 +571,7 @@ export class ApPersonService implements OnModuleInit, OnApplicationShutdown {
|
|||
.catch(err => {
|
||||
if (!(err instanceof StatusError) || err.isRetryable) {
|
||||
this.logger.error('error occurred while fetching following/followers collection', { stack: err });
|
||||
// Do not update the visibiility on transient errors.
|
||||
// Do not update the visibility on transient errors.
|
||||
return undefined;
|
||||
}
|
||||
return 'private';
|
||||
|
|
|
|||
|
|
@ -479,14 +479,6 @@ export class NoteEntityService implements OnModuleInit {
|
|||
mentions: note.mentions && note.mentions.length > 0 ? note.mentions : undefined,
|
||||
uri: note.uri ?? undefined,
|
||||
url: note.url ?? undefined,
|
||||
poll: note.hasPoll ? this.populatePoll(note, meId) : undefined,
|
||||
...(meId && Object.keys(reactions).length > 0 ? {
|
||||
myReaction: this.populateMyReaction({
|
||||
id: note.id,
|
||||
reactions: reactions,
|
||||
reactionAndUserPairCache: reactionAndUserPairCache,
|
||||
}, meId, options?._hint_),
|
||||
} : {}),
|
||||
|
||||
...(opts.detail ? {
|
||||
clippedCount: note.clippedCount,
|
||||
|
|
@ -505,6 +497,16 @@ export class NoteEntityService implements OnModuleInit {
|
|||
withReactionAndUserPairCache: opts.withReactionAndUserPairCache,
|
||||
_hint_: options?._hint_,
|
||||
}) : undefined,
|
||||
|
||||
poll: note.hasPoll ? this.populatePoll(note, meId) : undefined,
|
||||
|
||||
...(meId && Object.keys(reactions).length > 0 ? {
|
||||
myReaction: this.populateMyReaction({
|
||||
id: note.id,
|
||||
reactions: reactions,
|
||||
reactionAndUserPairCache: reactionAndUserPairCache,
|
||||
}, meId, options?._hint_),
|
||||
} : {}),
|
||||
} : {}),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const sideN = Math.floor(n / 2);
|
|||
/**
|
||||
* Generate buffer of an identicon by seed
|
||||
*/
|
||||
export async function genIdenticon(seed: string): Promise<Buffer> {
|
||||
export function genIdenticon(seed: string): Buffer {
|
||||
const rand = gen.create(seed);
|
||||
const canvas = createCanvas(size, size);
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
|
@ -100,5 +100,5 @@ export async function genIdenticon(seed: string): Promise<Buffer> {
|
|||
}
|
||||
}
|
||||
|
||||
return await canvas.toBuffer('image/png');
|
||||
return canvas.toBuffer('image/png');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ type MinimumUser = {
|
|||
uri: MiUser['uri'];
|
||||
};
|
||||
|
||||
export type MiScheduleNoteType={
|
||||
export type MiScheduleNoteType = {
|
||||
visibility: 'public' | 'home' | 'followers' | 'specified';
|
||||
visibleUsers: MinimumUser[];
|
||||
channel?: MiChannel['id'];
|
||||
|
|
@ -37,7 +37,7 @@ export type MiScheduleNoteType={
|
|||
apMentions?: MinimumUser[] | null;
|
||||
apHashtags?: string[] | null;
|
||||
apEmojis?: string[] | null;
|
||||
}
|
||||
};
|
||||
|
||||
@Entity('note_schedule')
|
||||
export class MiNoteSchedule {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
|
||||
import { obsoleteNotificationTypes, followingVisibilities, followersVisibilities, notificationTypes, noteVisibilities, defaultCWPriorities } from '@/types.js';
|
||||
import { obsoleteNotificationTypes, followingVisibilities, followersVisibilities, notificationTypes, defaultCWPriorities } from '@/types.js';
|
||||
import { id } from './util/id.js';
|
||||
import { MiUser } from './User.js';
|
||||
import { MiPage } from './Page.js';
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: marie and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export const packedNoteEdit = {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
format: "id",
|
||||
example: "xxxxxxxxxx",
|
||||
},
|
||||
updatedAt: {
|
||||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
format: "date-time",
|
||||
},
|
||||
note: {
|
||||
type: "object",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
ref: "Note",
|
||||
},
|
||||
noteId: {
|
||||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
format: "id",
|
||||
},
|
||||
oldText: {
|
||||
type: "string",
|
||||
optional: true,
|
||||
nullable: true,
|
||||
},
|
||||
newText: {
|
||||
type: "string",
|
||||
optional: true,
|
||||
nullable: true,
|
||||
},
|
||||
cw: {
|
||||
type: "string",
|
||||
optional: true,
|
||||
nullable: true,
|
||||
},
|
||||
fileIds: {
|
||||
type: "array",
|
||||
optional: true,
|
||||
nullable: true,
|
||||
items: {
|
||||
type: "string",
|
||||
format: "id",
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
|
@ -184,6 +184,11 @@ export class DeleteAccountProcessorService {
|
|||
await this.apLogService.deleteObjectLogs(user.uri)
|
||||
.catch(err => this.logger.error(err, `Failed to delete AP logs for user '${user.uri}'`));
|
||||
}
|
||||
|
||||
await this.apLogService.deleteInboxLogs(user.id)
|
||||
.catch(err => this.logger.error(err, `Failed to delete AP logs for user '${user.uri}'`));
|
||||
|
||||
this.logger.succ('All AP logs deleted');
|
||||
}
|
||||
|
||||
{ // Send email notification
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@ import { JsonLdService } from '@/core/activitypub/JsonLdService.js';
|
|||
import { ApInboxService } from '@/core/activitypub/ApInboxService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
//import { CollapsedQueue } from '@/misc/collapsed-queue.js';
|
||||
//import { MiNote } from '@/models/Note.js';
|
||||
import { MiMeta } from '@/models/Meta.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { SkApInboxLog } from '@/models/_.js';
|
||||
|
|
@ -68,7 +66,6 @@ export class InboxProcessorService implements OnApplicationShutdown {
|
|||
private readonly updateInstanceQueue: UpdateInstanceQueue,
|
||||
) {
|
||||
this.logger = this.queueLoggerService.logger.createSubLogger('inbox');
|
||||
//this.updateInstanceQueue = new CollapsedQueue(process.env.NODE_ENV !== 'test' ? 60 * 1000 * 5 : 0, this.collapseUpdateInstanceJobs, this.performUpdateInstance);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import { ActivityPubServerService } from './ActivityPubServerService.js';
|
|||
import { ApiLoggerService } from './api/ApiLoggerService.js';
|
||||
import { ApiServerService } from './api/ApiServerService.js';
|
||||
import { AuthenticateService } from './api/AuthenticateService.js';
|
||||
import { RateLimiterService } from './api/RateLimiterService.js';
|
||||
import { SigninApiService } from './api/SigninApiService.js';
|
||||
import { SigninService } from './api/SigninService.js';
|
||||
import { SignupApiService } from './api/SignupApiService.js';
|
||||
|
|
@ -88,8 +87,6 @@ import { SigninWithPasskeyApiService } from './api/SigninWithPasskeyApiService.j
|
|||
ApiServerService,
|
||||
AuthenticateService,
|
||||
SkRateLimiterService,
|
||||
// No longer used, but kept for backwards compatibility
|
||||
RateLimiterService,
|
||||
SigninApiService,
|
||||
SigninWithPasskeyApiService,
|
||||
SigninService,
|
||||
|
|
|
|||
|
|
@ -229,12 +229,12 @@ export class ServerService implements OnApplicationShutdown {
|
|||
}
|
||||
});
|
||||
|
||||
fastify.get<{ Params: { x: string } }>('/identicon/:x', async (request, reply) => {
|
||||
reply.header('Content-Type', 'image/png');
|
||||
fastify.get<{ Params: { x: string } }>('/identicon/:x', (request, reply) => {
|
||||
reply.header('Content-Type', 'image/png');
|
||||
reply.header('Cache-Control', 'public, max-age=86400');
|
||||
|
||||
if (this.meta.enableIdenticonGeneration) {
|
||||
return await genIdenticon(request.params.x);
|
||||
return genIdenticon(request.params.x);
|
||||
} else {
|
||||
return reply.redirect('/static-assets/avatar.png');
|
||||
}
|
||||
|
|
@ -293,13 +293,14 @@ export class ServerService implements OnApplicationShutdown {
|
|||
if (fs.existsSync(this.config.socket)) {
|
||||
fs.unlinkSync(this.config.socket);
|
||||
}
|
||||
fastify.listen({ path: this.config.socket }, (err, address) => {
|
||||
if (this.config.chmodSocket) {
|
||||
fs.chmodSync(this.config.socket!, this.config.chmodSocket);
|
||||
}
|
||||
});
|
||||
|
||||
await fastify.listen({ path: this.config.socket });
|
||||
|
||||
if (this.config.chmodSocket) {
|
||||
fs.chmodSync(this.config.socket!, this.config.chmodSocket);
|
||||
}
|
||||
} else {
|
||||
fastify.listen({ port: this.config.port, host: this.config.address });
|
||||
await fastify.listen({ port: this.config.port, host: this.config.address });
|
||||
}
|
||||
|
||||
await fastify.ready();
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import Limiter from 'ratelimiter';
|
||||
import * as Redis from 'ioredis';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { LegacyRateLimit } from '@/misc/rate-limit-utils.js';
|
||||
import type { IEndpointMeta } from './endpoints.js';
|
||||
|
||||
/** @deprecated Use SkRateLimiterService instead */
|
||||
@Injectable()
|
||||
export class RateLimiterService {
|
||||
private logger: Logger;
|
||||
private disabled = false;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.redis)
|
||||
private redisClient: Redis.Redis,
|
||||
|
||||
private loggerService: LoggerService,
|
||||
) {
|
||||
this.logger = this.loggerService.getLogger('limiter');
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
this.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public limit(limitation: LegacyRateLimit & { key: NonNullable<string> }, actor: string, factor = 1) {
|
||||
return new Promise<void>((ok, reject) => {
|
||||
if (this.disabled) ok();
|
||||
|
||||
// Short-term limit
|
||||
const minP = (): void => {
|
||||
const minIntervalLimiter = new Limiter({
|
||||
id: `${actor}:${limitation.key}:min`,
|
||||
duration: limitation.minInterval! * factor,
|
||||
max: 1,
|
||||
db: this.redisClient,
|
||||
});
|
||||
|
||||
minIntervalLimiter.get((err, info) => {
|
||||
if (err) {
|
||||
return reject({ code: 'ERR', info });
|
||||
}
|
||||
|
||||
this.logger.debug(`${actor} ${limitation.key} min remaining: ${info.remaining}`);
|
||||
|
||||
if (info.remaining === 0) {
|
||||
return reject({ code: 'BRIEF_REQUEST_INTERVAL', info });
|
||||
} else {
|
||||
if (hasLongTermLimit) {
|
||||
return maxP();
|
||||
} else {
|
||||
return ok();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Long term limit
|
||||
const maxP = (): void => {
|
||||
const limiter = new Limiter({
|
||||
id: `${actor}:${limitation.key}`,
|
||||
duration: limitation.duration! * factor,
|
||||
max: limitation.max! / factor,
|
||||
db: this.redisClient,
|
||||
});
|
||||
|
||||
limiter.get((err, info) => {
|
||||
if (err) {
|
||||
return reject({ code: 'ERR', info });
|
||||
}
|
||||
|
||||
this.logger.debug(`${actor} ${limitation.key} max remaining: ${info.remaining}`);
|
||||
|
||||
if (info.remaining === 0) {
|
||||
return reject({ code: 'RATE_LIMIT_EXCEEDED', info });
|
||||
} else {
|
||||
return ok();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const hasShortTermLimit = typeof limitation.minInterval === 'number';
|
||||
|
||||
const hasLongTermLimit =
|
||||
typeof limitation.duration === 'number' &&
|
||||
typeof limitation.max === 'number';
|
||||
|
||||
if (hasShortTermLimit) {
|
||||
minP();
|
||||
} else if (hasLongTermLimit) {
|
||||
maxP();
|
||||
} else {
|
||||
ok();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +35,8 @@ import type { FastifyReply, FastifyRequest } from 'fastify';
|
|||
// Up to 10 attempts, then 1 per minute
|
||||
const signinRateLimit: Keyed<RateLimit> = {
|
||||
key: 'signin',
|
||||
max: 10,
|
||||
type: 'bucket',
|
||||
size: 10,
|
||||
dripRate: 1000 * 60,
|
||||
};
|
||||
|
||||
|
|
@ -146,7 +147,7 @@ export class SigninApiService {
|
|||
|
||||
if (isSystemAccount(user)) {
|
||||
return error(403, {
|
||||
id: 's8dhsj9s-a93j-493j-ja9k-kas9sj20aml2',
|
||||
id: 'ba4ba3bc-ef1e-4c74-ad88-1d2b7d69a100',
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +244,7 @@ export class SigninApiService {
|
|||
if (profile.password!.startsWith('$2')) {
|
||||
const newHash = await argon2.hash(password);
|
||||
this.userProfilesRepository.update(user.id, {
|
||||
password: newHash
|
||||
password: newHash,
|
||||
});
|
||||
}
|
||||
if (!this.meta.approvalRequiredForSignup && !user.approved) this.usersRepository.update(user.id, { approved: true });
|
||||
|
|
@ -267,7 +268,7 @@ export class SigninApiService {
|
|||
if (profile.password!.startsWith('$2')) {
|
||||
const newHash = await argon2.hash(password);
|
||||
this.userProfilesRepository.update(user.id, {
|
||||
password: newHash
|
||||
password: newHash,
|
||||
});
|
||||
}
|
||||
await this.userAuthService.twoFactorAuthenticate(profile, token);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { IsNull } from 'typeorm';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
|
@ -205,7 +204,6 @@ export class SignupApiService {
|
|||
const code = secureRndstr(16, { chars: L_CHARS });
|
||||
|
||||
// Generate hash of password
|
||||
//const salt = await bcrypt.genSalt(8);
|
||||
const hash = await argon2.hash(password);
|
||||
|
||||
const pendingUser = await this.userPendingsRepository.insertOne({
|
||||
|
|
|
|||
|
|
@ -124,9 +124,11 @@ export class StreamingApiServerService {
|
|||
const requestIp = proxyAddr(request, () => true );
|
||||
const limitActor = user?.id ?? getIpHash(requestIp);
|
||||
if (await this.rateLimitThis(limitActor, {
|
||||
// Up to 32 connections, then 1 every 10 seconds
|
||||
type: 'bucket',
|
||||
key: 'wsconnect',
|
||||
duration: ms('5min'),
|
||||
max: 32,
|
||||
size: 32,
|
||||
dripRate: 10 * 1000,
|
||||
})) {
|
||||
socket.write('HTTP/1.1 429 Rate Limit Exceeded\r\n\r\n');
|
||||
socket.destroy();
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private readonly driveFilesRepository: DriveFilesRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const file = await driveFilesRepository.findOneByOrFail({ id: ps.fileId });
|
||||
const file = await this.driveFilesRepository.findOneByOrFail({ id: ps.fileId });
|
||||
await this.moderationLogService.log(me, 'importCustomEmojis', {
|
||||
fileName: file.name,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const keys = await generateVAPIDKeys();
|
||||
|
||||
|
||||
// TODO add moderation log
|
||||
|
||||
return { public: keys.publicKey, private: keys.privateKey };
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository, UserProfilesRepository, MiMeta } from '@/models/_.js';
|
||||
|
|
|
|||
|
|
@ -404,14 +404,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
set.turnstileSecretKey = ps.turnstileSecretKey;
|
||||
}
|
||||
|
||||
if (ps.enableFC !== undefined) {
|
||||
set.enableFC = ps.enableFC;
|
||||
}
|
||||
|
||||
if (ps.enableTestcaptcha !== undefined) {
|
||||
set.enableTestcaptcha = ps.enableTestcaptcha;
|
||||
}
|
||||
|
||||
if (ps.enableFC !== undefined) {
|
||||
set.enableFC = ps.enableFC;
|
||||
}
|
||||
|
||||
if (ps.fcSiteKey !== undefined) {
|
||||
set.fcSiteKey = ps.fcSiteKey;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ export const meta = {
|
|||
|
||||
// Up to 30 calls, then 1 per 1/2 second
|
||||
limit: {
|
||||
max: 30,
|
||||
type: 'bucket',
|
||||
size: 30,
|
||||
dripRate: 500,
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ export const meta = {
|
|||
// Up to 10 calls, then 4 / second.
|
||||
// This allows for reliable automation.
|
||||
limit: {
|
||||
max: 10,
|
||||
type: 'bucket',
|
||||
size: 10,
|
||||
dripRate: 250,
|
||||
},
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ export const meta = {
|
|||
// up to 20 calls, then 1 per second.
|
||||
// This handles bursty traffic when all tabs reload as a group
|
||||
limit: {
|
||||
max: 20,
|
||||
type: 'bucket',
|
||||
size: 20,
|
||||
dripSize: 1,
|
||||
dripRate: 1000,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import * as OTPAuth from 'otpauth';
|
||||
import * as QRCode from 'qrcode';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
|
|
@ -65,7 +64,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
}
|
||||
|
||||
// Generate hash of password
|
||||
//const salt = await bcrypt.genSalt(8);
|
||||
const hash = await argon2.hash(ps.newPassword);
|
||||
|
||||
await this.userProfilesRepository.update(me.id, {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { MiMeta, UserProfilesRepository } from '@/models/_.js';
|
||||
|
|
|
|||
|
|
@ -76,11 +76,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new ApiError(meta.errors.gtlDisabled);
|
||||
}
|
||||
|
||||
const [
|
||||
followings,
|
||||
] = me ? await Promise.all([
|
||||
this.cacheService.userFollowingsCache.fetch(me.id),
|
||||
]) : [undefined];
|
||||
const followings = me ? await this.cacheService.userFollowingsCache.fetch(me.id) : {};
|
||||
|
||||
//#region Construct query
|
||||
const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'),
|
||||
|
|
|
|||
|
|
@ -100,11 +100,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
if (me) this.queryService.generateMutedUserQueryForNotes(query, me);
|
||||
if (me) this.queryService.generateBlockedUserQueryForNotes(query, me);
|
||||
|
||||
const [
|
||||
followings,
|
||||
] = me ? await Promise.all([
|
||||
this.cacheService.userFollowingsCache.fetch(me.id),
|
||||
]) : [undefined];
|
||||
const followings = me ? await this.cacheService.userFollowingsCache.fetch(me.id) : {};
|
||||
|
||||
try {
|
||||
if (ps.tag) {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
renoteId: note.id,
|
||||
});
|
||||
|
||||
// TODO inline this into the above query
|
||||
for (const note of renotes) {
|
||||
if (ps.quote) {
|
||||
if (note.text) this.noteDeleteService.delete(await this.usersRepository.findOneByOrFail({ id: me.id }), note, false);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { UserProfilesRepository, PasswordResetRequestsRepository } from '@/models/_.js';
|
||||
|
|
@ -60,7 +59,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
}
|
||||
|
||||
// Generate hash of password
|
||||
//const salt = await bcrypt.genSalt(8);
|
||||
const hash = await argon2.hash(ps.password);
|
||||
|
||||
await this.userProfilesRepository.update(req.userId, {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ export const meta = {
|
|||
|
||||
// 24 calls, then 7 per second-ish (1 for each type of server info graph)
|
||||
limit: {
|
||||
max: 24,
|
||||
type: 'bucket',
|
||||
size: 24,
|
||||
dripSize: 7,
|
||||
dripRate: 900,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ export const meta = {
|
|||
|
||||
// up to 50 calls @ 4 per second
|
||||
limit: {
|
||||
max: 50,
|
||||
type: 'bucket',
|
||||
size: 50,
|
||||
dripRate: 250,
|
||||
},
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import type Channel from './channel.js';
|
|||
|
||||
const MAX_CHANNELS_PER_CONNECTION = 32;
|
||||
const MAX_SUBSCRIPTIONS_PER_CONNECTION = 512;
|
||||
const MAX_CACHED_NOTES_PER_CONNECTION = 64;
|
||||
|
||||
/**
|
||||
* Main stream connection
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@
|
|||
import querystring from 'querystring';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
/* import { kinds } from '@/misc/api-permissions.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { DI } from '@/di-symbols.js'; */
|
||||
import multer from 'fastify-multer';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { Config } from '@/config.js';
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ export class ClientServerService {
|
|||
fastify.get('/robots.txt', async (request, reply) => {
|
||||
if (this.meta.robotsTxt) {
|
||||
reply.header('Content-Type', 'text/plain');
|
||||
return await reply.send(this.meta.robotsTxt);
|
||||
return reply.send(this.meta.robotsTxt);
|
||||
} else {
|
||||
return await reply.sendFile('/robots.txt', staticAssets);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue