Merge branch 'develop' into iceshrimp_mastodon

This commit is contained in:
naskya 2024-06-05 12:33:48 +09:00
commit be894399a5
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
54 changed files with 107 additions and 101 deletions

View file

@ -433,7 +433,8 @@ export function isQuote(note: NoteLikeForIsQuote): boolean
export function isSafeUrl(url: string): boolean
/** Returns the latest Firefish version. */
export function latestVersion(): Promise<string>
export function fetchMeta(useCache: boolean): Promise<Meta>
export function fetchMeta(): Promise<Meta>
export function updateMetaCache(): Promise<void>
export interface PugArgs {
img: string | null
title: string

View file

@ -310,7 +310,7 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}
const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, loadEnv, loadConfig, stringToAcct, acctToString, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, Protocol, Inbound, Outbound, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, sqlRegexEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, getNoteSummary, isQuote, isSafeUrl, latestVersion, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, PushSubscriptionType, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, ChatEvent, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding
const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, loadEnv, loadConfig, stringToAcct, acctToString, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, Protocol, Inbound, Outbound, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, sqlRegexEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, getNoteSummary, isQuote, isSafeUrl, latestVersion, fetchMeta, updateMetaCache, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, PushSubscriptionType, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, ChatEvent, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding
module.exports.SECOND = SECOND
module.exports.MINUTE = MINUTE
@ -352,6 +352,7 @@ module.exports.isQuote = isQuote
module.exports.isSafeUrl = isSafeUrl
module.exports.latestVersion = latestVersion
module.exports.fetchMeta = fetchMeta
module.exports.updateMetaCache = updateMetaCache
module.exports.metaToPugArgs = metaToPugArgs
module.exports.nyaify = nyaify
module.exports.hashPassword = hashPassword

View file

@ -23,10 +23,8 @@ pub enum Error {
Redis(#[from] RedisError),
#[error("Redis connection error: {0}")]
RedisConn(#[from] RedisConnError),
#[error("Data serialization error: {0}")]
Serialize(#[from] rmp_serde::encode::Error),
#[error("Data deserialization error: {0}")]
Deserialize(#[from] rmp_serde::decode::Error),
#[error("Failed to encode the data: {0}")]
Encode(#[from] rmp_serde::encode::Error),
}
#[inline]
@ -123,7 +121,7 @@ pub async fn set<V: for<'a> Deserialize<'a> + Serialize>(
pub async fn get<V: for<'a> Deserialize<'a> + Serialize>(key: &str) -> Result<Option<V>, Error> {
let serialized_value: Option<Vec<u8>> = redis_conn().await?.get(prefix_key(key)).await?;
Ok(match serialized_value {
Some(v) => Some(rmp_serde::from_slice::<V>(v.as_ref())?),
Some(v) => rmp_serde::from_slice::<V>(v.as_ref()).ok(),
None => None,
})
}

View file

@ -63,7 +63,7 @@ async fn statistics() -> Result<(u64, u64, u64, u64), DbErr> {
async fn generate_nodeinfo_2_1() -> Result<Nodeinfo21, Error> {
let (local_users, local_active_halfyear, local_active_month, local_posts) =
statistics().await?;
let meta = fetch_meta(true).await?;
let meta = fetch_meta().await?;
let metadata = HashMap::from([
(
"nodeName".to_string(),

View file

@ -20,7 +20,7 @@
/// ```
#[crate::ts_export]
pub async fn is_blocked_server(host: &str) -> Result<bool, sea_orm::DbErr> {
Ok(crate::misc::meta::fetch_meta(true)
Ok(crate::misc::meta::fetch_meta()
.await?
.blocked_hosts
.iter()
@ -47,7 +47,7 @@ pub async fn is_blocked_server(host: &str) -> Result<bool, sea_orm::DbErr> {
/// ```
#[crate::ts_export]
pub async fn is_silenced_server(host: &str) -> Result<bool, sea_orm::DbErr> {
Ok(crate::misc::meta::fetch_meta(true)
Ok(crate::misc::meta::fetch_meta()
.await?
.silenced_hosts
.iter()
@ -75,7 +75,7 @@ pub async fn is_silenced_server(host: &str) -> Result<bool, sea_orm::DbErr> {
/// ```
#[crate::ts_export]
pub async fn is_allowed_server(host: &str) -> Result<bool, sea_orm::DbErr> {
let meta = crate::misc::meta::fetch_meta(true).await?;
let meta = crate::misc::meta::fetch_meta().await?;
if !meta.private_mode.unwrap_or(false) {
return Ok(true);

View file

@ -7,12 +7,22 @@ use std::sync::Mutex;
type Meta = meta::Model;
static CACHE: Mutex<Option<Meta>> = Mutex::new(None);
fn update_cache(meta: &Meta) {
fn set_cache(meta: &Meta) {
let _ = CACHE.lock().map(|mut cache| *cache = Some(meta.clone()));
}
#[crate::export]
pub async fn fetch_meta(use_cache: bool) -> Result<Meta, DbErr> {
pub async fn fetch_meta() -> Result<Meta, DbErr> {
fetch_meta_impl(true).await
}
#[crate::export]
pub async fn update_meta_cache() -> Result<(), DbErr> {
fetch_meta_impl(false).await?;
Ok(())
}
async fn fetch_meta_impl(use_cache: bool) -> Result<Meta, DbErr> {
// try using cache
if use_cache {
if let Some(cache) = CACHE.lock().ok().and_then(|cache| cache.clone()) {
@ -24,7 +34,7 @@ pub async fn fetch_meta(use_cache: bool) -> Result<Meta, DbErr> {
let db = db_conn().await?;
let meta = meta::Entity::find().one(db).await?;
if let Some(meta) = meta {
update_cache(&meta);
set_cache(&meta);
return Ok(meta);
}
@ -35,7 +45,7 @@ pub async fn fetch_meta(use_cache: bool) -> Result<Meta, DbErr> {
})
.exec_with_returning(db)
.await?;
update_cache(&meta);
set_cache(&meta);
Ok(meta)
}

View file

@ -118,7 +118,7 @@ pub async fn to_db_reaction(reaction: Option<&str>, host: Option<&str>) -> Resul
};
};
Ok(fetch_meta(true).await?.default_reaction)
Ok(fetch_meta().await?.default_reaction)
}
#[cfg(test)]

View file

@ -197,7 +197,7 @@ pub async fn send_push_notification(
kind: PushNotificationKind,
content: &serde_json::Value,
) -> Result<(), Error> {
let meta = fetch_meta(true).await?;
let meta = fetch_meta().await?;
if !meta.enable_service_worker || meta.sw_public_key.is_none() || meta.sw_private_key.is_none()
{

View file

@ -1,23 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Firefish API</title>
<!-- needed for adaptive design -->
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--
ReDoc doesn't change outer page styles
-->
<style>
body {
margin: 0;
padding: 0;
}
</style>
<!-- Embed elements Elements via Web Component -->
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
</head>
<body>
<redoc spec-url="/api.json" expand-responses="200" expand-single-schema-field="true"></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc@2.0.0-rc.50/bundles/redoc.standalone.js" integrity="sha256-WJbngBWN9vp6vkEuzeoSj5tE5saW9Hfj6/SinkzhL2s=" crossorigin="anonymous"></script>
<elements-api
id="element-main"
apiDescriptionUrl='/api.json'
router="hash"
layout="responsive"
/>
</body>
</html>

View file

@ -4,10 +4,10 @@ import semver from "semver";
import Logger from "@/services/logger.js";
import {
fetchMeta,
greet,
removeOldAttestationChallenges,
showServerInfo,
updateMetaCache,
type Config,
} from "backend-rs";
import { config, envOption } from "@/config.js";
@ -53,7 +53,7 @@ export async function masterMain() {
import("../daemons/server-stats.js").then((x) => x.default());
import("../daemons/queue-stats.js").then((x) => x.default());
// Update meta cache every 5 minitues
setInterval(() => fetchMeta(false), 1000 * 60 * 5);
setInterval(() => updateMetaCache(), 1000 * 60 * 5);
// Remove old attestation challenges
setInterval(() => removeOldAttestationChallenges(), 1000 * 60 * 30);
}

View file

@ -13,7 +13,7 @@ export default async function () {
ev.emit(`serverStatsLog:${x.id}`, log.slice(0, x.length || 50));
});
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (!meta.enableServerMachineStats) return;
async function tick() {

View file

@ -3,7 +3,7 @@ import type { ILocalUser } from "@/models/entities/user.js";
import { Users } from "@/models/index.js";
export async function fetchProxyAccount(): Promise<ILocalUser | null> {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.proxyAccountId == null) return null;
return (await Users.findOneByOrFail({
id: meta.proxyAccountId,

View file

@ -26,7 +26,7 @@ export async function translate(
from: PostLanguage | null,
to: PostLanguage,
) {
const instance = await fetchMeta(true);
const instance = await fetchMeta();
if (instance.deeplAuthKey == null && instance.libreTranslateApiUrl == null) {
throw Error("No translator is set up on this server.");

View file

@ -15,7 +15,7 @@ import type { UserPublickey } from "@/models/entities/user-publickey.js";
import { verify } from "node:crypto";
export async function hasSignature(req: IncomingMessage): Promise<string> {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const required = meta.secureMode || meta.privateMode;
try {
@ -30,7 +30,7 @@ export async function hasSignature(req: IncomingMessage): Promise<string> {
}
export async function checkFetch(req: IncomingMessage): Promise<number> {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
if (req.headers.host !== config.host) return 400;

View file

@ -36,7 +36,7 @@ export async function createImage(
apLogger.info(`Creating an image: ${image.url}`);
const instance = await fetchMeta(true);
const instance = await fetchMeta();
let file = await uploadFromUrl({
url: image.url,

View file

@ -243,7 +243,7 @@ router.get("/notes/:note", async (ctx, next) => {
ctx.body = renderActivity(await renderNote(note, false));
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {
@ -273,7 +273,7 @@ router.get("/notes/:note/activity", async (ctx) => {
}
ctx.body = renderActivity(await packActivity(note));
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {
@ -328,7 +328,7 @@ router.get("/users/:user/publickey", async (ctx) => {
if (Users.isLocalUser(user)) {
ctx.body = renderActivity(renderKey(user, keypair));
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {
@ -348,7 +348,7 @@ async function userInfo(ctx: Router.RouterContext, user: User | null) {
}
ctx.body = renderActivity(await renderPerson(user as ILocalUser));
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {
@ -432,7 +432,7 @@ router.get("/emojis/:emoji", async (ctx) => {
}
ctx.body = renderActivity(renderEmoji(emoji));
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {
@ -464,7 +464,7 @@ router.get("/likes/:like", async (ctx) => {
}
ctx.body = renderActivity(await renderLike(reaction, note));
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {
@ -502,7 +502,7 @@ router.get(
}
ctx.body = renderActivity(renderFollow(follower, followee));
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {
@ -545,7 +545,7 @@ router.get("/follows/:followRequestId", async (ctx: Router.RouterContext) => {
return;
}
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {

View file

@ -57,7 +57,7 @@ export default async (ctx: Router.RouterContext) => {
ctx.body = renderActivity(rendered);
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {

View file

@ -110,7 +110,7 @@ export default async (ctx: Router.RouterContext) => {
ctx.body = renderActivity(rendered);
setResponseType(ctx);
}
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {

View file

@ -110,7 +110,7 @@ export default async (ctx: Router.RouterContext) => {
ctx.body = renderActivity(rendered);
setResponseType(ctx);
}
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {

View file

@ -117,7 +117,7 @@ export default async (ctx: Router.RouterContext) => {
setResponseType(ctx);
}
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.secureMode || meta.privateMode) {
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
} else {

View file

@ -84,7 +84,7 @@ export default (endpoint: IEndpoint, ctx: Koa.Context) =>
// Log IP
if (user) {
fetchMeta(true).then((meta) => {
fetchMeta().then((meta) => {
if (!meta.enableIpLogging) return;
const ip = ctx.ip;
const ips = userIpHistories.get(user.id);

View file

@ -117,7 +117,7 @@ export default async (
}
// private mode
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (
meta.privateMode &&
ep.meta.requireCredentialPrivateMode &&

View file

@ -470,7 +470,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async () => {
const instance = await fetchMeta(false);
const instance = await fetchMeta();
return {
maintainerName: instance.maintainerName,

View file

@ -123,7 +123,7 @@ export default define(meta, paramDef, async (ps, user) => {
let userList;
let userGroupJoining;
const instance = await fetchMeta(true);
const instance = await fetchMeta();
const antennas = await Antennas.findBy({
userId: user.id,

View file

@ -27,7 +27,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async () => {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const motd = await Promise.all(meta.customMotd.map((x) => x));
return motd;
});

View file

@ -27,7 +27,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async () => {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const icons = await Promise.all(meta.customSplashIcons.map((x) => x));
return icons;
});

View file

@ -35,7 +35,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async (ps, user) => {
const instance = await fetchMeta(false);
const instance = await fetchMeta();
// Calculate drive usage
const usage = await DriveFiles.calcDriveUsageOf(user.id);

View file

@ -95,7 +95,7 @@ export default define(
name = null;
}
const instanceMeta = await fetchMeta(true);
const instanceMeta = await fetchMeta();
try {
// Create file

View file

@ -100,7 +100,7 @@ export default define(meta, paramDef, async (ps, me) => {
}
if (typeof ps.blocked === "boolean") {
const meta = await fetchMeta(false);
const meta = await fetchMeta();
if (ps.blocked) {
if (meta.blockedHosts.length === 0) {
return [];
@ -116,7 +116,7 @@ export default define(meta, paramDef, async (ps, me) => {
}
if (typeof ps.silenced === "boolean") {
const meta = await fetchMeta(false);
const meta = await fetchMeta();
if (ps.silenced) {
if (meta.silencedHosts.length === 0) {
return [];

View file

@ -66,7 +66,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async () => {
const instance = await fetchMeta(false);
const instance = await fetchMeta();
const hiddenTags = instance.hiddenTags.map((t) => normalizeForSearch(t));
const now = new Date(); // 5分単位で丸めた現在日時

View file

@ -44,7 +44,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => {
const file = await DriveFiles.findOneBy({ id: ps.fileId });
const instanceMeta = await fetchMeta(true);
const instanceMeta = await fetchMeta();
if (instanceMeta.experimentalFeatures?.postImports === false)
throw new ApiError(meta.errors.importsDisabled);

View file

@ -402,7 +402,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async (ps, me) => {
const instance = await fetchMeta(false);
const instance = await fetchMeta();
const emojis = await Emojis.find({
where: {

View file

@ -64,7 +64,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async (ps, user) => {
const m = await fetchMeta(true);
const m = await fetchMeta();
if (m.disableGlobalTimeline) {
if (user == null || !(user.isAdmin || user.isModerator)) {
throw new ApiError(meta.errors.gtlDisabled);

View file

@ -71,7 +71,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async (ps, user) => {
const m = await fetchMeta(true);
const m = await fetchMeta();
if (m.disableLocalTimeline && !user.isAdmin && !user.isModerator) {
throw new ApiError(meta.errors.stlDisabled);
}

View file

@ -74,7 +74,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async (ps, user) => {
const m = await fetchMeta(true);
const m = await fetchMeta();
if (m.disableLocalTimeline) {
if (user == null || !(user.isAdmin || user.isModerator)) {
throw new ApiError(meta.errors.ltlDisabled);

View file

@ -74,7 +74,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async (ps, user) => {
const m = await fetchMeta(true);
const m = await fetchMeta();
if (m.disableRecommendedTimeline) {
if (user == null || !(user.isAdmin || user.isModerator)) {
throw new ApiError(meta.errors.rtlDisabled);

View file

@ -30,7 +30,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async (ps, me) => {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const users = await Promise.all(
meta.pinnedUsers

View file

@ -27,7 +27,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async () => {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const instances = await Promise.all(meta.recommendedInstances.map((x) => x));
return instances;
});

View file

@ -17,7 +17,7 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async () => {
const instanceMeta = await fetchMeta(true);
const instanceMeta = await fetchMeta();
if (!instanceMeta.enableServerMachineStats) {
return {

View file

@ -63,7 +63,7 @@ export default define(meta, paramDef, async (ps, me) => {
publickey: ps.publickey,
});
const instance = await fetchMeta(false);
const instance = await fetchMeta();
// if already subscribed
if (subscription != null) {

View file

@ -101,7 +101,7 @@ export function genOpenapiSpec() {
}
const info = {
operationId: endpoint.name,
operationId: `POST-${endpoint.name}`,
summary: endpoint.name,
description: desc,
externalDocs: {
@ -208,11 +208,11 @@ export function genOpenapiSpec() {
},
};
const path = {
const path: Record<string, typeof info> = {
post: info,
};
if (endpoint.meta.allowGet) {
path.get = { ...info };
path.get = { ...info, operationId: `GET-${endpoint.name}` };
// API Key authentication is not permitted for GET requests
path.get.security = path.get.security.filter(
(elem) => !Object.prototype.hasOwnProperty.call(elem, "ApiKeyAuth"),

View file

@ -11,7 +11,7 @@ import { validateEmailForAccount } from "@/services/validate-email-for-account.j
export default async (ctx: Koa.Context) => {
const body = ctx.request.body;
const instance = await fetchMeta(false);
const instance = await fetchMeta();
// Verify *Captcha
// ただしテスト時はこの機構は障害となるため無効にする

View file

@ -16,7 +16,7 @@ export default class extends Channel {
}
public async init(params: any) {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.disableGlobalTimeline) {
if (this.user == null || !(this.user.isAdmin || this.user.isModerator))
return;

View file

@ -16,7 +16,7 @@ export default class extends Channel {
}
public async init(params: any) {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (
meta.disableLocalTimeline &&
!this.user!.isAdmin &&

View file

@ -15,7 +15,7 @@ export default class extends Channel {
}
public async init(params: any) {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.disableLocalTimeline) {
if (this.user == null || !(this.user.isAdmin || this.user.isModerator))
return;

View file

@ -16,7 +16,7 @@ export default class extends Channel {
}
public async init(params: any) {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (
meta.disableRecommendedTimeline &&
!this.user!.isAdmin &&
@ -36,7 +36,7 @@ export default class extends Channel {
// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
// チャンネルの投稿ではなく、全体公開のローカルの投稿 または
// フォローしているチャンネルの投稿 の場合だけ
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (
!(
note.user.host != null &&

View file

@ -126,7 +126,7 @@ router.get("/avatar/@:acct", async (ctx) => {
});
router.get("/identicon/:x", async (ctx) => {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.enableIdenticonGeneration) {
const [temp, cleanup] = await createTemp();
await genIdenticon(ctx.params.x, fs.createWriteStream(temp));

View file

@ -334,7 +334,7 @@ const getFeed = async (
noRenotes: string,
noReplies: string,
) => {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.privateMode) {
return;
}
@ -482,7 +482,7 @@ const userPage: Router.Middleware = async (ctx, next) => {
}
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const me = profile.fields
? profile.fields
.filter((filed) => filed.value?.match(/^https?:/))
@ -531,7 +531,7 @@ router.get("/notes/:note", async (ctx, next) => {
const profile = await UserProfiles.findOneByOrFail({
userId: note.userId,
});
const meta = await fetchMeta(true);
const meta = await fetchMeta();
await ctx.render("note", {
...metaToPugArgs(meta),
note: packedNote,
@ -565,7 +565,7 @@ router.get("/posts/:note", async (ctx, next) => {
if (note) {
const _note = await Notes.pack(note);
const profile = await UserProfiles.findOneByOrFail({ userId: note.userId });
const meta = await fetchMeta(true);
const meta = await fetchMeta();
await ctx.render("note", {
...metaToPugArgs(meta),
note: _note,
@ -603,7 +603,7 @@ router.get("/@:user/pages/:page", async (ctx, next) => {
if (page) {
const _page = await Pages.pack(page);
const profile = await UserProfiles.findOneByOrFail({ userId: page.userId });
const meta = await fetchMeta(true);
const meta = await fetchMeta();
await ctx.render("page", {
...metaToPugArgs(meta),
page: _page,
@ -635,7 +635,7 @@ router.get("/clips/:clip", async (ctx, next) => {
if (clip) {
const _clip = await Clips.pack(clip);
const profile = await UserProfiles.findOneByOrFail({ userId: clip.userId });
const meta = await fetchMeta(true);
const meta = await fetchMeta();
await ctx.render("clip", {
...metaToPugArgs(meta),
clip: _clip,
@ -660,7 +660,7 @@ router.get("/gallery/:post", async (ctx, next) => {
if (post) {
const _post = await GalleryPosts.pack(post);
const profile = await UserProfiles.findOneByOrFail({ userId: post.userId });
const meta = await fetchMeta(true);
const meta = await fetchMeta();
await ctx.render("gallery-post", {
...metaToPugArgs(meta),
post: _post,
@ -686,7 +686,7 @@ router.get("/channels/:channel", async (ctx, next) => {
if (channel) {
const _channel = await Channels.pack(channel);
const meta = await fetchMeta(true);
const meta = await fetchMeta();
await ctx.render("channel", {
...metaToPugArgs(meta),
channel: _channel,
@ -739,7 +739,7 @@ router.get("/api/v1/streaming", async (ctx) => {
// Render base html for all requests
router.get("(.*)", async (ctx) => {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
await ctx.render("base", {
...metaToPugArgs(meta),

View file

@ -77,7 +77,7 @@ const manifest = {
};
export const manifestHandler = async (ctx: Koa.Context) => {
const instance = await fetchMeta(true);
const instance = await fetchMeta();
manifest.short_name = instance.name || "Firefish";
manifest.name = instance.name || "Firefish";

View file

@ -22,7 +22,7 @@ export const urlPreviewHandler = async (ctx: Koa.Context) => {
return;
}
const meta = await fetchMeta(true);
const meta = await fetchMeta();
logger.info(
meta.summalyProxy

View file

@ -78,7 +78,7 @@ async function save(
// thunbnail, webpublic を必要なら生成
const alts = await generateAlts(path, type, !file.uri);
const meta = await fetchMeta(true);
const meta = await fetchMeta();
if (meta.useObjectStorage) {
//#region ObjectStorage params
@ -363,7 +363,7 @@ async function upload(
if (type === "image/apng") type = "image/png";
if (!FILE_TYPE_BROWSERSAFE.includes(type)) type = "application/octet-stream";
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const params = {
Bucket: meta.objectStorageBucket,
@ -507,7 +507,7 @@ export async function addFile({
const usage = await DriveFiles.calcDriveUsageOf(user);
const u = await Users.findOneBy({ id: user.id });
const instance = await fetchMeta(true);
const instance = await fetchMeta();
let driveCapacity =
1024 *
1024 *
@ -579,7 +579,7 @@ export async function addFile({
: null;
const folder = await fetchFolder();
const instance = await fetchMeta(true);
const instance = await fetchMeta();
let file = new DriveFile();
file.id = genId();

View file

@ -82,7 +82,7 @@ async function postProcess(file: DriveFile, isExpired = false) {
}
export async function deleteObjectStorageFile(key: string) {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const s3 = getS3(meta);

View file

@ -12,7 +12,7 @@ export async function sendEmail(
html: string,
text: string,
) {
const meta = await fetchMeta(false);
const meta = await fetchMeta();
const iconUrl = `${config.url}/static-assets/mi-white.png`;
const emailSettingUrl = `${config.url}/settings/email`;

View file

@ -6,7 +6,7 @@ export async function validateEmailForAccount(emailAddress: string): Promise<{
available: boolean;
reason: null | "used" | "format" | "disposable" | "mx" | "smtp";
}> {
const meta = await fetchMeta(true);
const meta = await fetchMeta();
const exist = await UserProfiles.countBy({
emailVerified: true,