Merge branch 'develop' into feat/scylladb

This commit is contained in:
Namekuji 2023-08-17 02:27:19 -04:00
commit 466c4e5636
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
11 changed files with 70 additions and 26 deletions

View file

@ -184,6 +184,9 @@ reservedUsernames: [
# deliverJobMaxAttempts: 12
# inboxJobMaxAttempts: 8
# Local address used for outgoing requests
#outgoingAddress: 127.0.0.1
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4

View file

@ -76,5 +76,5 @@ COPY --from=build /firefish/packages/backend/native-utils/built /firefish/packag
RUN corepack enable && corepack prepare pnpm@latest --activate
ENV NODE_ENV=production
VOLUME "/firefish/files"
ENTRYPOINT [ "/sbin/tini", "--" ]
ENTRYPOINT [ "/usr/bin/tini", "--" ]
CMD [ "pnpm", "run", "migrateandstart" ]

View file

@ -2099,7 +2099,7 @@ customKaTeXMacro: Individuelle KaTeX Makros
enableCustomKaTeXMacro: Individuelle KaTeX-Makros aktivieren
replayTutorial: Wiederhole die Benutzeranleitung
apps: Apps
caption: Automatische Untertitelung
caption: Automatische Beschreibung
pwa: PWA installieren
cw: Inhaltswarnung
older: älter
@ -2204,3 +2204,7 @@ deletePasskeysConfirm: Alle Passkeys und Security-Keys werden unwiderruflich von
inputNotMatch: Eingabe stimmt nicht überein
addRe: Ein "re:" am Anfang des Kommentars hinzufügen, um einem Beitrag mit einer Inhaltswarnung
zu antworten
confirm: Bestätigen
importZip: ZIP Importieren
emojiPackCreator: Emoji-Pack Ersteller
exportZip: ZIP Exportieren

View file

@ -303,7 +303,7 @@ emptyDrive: "ドライブは空です"
emptyFolder: "フォルダーは空です"
unableToDelete: "削除できません"
inputNewFileName: "新しいファイル名を入力してください"
inputNewDescription: "新しいキャプションを入力"
inputNewDescription: "新しい説明を入力"
inputNewFolderName: "新しいフォルダ名を入力してください"
circularReferenceFolder: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。"
hasChildFilesOrFolders: "このフォルダは空でないため、削除できません。"
@ -577,8 +577,8 @@ disablePlayer: "プレイヤーを閉じる"
expandTweet: "ツイートを展開する"
themeEditor: "テーマエディター"
description: "説明"
describeFile: "キャプションを追加"
enterFileDescription: "キャプションを入力"
describeFile: "説明を追加"
enterFileDescription: "説明を入力"
author: "作者"
leaveConfirm: "未保存の変更があります。破棄しますか?"
manage: "管理"
@ -949,7 +949,7 @@ customSplashIconsDescription: "ユーザがページをロード/リロードす
showUpdates: "Firefishの更新時にポップアップを表示する"
recommendedInstances: "おすすめサーバー"
recommendedInstancesDescription: "おすすめタイムラインに表示するサーバーを改行区切りで入力してください。"
caption: "自動でキャプションをつける"
caption: "自動で説明をつける"
splash: "スプラッシュスクリーン"
updateAvailable: "アップデートがありますよ!"
swipeOnDesktop: "デスクトップでモバイルスタイルのスワイプを可能にする"

View file

@ -85,6 +85,7 @@ export type Source = {
fingerprint?: string;
};
outgoingAddress?: string;
outgoingAddressFamily?: "ipv4" | "ipv6" | "dual";
deliverJobConcurrency?: number;

View file

@ -99,6 +99,7 @@ const _http = new http.Agent({
keepAlive: true,
keepAliveMsecs: 30 * 1000,
lookup: cache.lookup,
localAddress: config.outgoingAddress,
} as http.AgentOptions);
/**
@ -108,6 +109,7 @@ const _https = new https.Agent({
keepAlive: true,
keepAliveMsecs: 30 * 1000,
lookup: cache.lookup,
localAddress: config.outgoingAddress,
} as https.AgentOptions);
const maxSockets = Math.max(256, config.deliverJobConcurrency || 128);
@ -123,6 +125,7 @@ export const httpAgent = config.proxy
maxFreeSockets: 256,
scheduling: "lifo",
proxy: config.proxy,
localAddress: config.outgoingAddress,
})
: _http;
@ -137,6 +140,7 @@ export const httpsAgent = config.proxy
maxFreeSockets: 256,
scheduling: "lifo",
proxy: config.proxy,
localAddress: config.outgoingAddress,
})
: _https;

View file

@ -122,19 +122,31 @@ export default class DeliverManager {
)
.forEach((recipe) => inboxes.add(recipe.to.inbox!));
// Validate Inboxes first
const validInboxes = [];
for (const inbox of inboxes) {
try {
validInboxes.push({
inbox,
host: new URL(inbox).host,
});
} catch (error) {
console.error(error);
console.error(`Invalid Inbox ${inbox}`);
}
}
const instancesToSkip = await skippedInstances(
// get (unique) list of hosts
Array.from(
new Set(Array.from(inboxes).map((inbox) => new URL(inbox).host)),
),
Array.from(new Set(validInboxes.map((valid) => valid.host))),
);
// deliver
for (const inbox of inboxes) {
for (const valid of validInboxes) {
// skip instances as indicated
if (instancesToSkip.includes(new URL(inbox).host)) continue;
if (instancesToSkip.includes(valid.host)) continue;
deliver(this.actor, this.activity, inbox);
deliver(this.actor, this.activity, valid.inbox);
}
}
}

View file

@ -1,4 +1,4 @@
import * as sanitizeHtml from "sanitize-html";
import sanitizeHtml from "sanitize-html";
import define from "../../define.js";
import { Users, UserProfiles } from "@/models/index.js";
import { ApiError } from "../../error.js";

View file

@ -1,12 +1,14 @@
import * as sanitizeHtml from "sanitize-html";
import * as mfm from "mfm-js";
import sanitizeHtml from "sanitize-html";
import { publishAdminStream } from "@/services/stream.js";
import { AbuseUserReports, Users } from "@/models/index.js";
import { AbuseUserReports, UserProfiles, Users } from "@/models/index.js";
import { genId } from "@/misc/gen-id.js";
import { sendEmail } from "@/services/send-email.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
import { getUser } from "../../common/getters.js";
import { ApiError } from "../../error.js";
import define from "../../define.js";
import { toHtml } from "@/mfm/to-html.js";
export const meta = {
tags: ["users"],
@ -84,6 +86,7 @@ export default define(meta, paramDef, async (ps, me) => {
],
});
const meta = await fetchMeta();
for (const moderator of moderators) {
publishAdminStream(moderator.id, "newAbuseUserReport", {
id: report.id,
@ -91,16 +94,16 @@ export default define(meta, paramDef, async (ps, me) => {
reporterId: report.reporterId,
comment: report.comment,
});
}
const meta = await fetchMeta();
if (meta.email) {
const profile = await UserProfiles.findOneBy({ userId: moderator.id });
if (profile?.email) {
sendEmail(
meta.email,
profile.email,
"New abuse report",
sanitizeHtml(ps.comment),
sanitizeHtml(ps.comment),
sanitizeHtml(toHtml(mfm.parse(ps.comment))!),
sanitizeHtml(toHtml(mfm.parse(ps.comment))!),
);
}
}
});
});

View file

@ -74,3 +74,13 @@ export function convertStatus(status: Entity.Status) {
return status;
}
export function convertConversation(conversation: Entity.Conversation) {
conversation.id = convertId(conversation.id, IdType.MastodonId);
conversation.accounts = conversation.accounts.map(convertAccount);
if (conversation.last_status) {
conversation.last_status = convertStatus(conversation.last_status);
}
return conversation;
}

View file

@ -1,7 +1,12 @@
import Router from "@koa/router";
import { getClient } from "../ApiMastodonCompatibleService.js";
import { ParsedUrlQuery } from "querystring";
import { convertAccount, convertList, convertStatus } from "../converters.js";
import {
convertAccount,
convertConversation,
convertList,
convertStatus,
} from "../converters.js";
import { convertId, IdType } from "../../index.js";
export function limitToInt(q: ParsedUrlQuery) {
@ -136,7 +141,9 @@ export function apiTimelineMastodon(router: Router): void {
const data = await client.getConversationTimeline(
convertTimelinesArgsId(limitToInt(ctx.query)),
);
ctx.body = data.data;
ctx.body = data.data.map((conversation) =>
convertConversation(conversation),
);
} catch (e: any) {
console.error(e);
console.error(e.response.data);