Merge branch 'develop' of https://firefish.dev/firefish/firefish into fix/use-pagination-in-note
This commit is contained in:
commit
70e4d78f90
|
@ -5,6 +5,10 @@ Critical security updates are indicated by the :warning: icon.
|
||||||
- Server administrators should check [notice-for-admins.md](./notice-for-admins.md) as well.
|
- Server administrators should check [notice-for-admins.md](./notice-for-admins.md) as well.
|
||||||
- Third-party client/bot developers may want to check [api-change.md](./api-change.md) as well.
|
- Third-party client/bot developers may want to check [api-change.md](./api-change.md) as well.
|
||||||
|
|
||||||
|
## [v20240421](https://firefish.dev/firefish/firefish/-/merge_requests/10756/commits)
|
||||||
|
|
||||||
|
- Fix bugs
|
||||||
|
|
||||||
## [v20240413](https://firefish.dev/firefish/firefish/-/merge_requests/10741/commits)
|
## [v20240413](https://firefish.dev/firefish/firefish/-/merge_requests/10741/commits)
|
||||||
|
|
||||||
- Add "Media" tab to user page
|
- Add "Media" tab to user page
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "firefish",
|
"name": "firefish",
|
||||||
"version": "20240413",
|
"version": "20240421",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://firefish.dev/firefish/firefish.git"
|
"url": "https://firefish.dev/firefish/firefish.git"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { redisClient } from "@/db/redis.js";
|
import { redisClient } from "@/db/redis.js";
|
||||||
import { encode, decode } from "msgpackr";
|
import { encode, decode } from "msgpackr";
|
||||||
import { ChainableCommander } from "ioredis";
|
import type { ChainableCommander } from "ioredis";
|
||||||
|
|
||||||
export class Cache<T> {
|
export class Cache<T> {
|
||||||
private ttl: number;
|
private ttl: number;
|
||||||
|
|
|
@ -34,7 +34,7 @@ export function initialize<T>(name: string, limitPerSec = -1) {
|
||||||
function apBackoff(attemptsMade: number, err: Error) {
|
function apBackoff(attemptsMade: number, err: Error) {
|
||||||
const baseDelay = 60 * 1000; // 1min
|
const baseDelay = 60 * 1000; // 1min
|
||||||
const maxBackoff = 8 * 60 * 60 * 1000; // 8hours
|
const maxBackoff = 8 * 60 * 60 * 1000; // 8hours
|
||||||
let backoff = (Math.pow(2, attemptsMade) - 1) * baseDelay;
|
let backoff = (2 ** attemptsMade - 1) * baseDelay;
|
||||||
backoff = Math.min(backoff, maxBackoff);
|
backoff = Math.min(backoff, maxBackoff);
|
||||||
backoff += Math.round(backoff * Math.random() * 0.2);
|
backoff += Math.round(backoff * Math.random() * 0.2);
|
||||||
return backoff;
|
return backoff;
|
||||||
|
|
|
@ -32,7 +32,7 @@ import Followers from "./activitypub/followers.js";
|
||||||
import Outbox, { packActivity } from "./activitypub/outbox.js";
|
import Outbox, { packActivity } from "./activitypub/outbox.js";
|
||||||
import { serverLogger } from "./index.js";
|
import { serverLogger } from "./index.js";
|
||||||
import config from "@/config/index.js";
|
import config from "@/config/index.js";
|
||||||
import Koa from "koa";
|
import type Koa from "koa";
|
||||||
import * as crypto from "node:crypto";
|
import * as crypto from "node:crypto";
|
||||||
import { inspect } from "node:util";
|
import { inspect } from "node:util";
|
||||||
import type { IActivity } from "@/remote/activitypub/type.js";
|
import type { IActivity } from "@/remote/activitypub/type.js";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Readable, ReadableOptions } from "node:stream";
|
import { Readable, type ReadableOptions } from "node:stream";
|
||||||
import { Buffer } from "node:buffer";
|
import { Buffer } from "node:buffer";
|
||||||
import * as fs from "node:fs";
|
import * as fs from "node:fs";
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,10 @@ app.use(async (ctx, next) => {
|
||||||
const url = decodeURI(ctx.path);
|
const url = decodeURI(ctx.path);
|
||||||
|
|
||||||
if (url === bullBoardPath || url.startsWith(`${bullBoardPath}/`)) {
|
if (url === bullBoardPath || url.startsWith(`${bullBoardPath}/`)) {
|
||||||
|
if (!url.startsWith(`${bullBoardPath}/static/`)) {
|
||||||
|
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
|
||||||
|
}
|
||||||
|
|
||||||
const token = ctx.cookies.get("token");
|
const token = ctx.cookies.get("token");
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
ctx.status = 401;
|
ctx.status = 401;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import type { KVs } from "../core.js";
|
|
||||||
import Chart from "../core.js";
|
import Chart from "../core.js";
|
||||||
import type { User } from "@/models/entities/user.js";
|
import type { User } from "@/models/entities/user.js";
|
||||||
import { name, schema } from "./entities/active-users.js";
|
import { name, schema } from "./entities/active-users.js";
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Window } from "happy-dom";
|
import { Window } from "happy-dom";
|
||||||
|
import type { HTMLAnchorElement, HTMLLinkElement } from "happy-dom";
|
||||||
import config from "@/config/index.js";
|
import config from "@/config/index.js";
|
||||||
|
|
||||||
async function getRelMeLinks(url: string): Promise<string[]> {
|
async function getRelMeLinks(url: string): Promise<string[]> {
|
||||||
|
|
|
@ -28,9 +28,9 @@ export default class Logger {
|
||||||
|
|
||||||
if (config.syslog) {
|
if (config.syslog) {
|
||||||
this.syslogClient = new SyslogPro.RFC5424({
|
this.syslogClient = new SyslogPro.RFC5424({
|
||||||
applacationName: "Firefish",
|
applicationName: "Firefish",
|
||||||
timestamp: true,
|
timestamp: true,
|
||||||
encludeStructuredData: true,
|
includeStructuredData: true,
|
||||||
color: true,
|
color: true,
|
||||||
extendedColor: true,
|
extendedColor: true,
|
||||||
server: {
|
server: {
|
||||||
|
@ -144,12 +144,12 @@ export default class Logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used when the process can't continue (fatal error)
|
||||||
public error(
|
public error(
|
||||||
x: string | Error,
|
x: string | Error,
|
||||||
data?: Record<string, any> | null,
|
data?: Record<string, any> | null,
|
||||||
important = false,
|
important = false,
|
||||||
): void {
|
): void {
|
||||||
// 実行を継続できない状況で使う
|
|
||||||
if (x instanceof Error) {
|
if (x instanceof Error) {
|
||||||
data = data || {};
|
data = data || {};
|
||||||
data.e = x;
|
data.e = x;
|
||||||
|
@ -166,30 +166,30 @@ export default class Logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used when the process can continue but some action should be taken
|
||||||
public warn(
|
public warn(
|
||||||
message: string,
|
message: string,
|
||||||
data?: Record<string, any> | null,
|
data?: Record<string, any> | null,
|
||||||
important = false,
|
important = false,
|
||||||
): void {
|
): void {
|
||||||
// 実行を継続できるが改善すべき状況で使う
|
|
||||||
this.log("warning", message, data, important);
|
this.log("warning", message, data, important);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used when something is successful
|
||||||
public succ(
|
public succ(
|
||||||
message: string,
|
message: string,
|
||||||
data?: Record<string, any> | null,
|
data?: Record<string, any> | null,
|
||||||
important = false,
|
important = false,
|
||||||
): void {
|
): void {
|
||||||
// 何かに成功した状況で使う
|
|
||||||
this.log("success", message, data, important);
|
this.log("success", message, data, important);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used for debugging (information necessary for developers but unnecessary for users)
|
||||||
public debug(
|
public debug(
|
||||||
message: string,
|
message: string,
|
||||||
data?: Record<string, any> | null,
|
data?: Record<string, any> | null,
|
||||||
important = false,
|
important = false,
|
||||||
): void {
|
): void {
|
||||||
// Used for debugging (information necessary for developers but unnecessary for users)
|
|
||||||
// Fixed if statement is ignored when logLevel includes debug
|
// Fixed if statement is ignored when logLevel includes debug
|
||||||
if (
|
if (
|
||||||
config.logLevel?.includes("debug") ||
|
config.logLevel?.includes("debug") ||
|
||||||
|
@ -200,12 +200,12 @@ export default class Logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Other generic logs
|
||||||
public info(
|
public info(
|
||||||
message: string,
|
message: string,
|
||||||
data?: Record<string, any> | null,
|
data?: Record<string, any> | null,
|
||||||
important = false,
|
important = false,
|
||||||
): void {
|
): void {
|
||||||
// それ以外
|
|
||||||
this.log("info", message, data, important);
|
this.log("info", message, data, important);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
import { publishMainStream } from "@/services/stream.js";
|
import { publishMainStream } from "@/services/stream.js";
|
||||||
import type { Note } from "@/models/entities/note.js";
|
import type { Note } from "@/models/entities/note.js";
|
||||||
import type { User } from "@/models/entities/user.js";
|
import type { User } from "@/models/entities/user.js";
|
||||||
import {
|
import { NoteUnreads, Followings, ChannelFollowings } from "@/models/index.js";
|
||||||
NoteUnreads,
|
|
||||||
Users,
|
|
||||||
Followings,
|
|
||||||
ChannelFollowings,
|
|
||||||
} from "@/models/index.js";
|
|
||||||
import { Not, IsNull, In } from "typeorm";
|
import { Not, IsNull, In } from "typeorm";
|
||||||
import type { Channel } from "@/models/entities/channel.js";
|
import type { Channel } from "@/models/entities/channel.js";
|
||||||
import { readNotificationByQuery } from "@/server/api/common/read-notification.js";
|
import { readNotificationByQuery } from "@/server/api/common/read-notification.js";
|
||||||
|
@ -120,34 +115,4 @@ export default async function (
|
||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (readAntennaNotes.length > 0) {
|
|
||||||
// await AntennaNotes.update(
|
|
||||||
// {
|
|
||||||
// antennaId: In(myAntennas.map((a) => a.id)),
|
|
||||||
// noteId: In(readAntennaNotes.map((n) => n.id)),
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// read: true,
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
|
|
||||||
// // TODO: まとめてクエリしたい
|
|
||||||
// for (const antenna of myAntennas) {
|
|
||||||
// const count = await AntennaNotes.countBy({
|
|
||||||
// antennaId: antenna.id,
|
|
||||||
// read: false,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (count === 0) {
|
|
||||||
// publishMainStream(userId, "readAntenna", antenna);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Users.getHasUnreadAntenna(userId).then((unread) => {
|
|
||||||
// if (!unread) {
|
|
||||||
// publishMainStream(userId, "readAllAntennas");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue