mirror of
https://git.joinfirefish.org/firefish/firefish.git
synced 2024-05-19 09:01:10 +02:00
refactor (backend): port should-block-instance to backend-rs
This commit is contained in:
parent
cbd15fb2ca
commit
0c1e7cdd72
17
packages/backend-rs/index.d.ts
vendored
17
packages/backend-rs/index.d.ts
vendored
|
@ -193,6 +193,21 @@ export interface Acct {
|
||||||
}
|
}
|
||||||
export function stringToAcct(acct: string): Acct
|
export function stringToAcct(acct: string): Acct
|
||||||
export function acctToString(acct: Acct): string
|
export function acctToString(acct: Acct): string
|
||||||
|
/**
|
||||||
|
* @param host punycoded instance host
|
||||||
|
* @returns whether the given host should be blocked
|
||||||
|
*/
|
||||||
|
export function isBlockedServer(host: string): Promise<boolean>
|
||||||
|
/**
|
||||||
|
* @param host punycoded instance host
|
||||||
|
* @returns whether the given host should be limited
|
||||||
|
*/
|
||||||
|
export function isSilencedServer(host: string): Promise<boolean>
|
||||||
|
/**
|
||||||
|
* @param host punycoded instance host
|
||||||
|
* @returns whether the given host is allowlisted (this is always true if private mode is disabled)
|
||||||
|
*/
|
||||||
|
export function isAllowedServer(host: string): Promise<boolean>
|
||||||
/** TODO: handle name collisions better */
|
/** TODO: handle name collisions better */
|
||||||
export interface NoteLikeForCheckWordMute {
|
export interface NoteLikeForCheckWordMute {
|
||||||
fileIds: Array<string>
|
fileIds: Array<string>
|
||||||
|
@ -557,7 +572,6 @@ export interface Meta {
|
||||||
recaptchaSecretKey: string | null
|
recaptchaSecretKey: string | null
|
||||||
localDriveCapacityMb: number
|
localDriveCapacityMb: number
|
||||||
remoteDriveCapacityMb: number
|
remoteDriveCapacityMb: number
|
||||||
antennaLimit: number
|
|
||||||
summalyProxy: string | null
|
summalyProxy: string | null
|
||||||
enableEmail: boolean
|
enableEmail: boolean
|
||||||
email: string | null
|
email: string | null
|
||||||
|
@ -620,6 +634,7 @@ export interface Meta {
|
||||||
donationLink: string | null
|
donationLink: string | null
|
||||||
moreUrls: Json
|
moreUrls: Json
|
||||||
markLocalFilesNsfwByDefault: boolean
|
markLocalFilesNsfwByDefault: boolean
|
||||||
|
antennaLimit: number
|
||||||
}
|
}
|
||||||
export interface Migrations {
|
export interface Migrations {
|
||||||
id: number
|
id: number
|
||||||
|
|
|
@ -310,12 +310,15 @@ if (!nativeBinding) {
|
||||||
throw new Error(`Failed to load native binding`)
|
throw new Error(`Failed to load native binding`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { loadEnv, loadConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, DriveFileUsageHintEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, addNoteToAntenna, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding
|
const { loadEnv, loadConfig, stringToAcct, acctToString, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, DriveFileUsageHintEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, addNoteToAntenna, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding
|
||||||
|
|
||||||
module.exports.loadEnv = loadEnv
|
module.exports.loadEnv = loadEnv
|
||||||
module.exports.loadConfig = loadConfig
|
module.exports.loadConfig = loadConfig
|
||||||
module.exports.stringToAcct = stringToAcct
|
module.exports.stringToAcct = stringToAcct
|
||||||
module.exports.acctToString = acctToString
|
module.exports.acctToString = acctToString
|
||||||
|
module.exports.isBlockedServer = isBlockedServer
|
||||||
|
module.exports.isSilencedServer = isSilencedServer
|
||||||
|
module.exports.isAllowedServer = isAllowedServer
|
||||||
module.exports.checkWordMute = checkWordMute
|
module.exports.checkWordMute = checkWordMute
|
||||||
module.exports.getFullApAccount = getFullApAccount
|
module.exports.getFullApAccount = getFullApAccount
|
||||||
module.exports.isSelfHost = isSelfHost
|
module.exports.isSelfHost = isSelfHost
|
||||||
|
|
49
packages/backend-rs/src/misc/check_server_block.rs
Normal file
49
packages/backend-rs/src/misc/check_server_block.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use crate::misc::meta::fetch_meta;
|
||||||
|
use sea_orm::DbErr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param host punycoded instance host
|
||||||
|
* @returns whether the given host should be blocked
|
||||||
|
*/
|
||||||
|
#[crate::export]
|
||||||
|
pub async fn is_blocked_server(host: &str) -> Result<bool, DbErr> {
|
||||||
|
Ok(fetch_meta(true)
|
||||||
|
.await?
|
||||||
|
.blocked_hosts
|
||||||
|
.iter()
|
||||||
|
.any(|blocked_host| {
|
||||||
|
host == blocked_host || host.ends_with(format!(".{}", blocked_host).as_str())
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param host punycoded instance host
|
||||||
|
* @returns whether the given host should be limited
|
||||||
|
*/
|
||||||
|
#[crate::export]
|
||||||
|
pub async fn is_silenced_server(host: &str) -> Result<bool, DbErr> {
|
||||||
|
Ok(fetch_meta(true)
|
||||||
|
.await?
|
||||||
|
.silenced_hosts
|
||||||
|
.iter()
|
||||||
|
.any(|silenced_host| {
|
||||||
|
host == silenced_host || host.ends_with(format!(".{}", silenced_host).as_str())
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param host punycoded instance host
|
||||||
|
* @returns whether the given host is allowlisted (this is always true if private mode is disabled)
|
||||||
|
*/
|
||||||
|
#[crate::export]
|
||||||
|
pub async fn is_allowed_server(host: &str) -> Result<bool, DbErr> {
|
||||||
|
let meta = fetch_meta(true).await?;
|
||||||
|
|
||||||
|
if !meta.private_mode.unwrap_or(false) {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
if let Some(allowed_hosts) = meta.allowed_hosts {
|
||||||
|
return Ok(allowed_hosts.contains(&host.to_string()));
|
||||||
|
}
|
||||||
|
Ok(false)
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod acct;
|
pub mod acct;
|
||||||
|
pub mod check_server_block;
|
||||||
pub mod check_word_mute;
|
pub mod check_word_mute;
|
||||||
pub mod convert_host;
|
pub mod convert_host;
|
||||||
pub mod emoji;
|
pub mod emoji;
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { fetchMeta } from "backend-rs";
|
|
||||||
import type { Instance } from "@/models/entities/instance.js";
|
|
||||||
import type { Meta } from "@/models/entities/meta.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether a specific host (punycoded) should be blocked.
|
|
||||||
*
|
|
||||||
* @param host punycoded instance host
|
|
||||||
* @param meta a resolved Meta table
|
|
||||||
* @returns whether the given host should be blocked
|
|
||||||
*/
|
|
||||||
export async function shouldBlockInstance(
|
|
||||||
host: Instance["host"],
|
|
||||||
meta?: Meta,
|
|
||||||
): Promise<boolean> {
|
|
||||||
const { blockedHosts } = meta ?? (await fetchMeta(true));
|
|
||||||
return blockedHosts.some(
|
|
||||||
(blockedHost) => host === blockedHost || host.endsWith(`.${blockedHost}`),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether a specific host (punycoded) should be limited.
|
|
||||||
*
|
|
||||||
* @param host punycoded instance host
|
|
||||||
* @param meta a resolved Meta table
|
|
||||||
* @returns whether the given host should be limited
|
|
||||||
*/
|
|
||||||
export async function shouldSilenceInstance(
|
|
||||||
host: Instance["host"],
|
|
||||||
meta?: Meta,
|
|
||||||
): Promise<boolean> {
|
|
||||||
const { silencedHosts } = meta ?? (await fetchMeta(true));
|
|
||||||
return silencedHosts.some(
|
|
||||||
(silencedHost) =>
|
|
||||||
host === silencedHost || host.endsWith(`.${silencedHost}`),
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { Brackets } from "typeorm";
|
import { Brackets } from "typeorm";
|
||||||
import { fetchMeta } from "backend-rs";
|
import { isBlockedServer } from "backend-rs";
|
||||||
import { Instances } from "@/models/index.js";
|
import { Instances } from "@/models/index.js";
|
||||||
import type { Instance } from "@/models/entities/instance.js";
|
import type { Instance } from "@/models/entities/instance.js";
|
||||||
import { DAY } from "@/const.js";
|
import { DAY } from "@/const.js";
|
||||||
import { shouldBlockInstance } from "./should-block-instance.js";
|
|
||||||
|
|
||||||
// Threshold from last contact after which an instance will be considered
|
// Threshold from last contact after which an instance will be considered
|
||||||
// "dead" and should no longer get activities delivered to it.
|
// "dead" and should no longer get activities delivered to it.
|
||||||
|
@ -19,16 +18,16 @@ export async function skippedInstances(
|
||||||
hosts: Instance["host"][],
|
hosts: Instance["host"][],
|
||||||
): Promise<Instance["host"][]> {
|
): Promise<Instance["host"][]> {
|
||||||
// first check for blocked instances since that info may already be in memory
|
// first check for blocked instances since that info may already be in memory
|
||||||
const meta = await fetchMeta(true);
|
|
||||||
const shouldSkip = await Promise.all(
|
const shouldSkip = await Promise.all(
|
||||||
hosts.map((host) => shouldBlockInstance(host, meta)),
|
hosts.map((host) => isBlockedServer(host)),
|
||||||
);
|
);
|
||||||
const skipped = hosts.filter((_, i) => shouldSkip[i]);
|
const skipped = hosts.filter((_, i) => shouldSkip[i]);
|
||||||
|
|
||||||
// if possible return early and skip accessing the database
|
// if possible return early and skip accessing the database
|
||||||
if (skipped.length === hosts.length) return hosts;
|
if (skipped.length === hosts.length) return hosts;
|
||||||
|
|
||||||
const deadTime = new Date(Date.now() - deadThreshold);
|
// FIXME: Use or remove this
|
||||||
|
// const deadTime = new Date(Date.now() - deadThreshold);
|
||||||
|
|
||||||
return skipped.concat(
|
return skipped.concat(
|
||||||
await Instances.createQueryBuilder("instance")
|
await Instances.createQueryBuilder("instance")
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import { db } from "@/db/postgre.js";
|
import { db } from "@/db/postgre.js";
|
||||||
import { Instance } from "@/models/entities/instance.js";
|
import { Instance } from "@/models/entities/instance.js";
|
||||||
import type { Packed } from "@/misc/schema.js";
|
import type { Packed } from "@/misc/schema.js";
|
||||||
import {
|
import { isBlockedServer, isSilencedServer } from "backend-rs";
|
||||||
shouldBlockInstance,
|
|
||||||
shouldSilenceInstance,
|
|
||||||
} from "@/misc/should-block-instance.js";
|
|
||||||
|
|
||||||
export const InstanceRepository = db.getRepository(Instance).extend({
|
export const InstanceRepository = db.getRepository(Instance).extend({
|
||||||
async pack(instance: Instance): Promise<Packed<"FederationInstance">> {
|
async pack(instance: Instance): Promise<Packed<"FederationInstance">> {
|
||||||
|
@ -22,8 +19,8 @@ export const InstanceRepository = db.getRepository(Instance).extend({
|
||||||
lastCommunicatedAt: instance.lastCommunicatedAt.toISOString(),
|
lastCommunicatedAt: instance.lastCommunicatedAt.toISOString(),
|
||||||
isNotResponding: instance.isNotResponding,
|
isNotResponding: instance.isNotResponding,
|
||||||
isSuspended: instance.isSuspended,
|
isSuspended: instance.isSuspended,
|
||||||
isBlocked: await shouldBlockInstance(instance.host),
|
isBlocked: await isBlockedServer(instance.host),
|
||||||
isSilenced: await shouldSilenceInstance(instance.host),
|
isSilenced: await isSilencedServer(instance.host),
|
||||||
softwareName: instance.softwareName,
|
softwareName: instance.softwareName,
|
||||||
softwareVersion: instance.softwareVersion,
|
softwareVersion: instance.softwareVersion,
|
||||||
openRegistrations: instance.openRegistrations,
|
openRegistrations: instance.openRegistrations,
|
||||||
|
|
|
@ -5,7 +5,7 @@ import perform from "@/remote/activitypub/perform.js";
|
||||||
import Logger from "@/services/logger.js";
|
import Logger from "@/services/logger.js";
|
||||||
import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instance-doc.js";
|
import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instance-doc.js";
|
||||||
import { Instances } from "@/models/index.js";
|
import { Instances } from "@/models/index.js";
|
||||||
import { fetchMeta } from "backend-rs";
|
import { isAllowedServer, isBlockedServer } from "backend-rs";
|
||||||
import { toPuny, extractHost } from "backend-rs";
|
import { toPuny, extractHost } from "backend-rs";
|
||||||
import { getApId } from "@/remote/activitypub/type.js";
|
import { getApId } from "@/remote/activitypub/type.js";
|
||||||
import { fetchInstanceMetadata } from "@/services/fetch-instance-metadata.js";
|
import { fetchInstanceMetadata } from "@/services/fetch-instance-metadata.js";
|
||||||
|
@ -16,7 +16,6 @@ import { LdSignature } from "@/remote/activitypub/misc/ld-signature.js";
|
||||||
import { StatusError } from "@/misc/fetch.js";
|
import { StatusError } from "@/misc/fetch.js";
|
||||||
import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
||||||
import type { UserPublickey } from "@/models/entities/user-publickey.js";
|
import type { UserPublickey } from "@/models/entities/user-publickey.js";
|
||||||
import { shouldBlockInstance } from "@/misc/should-block-instance.js";
|
|
||||||
import { verifySignature } from "@/remote/activitypub/check-fetch.js";
|
import { verifySignature } from "@/remote/activitypub/check-fetch.js";
|
||||||
import { inspect } from "node:util";
|
import { inspect } from "node:util";
|
||||||
|
|
||||||
|
@ -41,13 +40,12 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
|
||||||
const host = toPuny(new URL(signature.keyId).hostname);
|
const host = toPuny(new URL(signature.keyId).hostname);
|
||||||
|
|
||||||
// interrupt if blocked
|
// interrupt if blocked
|
||||||
const meta = await fetchMeta(true);
|
if (await isBlockedServer(host)) {
|
||||||
if (await shouldBlockInstance(host, meta)) {
|
|
||||||
return `Blocked request: ${host}`;
|
return `Blocked request: ${host}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// only whitelisted instances in private mode
|
// only whitelisted instances in private mode
|
||||||
if (meta.privateMode && !meta.allowedHosts.includes(host)) {
|
if (!isAllowedServer(host)) {
|
||||||
return `Blocked request: ${host}`;
|
return `Blocked request: ${host}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +156,7 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
|
||||||
|
|
||||||
// ブロックしてたら中断
|
// ブロックしてたら中断
|
||||||
const ldHost = extractHost(authUser.user.uri);
|
const ldHost = extractHost(authUser.user.uri);
|
||||||
if (await shouldBlockInstance(ldHost, meta)) {
|
if (await isBlockedServer(ldHost)) {
|
||||||
return `Blocked request: ${ldHost}`;
|
return `Blocked request: ${ldHost}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import { URL } from "url";
|
import { URL } from "url";
|
||||||
import httpSignature, { IParsedSignature } from "@peertube/http-signature";
|
import httpSignature, { type IParsedSignature } from "@peertube/http-signature";
|
||||||
import { config } from "@/config.js";
|
import { config } from "@/config.js";
|
||||||
import { fetchMeta } from "backend-rs";
|
import { fetchMeta, isAllowedServer, isBlockedServer } from "backend-rs";
|
||||||
import { toPuny } from "backend-rs";
|
import { toPuny } from "backend-rs";
|
||||||
import DbResolver from "@/remote/activitypub/db-resolver.js";
|
import DbResolver from "@/remote/activitypub/db-resolver.js";
|
||||||
import { getApId } from "@/remote/activitypub/type.js";
|
import { getApId } from "@/remote/activitypub/type.js";
|
||||||
import { shouldBlockInstance } from "@/misc/should-block-instance.js";
|
|
||||||
import type { IncomingMessage } from "http";
|
import type { IncomingMessage } from "http";
|
||||||
import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
||||||
import type { UserPublickey } from "@/models/entities/user-publickey.js";
|
import type { UserPublickey } from "@/models/entities/user-publickey.js";
|
||||||
|
@ -44,15 +43,11 @@ export async function checkFetch(req: IncomingMessage): Promise<number> {
|
||||||
const keyId = new URL(signature.keyId);
|
const keyId = new URL(signature.keyId);
|
||||||
const host = toPuny(keyId.hostname);
|
const host = toPuny(keyId.hostname);
|
||||||
|
|
||||||
if (await shouldBlockInstance(host, meta)) {
|
if (await isBlockedServer(host)) {
|
||||||
return 403;
|
return 403;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (host !== config.host && !isAllowedServer(host)) {
|
||||||
meta.privateMode &&
|
|
||||||
host !== config.host &&
|
|
||||||
!meta.allowedHosts.includes(host)
|
|
||||||
) {
|
|
||||||
return 403;
|
return 403;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { getApLock } from "@/misc/app-lock.js";
|
||||||
import { parseAudience } from "../../audience.js";
|
import { parseAudience } from "../../audience.js";
|
||||||
import { StatusError } from "@/misc/fetch.js";
|
import { StatusError } from "@/misc/fetch.js";
|
||||||
import { Notes } from "@/models/index.js";
|
import { Notes } from "@/models/index.js";
|
||||||
import { shouldBlockInstance } from "@/misc/should-block-instance.js";
|
import { isBlockedServer } from "backend-rs";
|
||||||
import { inspect } from "node:util";
|
import { inspect } from "node:util";
|
||||||
|
|
||||||
const logger = apLogger;
|
const logger = apLogger;
|
||||||
|
@ -31,7 +31,7 @@ export default async function (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interrupt if you block the announcement destination
|
// Interrupt if you block the announcement destination
|
||||||
if (await shouldBlockInstance(extractHost(uri))) return;
|
if (await isBlockedServer(extractHost(uri))) return;
|
||||||
|
|
||||||
const lock = await getApLock(uri);
|
const lock = await getApLock(uri);
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,7 @@ import block from "./block/index.js";
|
||||||
import flag from "./flag/index.js";
|
import flag from "./flag/index.js";
|
||||||
import move from "./move/index.js";
|
import move from "./move/index.js";
|
||||||
import type { IObject, IActivity } from "../type.js";
|
import type { IObject, IActivity } from "../type.js";
|
||||||
import { extractHost } from "backend-rs";
|
import { extractHost, isBlockedServer } from "backend-rs";
|
||||||
import { shouldBlockInstance } from "@/misc/should-block-instance.js";
|
|
||||||
import { inspect } from "node:util";
|
import { inspect } from "node:util";
|
||||||
|
|
||||||
export async function performActivity(
|
export async function performActivity(
|
||||||
|
@ -71,7 +70,7 @@ async function performOneActivity(
|
||||||
|
|
||||||
if (typeof activity.id !== "undefined") {
|
if (typeof activity.id !== "undefined") {
|
||||||
const host = extractHost(getApId(activity));
|
const host = extractHost(getApId(activity));
|
||||||
if (await shouldBlockInstance(host)) return;
|
if (await isBlockedServer(host)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCreate(activity)) {
|
if (isCreate(activity)) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { unique, toArray, toSingle } from "@/prelude/array.js";
|
||||||
import { extractPollFromQuestion } from "./question.js";
|
import { extractPollFromQuestion } from "./question.js";
|
||||||
import vote from "@/services/note/polls/vote.js";
|
import vote from "@/services/note/polls/vote.js";
|
||||||
import { apLogger } from "../logger.js";
|
import { apLogger } from "../logger.js";
|
||||||
import { DriveFile } from "@/models/entities/drive-file.js";
|
import type { DriveFile } from "@/models/entities/drive-file.js";
|
||||||
import { extractHost, isSameOrigin, toPuny } from "backend-rs";
|
import { extractHost, isSameOrigin, toPuny } from "backend-rs";
|
||||||
import {
|
import {
|
||||||
Emojis,
|
Emojis,
|
||||||
|
@ -33,14 +33,13 @@ import {
|
||||||
getApType,
|
getApType,
|
||||||
} from "../type.js";
|
} from "../type.js";
|
||||||
import type { Emoji } from "@/models/entities/emoji.js";
|
import type { Emoji } from "@/models/entities/emoji.js";
|
||||||
import { genId } from "backend-rs";
|
import { genId, isBlockedServer } from "backend-rs";
|
||||||
import { getApLock } from "@/misc/app-lock.js";
|
import { getApLock } from "@/misc/app-lock.js";
|
||||||
import { createMessage } from "@/services/messages/create.js";
|
import { createMessage } from "@/services/messages/create.js";
|
||||||
import { parseAudience } from "../audience.js";
|
import { parseAudience } from "../audience.js";
|
||||||
import { extractApMentions } from "./mention.js";
|
import { extractApMentions } from "./mention.js";
|
||||||
import DbResolver from "../db-resolver.js";
|
import DbResolver from "../db-resolver.js";
|
||||||
import { StatusError } from "@/misc/fetch.js";
|
import { StatusError } from "@/misc/fetch.js";
|
||||||
import { shouldBlockInstance } from "@/misc/should-block-instance.js";
|
|
||||||
import { publishNoteStream } from "@/services/stream.js";
|
import { publishNoteStream } from "@/services/stream.js";
|
||||||
import { extractHashtags } from "@/misc/extract-hashtags.js";
|
import { extractHashtags } from "@/misc/extract-hashtags.js";
|
||||||
import { UserProfiles } from "@/models/index.js";
|
import { UserProfiles } from "@/models/index.js";
|
||||||
|
@ -421,7 +420,7 @@ export async function resolveNote(
|
||||||
if (uri == null) throw new Error("missing uri");
|
if (uri == null) throw new Error("missing uri");
|
||||||
|
|
||||||
// Abort if origin host is blocked
|
// Abort if origin host is blocked
|
||||||
if (await shouldBlockInstance(extractHost(uri)))
|
if (await isBlockedServer(extractHost(uri)))
|
||||||
throw new StatusError(
|
throw new StatusError(
|
||||||
"host blocked",
|
"host blocked",
|
||||||
451,
|
451,
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import { config } from "@/config.js";
|
import { config } from "@/config.js";
|
||||||
import type { ILocalUser } from "@/models/entities/user.js";
|
import type { ILocalUser } from "@/models/entities/user.js";
|
||||||
import { getInstanceActor } from "@/services/instance-actor.js";
|
import { getInstanceActor } from "@/services/instance-actor.js";
|
||||||
import { fetchMeta } from "backend-rs";
|
import {
|
||||||
import { extractHost, isSelfHost } from "backend-rs";
|
extractHost,
|
||||||
|
isAllowedServer,
|
||||||
|
isBlockedServer,
|
||||||
|
isSelfHost,
|
||||||
|
} from "backend-rs";
|
||||||
import { apGet } from "./request.js";
|
import { apGet } from "./request.js";
|
||||||
import type { IObject, ICollection, IOrderedCollection } from "./type.js";
|
import type { IObject, ICollection, IOrderedCollection } from "./type.js";
|
||||||
import { isCollectionOrOrderedCollection, getApId } from "./type.js";
|
import { isCollectionOrOrderedCollection, getApId } from "./type.js";
|
||||||
|
@ -21,7 +25,6 @@ import renderQuestion from "@/remote/activitypub/renderer/question.js";
|
||||||
import renderCreate from "@/remote/activitypub/renderer/create.js";
|
import renderCreate from "@/remote/activitypub/renderer/create.js";
|
||||||
import { renderActivity } from "@/remote/activitypub/renderer/index.js";
|
import { renderActivity } from "@/remote/activitypub/renderer/index.js";
|
||||||
import renderFollow from "@/remote/activitypub/renderer/follow.js";
|
import renderFollow from "@/remote/activitypub/renderer/follow.js";
|
||||||
import { shouldBlockInstance } from "@/misc/should-block-instance.js";
|
|
||||||
import { apLogger } from "@/remote/activitypub/logger.js";
|
import { apLogger } from "@/remote/activitypub/logger.js";
|
||||||
import { IsNull, Not } from "typeorm";
|
import { IsNull, Not } from "typeorm";
|
||||||
|
|
||||||
|
@ -69,7 +72,7 @@ export default class Resolver {
|
||||||
apLogger.debug("Object to resolve is not a string");
|
apLogger.debug("Object to resolve is not a string");
|
||||||
if (typeof value.id !== "undefined") {
|
if (typeof value.id !== "undefined") {
|
||||||
const host = extractHost(getApId(value));
|
const host = extractHost(getApId(value));
|
||||||
if (await shouldBlockInstance(host)) {
|
if (await isBlockedServer(host)) {
|
||||||
throw new Error("instance is blocked");
|
throw new Error("instance is blocked");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,17 +103,12 @@ export default class Resolver {
|
||||||
return await this.resolveLocal(value);
|
return await this.resolveLocal(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const meta = await fetchMeta(true);
|
if (await isBlockedServer(host)) {
|
||||||
if (await shouldBlockInstance(host, meta)) {
|
throw new Error("This instance is blocked");
|
||||||
throw new Error("Instance is blocked");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (config.host !== host && !isAllowedServer(host)) {
|
||||||
meta.privateMode &&
|
throw new Error("This instance is not allowed");
|
||||||
config.host !== host &&
|
|
||||||
!meta.allowedHosts.includes(host)
|
|
||||||
) {
|
|
||||||
throw new Error("Instance is not allowed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.user) {
|
if (!this.user) {
|
||||||
|
|
|
@ -4,14 +4,13 @@ import { createNote } from "@/remote/activitypub/models/note.js";
|
||||||
import DbResolver from "@/remote/activitypub/db-resolver.js";
|
import DbResolver from "@/remote/activitypub/db-resolver.js";
|
||||||
import Resolver from "@/remote/activitypub/resolver.js";
|
import Resolver from "@/remote/activitypub/resolver.js";
|
||||||
import { ApiError } from "@/server/api/error.js";
|
import { ApiError } from "@/server/api/error.js";
|
||||||
import { extractHost } from "backend-rs";
|
import { extractHost, isBlockedServer } from "backend-rs";
|
||||||
import { Users, Notes } from "@/models/index.js";
|
import { Users, Notes } from "@/models/index.js";
|
||||||
import type { Note } from "@/models/entities/note.js";
|
import type { Note } from "@/models/entities/note.js";
|
||||||
import type { CacheableLocalUser, User } from "@/models/entities/user.js";
|
import type { CacheableLocalUser, User } from "@/models/entities/user.js";
|
||||||
import { isActor, isPost, getApId } from "@/remote/activitypub/type.js";
|
import { isActor, isPost, getApId } from "@/remote/activitypub/type.js";
|
||||||
import type { SchemaType } from "@/misc/schema.js";
|
import type { SchemaType } from "@/misc/schema.js";
|
||||||
import { MINUTE } from "@/const.js";
|
import { MINUTE } from "@/const.js";
|
||||||
import { shouldBlockInstance } from "@/misc/should-block-instance.js";
|
|
||||||
import { updateQuestion } from "@/remote/activitypub/models/question.js";
|
import { updateQuestion } from "@/remote/activitypub/models/question.js";
|
||||||
import { populatePoll } from "@/models/repositories/note.js";
|
import { populatePoll } from "@/models/repositories/note.js";
|
||||||
import { redisClient } from "@/db/redis.js";
|
import { redisClient } from "@/db/redis.js";
|
||||||
|
@ -101,7 +100,7 @@ async function fetchAny(
|
||||||
me: CacheableLocalUser | null | undefined,
|
me: CacheableLocalUser | null | undefined,
|
||||||
): Promise<SchemaType<(typeof meta)["res"]> | null> {
|
): Promise<SchemaType<(typeof meta)["res"]> | null> {
|
||||||
// Wait if blocked.
|
// Wait if blocked.
|
||||||
if (await shouldBlockInstance(extractHost(uri))) return null;
|
if (await isBlockedServer(extractHost(uri))) return null;
|
||||||
|
|
||||||
const dbResolver = new DbResolver();
|
const dbResolver = new DbResolver();
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,10 @@ import {
|
||||||
Users,
|
Users,
|
||||||
Followings,
|
Followings,
|
||||||
} from "@/models/index.js";
|
} from "@/models/index.js";
|
||||||
import { genId } from "backend-rs";
|
import { genId, isSilencedServer } from "backend-rs";
|
||||||
import type { User } from "@/models/entities/user.js";
|
import type { User } from "@/models/entities/user.js";
|
||||||
import type { Notification } from "@/models/entities/notification.js";
|
import type { Notification } from "@/models/entities/notification.js";
|
||||||
import { sendEmailNotification } from "./send-email-notification.js";
|
import { sendEmailNotification } from "./send-email-notification.js";
|
||||||
import { shouldSilenceInstance } from "@/misc/should-block-instance.js";
|
|
||||||
|
|
||||||
export async function createNotification(
|
export async function createNotification(
|
||||||
notifieeId: User["id"],
|
notifieeId: User["id"],
|
||||||
|
@ -35,8 +34,8 @@ export async function createNotification(
|
||||||
if (
|
if (
|
||||||
(notifier.isSilenced ||
|
(notifier.isSilenced ||
|
||||||
(Users.isRemoteUser(notifier) &&
|
(Users.isRemoteUser(notifier) &&
|
||||||
(await shouldSilenceInstance(notifier.host)))) &&
|
(await isSilencedServer(notifier.host)))) &&
|
||||||
!(await Followings.exist({
|
!(await Followings.exists({
|
||||||
where: { followerId: notifieeId, followeeId: data.notifierId },
|
where: { followerId: notifieeId, followeeId: data.notifierId },
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,13 +17,12 @@ import {
|
||||||
Instances,
|
Instances,
|
||||||
UserProfiles,
|
UserProfiles,
|
||||||
} from "@/models/index.js";
|
} from "@/models/index.js";
|
||||||
import { genId } from "backend-rs";
|
import { genId, isSilencedServer } from "backend-rs";
|
||||||
import { createNotification } from "@/services/create-notification.js";
|
import { createNotification } from "@/services/create-notification.js";
|
||||||
import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
|
import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
|
||||||
import type { Packed } from "@/misc/schema.js";
|
import type { Packed } from "@/misc/schema.js";
|
||||||
import { getActiveWebhooks } from "@/misc/webhook-cache.js";
|
import { getActiveWebhooks } from "@/misc/webhook-cache.js";
|
||||||
import { webhookDeliver } from "@/queue/index.js";
|
import { webhookDeliver } from "@/queue/index.js";
|
||||||
import { shouldSilenceInstance } from "@/misc/should-block-instance.js";
|
|
||||||
|
|
||||||
const logger = new Logger("following/create");
|
const logger = new Logger("following/create");
|
||||||
|
|
||||||
|
@ -231,7 +230,7 @@ export default async function (
|
||||||
(Users.isLocalUser(follower) && Users.isRemoteUser(followee)) ||
|
(Users.isLocalUser(follower) && Users.isRemoteUser(followee)) ||
|
||||||
(Users.isRemoteUser(follower) &&
|
(Users.isRemoteUser(follower) &&
|
||||||
Users.isLocalUser(followee) &&
|
Users.isLocalUser(followee) &&
|
||||||
(await shouldSilenceInstance(follower.host)))
|
(await isSilencedServer(follower.host)))
|
||||||
) {
|
) {
|
||||||
let autoAccept = false;
|
let autoAccept = false;
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,18 @@ import type { DriveFile } from "@/models/entities/drive-file.js";
|
||||||
import type { App } from "@/models/entities/app.js";
|
import type { App } from "@/models/entities/app.js";
|
||||||
import { Not, In } from "typeorm";
|
import { Not, In } from "typeorm";
|
||||||
import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js";
|
import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js";
|
||||||
import { genId } from "backend-rs";
|
|
||||||
import { activeUsersChart } from "@/services/chart/index.js";
|
import { activeUsersChart } from "@/services/chart/index.js";
|
||||||
import type { IPoll } from "@/models/entities/poll.js";
|
import type { IPoll } from "@/models/entities/poll.js";
|
||||||
import { Poll } from "@/models/entities/poll.js";
|
import { Poll } from "@/models/entities/poll.js";
|
||||||
import { createNotification } from "@/services/create-notification.js";
|
import { createNotification } from "@/services/create-notification.js";
|
||||||
import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
|
import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
|
||||||
import { checkHitAntenna } from "@/misc/check-hit-antenna.js";
|
import { checkHitAntenna } from "@/misc/check-hit-antenna.js";
|
||||||
import { addNoteToAntenna, checkWordMute } from "backend-rs";
|
import {
|
||||||
|
addNoteToAntenna,
|
||||||
|
checkWordMute,
|
||||||
|
genId,
|
||||||
|
isSilencedServer,
|
||||||
|
} from "backend-rs";
|
||||||
import { countSameRenotes } from "@/misc/count-same-renotes.js";
|
import { countSameRenotes } from "@/misc/count-same-renotes.js";
|
||||||
import { deliverToRelays, getCachedRelays } from "../relay.js";
|
import { deliverToRelays, getCachedRelays } from "../relay.js";
|
||||||
import type { Channel } from "@/models/entities/channel.js";
|
import type { Channel } from "@/models/entities/channel.js";
|
||||||
|
@ -56,7 +60,6 @@ import { Cache } from "@/misc/cache.js";
|
||||||
import type { UserProfile } from "@/models/entities/user-profile.js";
|
import type { UserProfile } from "@/models/entities/user-profile.js";
|
||||||
import { db } from "@/db/postgre.js";
|
import { db } from "@/db/postgre.js";
|
||||||
import { getActiveWebhooks } from "@/misc/webhook-cache.js";
|
import { getActiveWebhooks } from "@/misc/webhook-cache.js";
|
||||||
import { shouldSilenceInstance } from "@/misc/should-block-instance.js";
|
|
||||||
import { redisClient } from "@/db/redis.js";
|
import { redisClient } from "@/db/redis.js";
|
||||||
import { Mutex } from "redis-semaphore";
|
import { Mutex } from "redis-semaphore";
|
||||||
import { langmap } from "@/misc/langmap.js";
|
import { langmap } from "@/misc/langmap.js";
|
||||||
|
@ -225,7 +228,7 @@ export default async (
|
||||||
if (
|
if (
|
||||||
data.visibility === "public" &&
|
data.visibility === "public" &&
|
||||||
Users.isRemoteUser(user) &&
|
Users.isRemoteUser(user) &&
|
||||||
(await shouldSilenceInstance(user.host))
|
(await isSilencedServer(user.host))
|
||||||
) {
|
) {
|
||||||
data.visibility = "home";
|
data.visibility = "home";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue