diff --git a/CHANGELOG.md b/CHANGELOG.md index e0829ed71c..015374e2db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,15 @@ You should also include the user name that made the change. --> +## 12.x.x (unreleased) + +### Improvements +- Bull Dashboardを組み込み、ジョブキューの確認や操作を行えるように @syuilo +- Check that installed Node.js version fulfills version requirement @ThatOneCalculator + +### Bugfixes +- API: fix endpoint endpoint @Johann150 + ## 12.108.1 (2022/03/12) ### Bugfixes diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index e0182c8863..2ee312a306 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -840,6 +840,7 @@ tenMinutes: "10分" oneHour: "1時間" oneDay: "1日" oneWeek: "1週間" +reflectMayTakeTime: "反映されるまで時間がかかる場合があります。" _emailUnavailable: used: "既に使用されています" diff --git a/package.json b/package.json index 65aa436cf3..ea691dec50 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,9 @@ "js-yaml": "4.1.0" }, "devDependencies": { - "@typescript-eslint/parser": "5.14.0", + "@typescript-eslint/parser": "5.15.0", "cross-env": "7.0.3", - "cypress": "9.5.0", + "cypress": "9.5.2", "start-server-and-test": "1.14.0", "typescript": "4.6.2" } diff --git a/packages/backend/package.json b/packages/backend/package.json index 87712faf7c..07904098f9 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -15,7 +15,7 @@ "lodash": "^4.17.21" }, "dependencies": { - "@discordapp/twemoji": "13.1.0", + "@discordapp/twemoji": "13.1.1", "@elastic/elasticsearch": "7.11.0", "@koa/cors": "3.1.0", "@koa/multer": "3.0.0", @@ -56,7 +56,7 @@ "@types/redis": "4.0.11", "@types/rename": "1.0.4", "@types/sanitize-html": "2.6.2", - "@types/sharp": "0.29.5", + "@types/sharp": "0.30.0", "@types/sinonjs__fake-timers": "8.1.1", "@types/speakeasy": "2.0.7", "@types/throttle-debounce": "2.1.0", @@ -65,15 +65,16 @@ "@types/uuid": "8.3.4", "@types/web-push": "3.3.2", "@types/websocket": "1.0.5", - "@types/ws": "8.5.2", - "@typescript-eslint/eslint-plugin": "5.14.0", - "@typescript-eslint/parser": "5.14.0", + "@types/ws": "8.5.3", + "@typescript-eslint/eslint-plugin": "5.15.0", + "@typescript-eslint/parser": "5.15.0", + "@bull-board/koa": "3.10.0", "abort-controller": "3.0.0", "ajv": "8.10.0", "archiver": "5.3.0", "autobind-decorator": "2.4.0", "autwh": "0.1.0", - "aws-sdk": "2.1079.0", + "aws-sdk": "2.1096.0", "bcryptjs": "2.4.3", "blurhash": "1.1.5", "broadcast-channel": "4.10.0", @@ -89,12 +90,12 @@ "date-fns": "2.28.0", "deep-email-validator": "0.1.21", "escape-regexp": "0.0.1", - "eslint": "8.10.0", + "eslint": "8.11.0", "eslint-plugin-import": "2.25.4", "feed": "4.2.2", "file-type": "17.1.1", "fluent-ffmpeg": "2.1.2", - "got": "12.0.1", + "got": "12.0.2", "hpagent": "0.1.2", "http-signature": "1.3.6", "ip-cidr": "3.0.4", @@ -115,13 +116,13 @@ "koa-slow": "2.1.0", "koa-views": "7.0.2", "mfm-js": "0.21.0", - "mime-types": "2.1.34", + "mime-types": "2.1.35", "misskey-js": "0.0.14", - "mocha": "9.2.1", + "mocha": "9.2.2", "ms": "3.0.0-canary.1", "multer": "1.4.4", "nested-property": "4.0.0", - "node-fetch": "3.2.2", + "node-fetch": "3.2.3", "nodemailer": "6.7.2", "os-utils": "0.0.14", "parse5": "6.0.1", @@ -145,22 +146,23 @@ "rndstr": "1.0.0", "s-age": "1.1.2", "sanitize-html": "2.7.0", - "sharp": "0.30.2", + "semver": "7.3.5", + "sharp": "0.30.3", "speakeasy": "2.0.0", "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "style-loader": "3.3.1", "summaly": "2.5.0", "syslog-pro": "1.0.0", - "systeminformation": "5.11.6", + "systeminformation": "5.11.8", "throttle-debounce": "3.0.1", "tinycolor2": "1.4.2", "tmp": "0.2.1", - "ts-loader": "9.2.7", + "ts-loader": "9.2.8", "ts-node": "10.7.0", "tsc-alias": "1.4.1", - "tsconfig-paths": "3.13.0", - "twemoji-parser": "13.1.0", + "tsconfig-paths": "3.14.0", + "twemoji-parser": "14.0.0", "typeorm": "0.2.45", "typescript": "4.6.2", "ulid": "2.3.0", @@ -172,7 +174,7 @@ "xev": "2.0.1" }, "devDependencies": { - "@redocly/openapi-core": "1.0.0-beta.83", + "@redocly/openapi-core": "1.0.0-beta.88", "@types/fluent-ffmpeg": "2.1.20", "cross-env": "7.0.3", "execa": "6.1.0" diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index 1c909dff13..48f0f81564 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -6,6 +6,7 @@ import cluster from 'node:cluster'; import chalk from 'chalk'; import chalkTemplate from 'chalk-template'; import * as portscanner from 'portscanner'; +import semver from 'semver'; import { getConnection } from 'typeorm'; import Logger from '@/services/logger.js'; @@ -88,10 +89,6 @@ export async function masterMain() { } } -const runningNodejsVersion = process.version.slice(1).split('.').map(x => parseInt(x, 10)); -const requiredNodejsVersion = [11, 7, 0]; -const satisfyNodejsVersion = !lessThan(runningNodejsVersion, requiredNodejsVersion); - function showEnvironment(): void { const env = process.env.NODE_ENV; const logger = bootLogger.createSubLogger('env'); @@ -108,10 +105,11 @@ function showEnvironment(): void { function showNodejsVersion(): void { const nodejsLogger = bootLogger.createSubLogger('nodejs'); - nodejsLogger.info(`Version ${runningNodejsVersion.join('.')}`); + nodejsLogger.info(`Version ${process.version} detected.`); - if (!satisfyNodejsVersion) { - nodejsLogger.error(`Node.js version is less than ${requiredNodejsVersion.join('.')}. Please upgrade it.`, null, true); + const minVersion = fs.readFileSync(`${_dirname}/../../../../.node-version`, 'utf-8').trim(); + if (semver.lt(process.version, minVersion)) { + nodejsLogger.error(`At least Node.js ${minVersion} required!`); process.exit(1); } } diff --git a/packages/backend/src/db/postgre.ts b/packages/backend/src/db/postgre.ts index 066a3c6739..5fd1f95cca 100644 --- a/packages/backend/src/db/postgre.ts +++ b/packages/backend/src/db/postgre.ts @@ -85,7 +85,7 @@ class MyCustomLogger implements Logger { public logQuery(query: string, parameters?: any[]) { if (envOption.verbose) { - sqlLogger.info(this.highlight(query)); + sqlLogger.info(this.highlight(query).substring(0, 100)); } } diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 76835b44b1..e9966b7785 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -28,11 +28,22 @@ export class Cache { this.cache.delete(key); } - public async fetch(key: string | null, fetcher: () => Promise): Promise { + /** + * キャッシュがあればそれを返し、無ければfetcherを呼び出して結果をキャッシュ&返します + * optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします + */ + public async fetch(key: string | null, fetcher: () => Promise, validator?: (cachedValue: T) => boolean): Promise { const cachedValue = this.get(key); if (cachedValue !== undefined) { - // Cache HIT - return cachedValue; + if (validator) { + if (validator(cachedValue)) { + // Cache HIT + return cachedValue; + } + } else { + // Cache HIT + return cachedValue; + } } // Cache MISS diff --git a/packages/backend/src/misc/check-hit-antenna.ts b/packages/backend/src/misc/check-hit-antenna.ts index ceb74d6904..745db391a4 100644 --- a/packages/backend/src/misc/check-hit-antenna.ts +++ b/packages/backend/src/misc/check-hit-antenna.ts @@ -1,17 +1,26 @@ import { Antenna } from '@/models/entities/antenna.js'; import { Note } from '@/models/entities/note.js'; import { User } from '@/models/entities/user.js'; -import { UserListJoinings, UserGroupJoinings } from '@/models/index.js'; +import { UserListJoinings, UserGroupJoinings, Blockings } from '@/models/index.js'; import { getFullApAccount } from './convert-host.js'; import * as Acct from '@/misc/acct.js'; import { Packed } from './schema.js'; +import { Cache } from './cache.js'; + +const blockingCache = new Cache(1000 * 60 * 5); + +// NOTE: フォローしているユーザーのノート、リストのユーザーのノート、グループのユーザーのノート指定はパフォーマンス上の理由で無効になっている /** * noteUserFollowers / antennaUserFollowing はどちらか一方が指定されていればよい */ -export async function checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise { +export async function checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { id: User['id']; username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise { if (note.visibility === 'specified') return false; + // アンテナ作成者がノート作成者にブロックされていたらスキップ + const blockings = await blockingCache.fetch(noteUser.id, () => Blockings.find({ blockerId: noteUser.id }).then(res => res.map(x => x.blockeeId))); + if (blockings.some(blocking => blocking === antenna.userId)) return false; + if (note.visibility === 'followers') { if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false; if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false; diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index a909ab3ba6..17b7987a4e 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -8,6 +8,10 @@ import { awaitAll, Promiseable } from '@/prelude/await-all.js'; import { populateEmojis } from '@/misc/populate-emojis.js'; import { getAntennas } from '@/misc/antenna-cache.js'; import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js'; +import { Cache } from '@/misc/cache.js'; +import { Instance } from '../entities/instance.js'; + +const userInstanceCache = new Cache(1000 * 60 * 60 * 3); type IsUserDetailed = Detailed extends true ? Packed<'UserDetailed'> : Packed<'UserLite'>; type IsMeAndIsUserDetailed = @@ -254,8 +258,11 @@ export class UserRepository extends Repository { isModerator: user.isModerator || falsy, isBot: user.isBot || falsy, isCat: user.isCat || falsy, - showTimelineReplies: user.showTimelineReplies || falsy, - instance: user.host ? Instances.findOne({ host: user.host }).then(instance => instance ? { + // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる + instance: user.host ? userInstanceCache.fetch(user.host, + () => Instances.findOne({ host: user.host }).then(x => x || null), + v => v != null + ).then(instance => instance ? { name: instance.name, softwareName: instance.softwareName, softwareVersion: instance.softwareVersion, @@ -334,6 +341,7 @@ export class UserRepository extends Repository { mutedInstances: profile!.mutedInstances, mutingNotificationTypes: profile!.mutingNotificationTypes, emailNotificationTypes: profile!.emailNotificationTypes, + showTimelineReplies: user.showTimelineReplies || falsy, } : {}), ...(opts.includeSecrets ? { diff --git a/packages/backend/src/queue/index.ts b/packages/backend/src/queue/index.ts index 50bcccbb7f..b679a552b2 100644 --- a/packages/backend/src/queue/index.ts +++ b/packages/backend/src/queue/index.ts @@ -263,6 +263,7 @@ export default function() { systemQueue.add('tickCharts', { }, { repeat: { cron: '55 * * * *' }, + removeOnComplete: true, }); systemQueue.add('resyncCharts', { @@ -278,6 +279,7 @@ export default function() { systemQueue.add('checkExpiredMutings', { }, { repeat: { cron: '*/5 * * * *' }, + removeOnComplete: true, }); processSystemQueue(systemQueue); diff --git a/packages/backend/src/queue/queues.ts b/packages/backend/src/queue/queues.ts index 02df587365..d612dee450 100644 --- a/packages/backend/src/queue/queues.ts +++ b/packages/backend/src/queue/queues.ts @@ -8,3 +8,12 @@ export const deliverQueue = initializeQueue('deliver', config.de export const inboxQueue = initializeQueue('inbox', config.inboxJobPerSec || 16); export const dbQueue = initializeQueue('db'); export const objectStorageQueue = initializeQueue('objectStorage'); + +export const queues = [ + systemQueue, + endedPollNotificationQueue, + deliverQueue, + inboxQueue, + dbQueue, + objectStorageQueue, +]; diff --git a/packages/backend/src/remote/activitypub/db-resolver.ts b/packages/backend/src/remote/activitypub/db-resolver.ts index 9281e494d0..3f16c5f56d 100644 --- a/packages/backend/src/remote/activitypub/db-resolver.ts +++ b/packages/backend/src/remote/activitypub/db-resolver.ts @@ -78,14 +78,14 @@ export default class DbResolver { public async getAuthUserFromKeyId(keyId: string): Promise { const key = await UserPublickeys.findOne({ keyId, + }, { + relations: ['user'], }); if (key == null) return null; - const user = await Users.findOne(key.userId) as IRemoteUser; - return { - user, + user: key.user as IRemoteUser, key, }; } diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index dca64d0a60..0bcc89fbbb 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -197,7 +197,7 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s const cw = note.summary === '' ? null : note.summary; // テキストのパース - const text = note._misskey_content || (note.content ? htmlToMfm(note.content, note.tag) : null); + const text = typeof note._misskey_content !== 'undefined' ? note._misskey_content : (note.content ? htmlToMfm(note.content, note.tag) : null); // vote if (reply && reply.hasPoll) { diff --git a/packages/backend/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts index c3d9e120d6..78190751f6 100644 --- a/packages/backend/src/remote/activitypub/renderer/note.ts +++ b/packages/backend/src/remote/activitypub/renderer/note.ts @@ -53,9 +53,7 @@ export default async function renderNote(note: Note, dive = true, isTalk = false } } - const user = await Users.findOneOrFail(note.userId); - - const attributedTo = `${config.url}/users/${user.id}`; + const attributedTo = `${config.url}/users/${note.userId}`; const mentions = (JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers).map(x => x.uri); diff --git a/packages/backend/src/remote/activitypub/renderer/undo.ts b/packages/backend/src/remote/activitypub/renderer/undo.ts index d28778e22e..46631df9ea 100644 --- a/packages/backend/src/remote/activitypub/renderer/undo.ts +++ b/packages/backend/src/remote/activitypub/renderer/undo.ts @@ -3,9 +3,11 @@ import { ILocalUser, User } from '@/models/entities/user.js'; export default (object: any, user: { id: User['id'] }) => { if (object == null) return null; + const id = typeof object.id === 'string' && object.id.startsWith(config.url) ? `${object.id}/undo` : undefined; return { type: 'Undo', + ...(id ? { id } : {}), actor: `${config.url}/users/${user.id}`, object, published: new Date().toISOString(), diff --git a/packages/backend/src/server/activitypub.ts b/packages/backend/src/server/activitypub.ts index 21be0a2517..c0a9b37726 100644 --- a/packages/backend/src/server/activitypub.ts +++ b/packages/backend/src/server/activitypub.ts @@ -18,6 +18,7 @@ import { ILocalUser, User } from '@/models/entities/user.js'; import { In } from 'typeorm'; import { renderLike } from '@/remote/activitypub/renderer/like.js'; import { getUserKeypair } from '@/misc/keypair-store.js'; +import { noteCache, userCache } from './activitypub/cache.js'; // Init router const router = new Router(); @@ -65,11 +66,13 @@ router.post('/users/:user/inbox', json(), inbox); router.get('/notes/:note', async (ctx, next) => { if (!isActivityPubReq(ctx)) return await next(); - const note = await Notes.findOne({ + // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる + // nginxとかでキャッシュしてくれそうだからそもそもnode側でのキャッシュ不要かも? + const note = await noteCache.fetch(ctx.params.note, () => Notes.findOne({ id: ctx.params.note, visibility: In(['public' as const, 'home' as const]), localOnly: false, - }); + }).then(x => x || null)); if (note == null) { ctx.status = 404; @@ -148,7 +151,7 @@ router.get('/users/:user/publickey', async ctx => { }); // user -async function userInfo(ctx: Router.RouterContext, user: User | undefined) { +async function userInfo(ctx: Router.RouterContext, user: User | undefined | null) { if (user == null) { ctx.status = 404; return; @@ -164,11 +167,13 @@ router.get('/users/:user', async (ctx, next) => { const userId = ctx.params.user; - const user = await Users.findOne({ + // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる + // nginxとかでキャッシュしてくれそうだからそもそもnode側でのキャッシュ不要かも? + const user = await userCache.fetch(userId, () => Users.findOne({ id: userId, host: null, isSuspended: false, - }); + }).then(x => x || null)); await userInfo(ctx, user); }); diff --git a/packages/backend/src/server/activitypub/cache.ts b/packages/backend/src/server/activitypub/cache.ts new file mode 100644 index 0000000000..00199ee253 --- /dev/null +++ b/packages/backend/src/server/activitypub/cache.ts @@ -0,0 +1,6 @@ +import { Cache } from "@/misc/cache.js"; +import { Note } from "@/models/entities/note.js"; +import { User } from "@/models/entities/user.js"; + +export const userCache = new Cache(1000 * 60 * 30); +export const noteCache = new Cache(1000 * 60 * 30); diff --git a/packages/backend/src/server/activitypub/featured.ts b/packages/backend/src/server/activitypub/featured.ts index 129881a718..d06a28a9ca 100644 --- a/packages/backend/src/server/activitypub/featured.ts +++ b/packages/backend/src/server/activitypub/featured.ts @@ -5,15 +5,16 @@ import renderOrderedCollection from '@/remote/activitypub/renderer/ordered-colle import { setResponseType } from '../activitypub.js'; import renderNote from '@/remote/activitypub/renderer/note.js'; import { Users, Notes, UserNotePinings } from '@/models/index.js'; +import { userCache } from './cache.js'; export default async (ctx: Router.RouterContext) => { const userId = ctx.params.user; - // Verify user - const user = await Users.findOne({ + // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる + const user = await userCache.fetch(userId, () => Users.findOne({ id: userId, host: null, - }); + }).then(x => x || null)); if (user == null) { ctx.status = 404; diff --git a/packages/backend/src/server/activitypub/followers.ts b/packages/backend/src/server/activitypub/followers.ts index 5d1d7c59eb..fdae9dd928 100644 --- a/packages/backend/src/server/activitypub/followers.ts +++ b/packages/backend/src/server/activitypub/followers.ts @@ -10,6 +10,7 @@ import renderFollowUser from '@/remote/activitypub/renderer/follow-user.js'; import { setResponseType } from '../activitypub.js'; import { Users, Followings, UserProfiles } from '@/models/index.js'; import { LessThan } from 'typeorm'; +import { userCache } from './cache.js'; export default async (ctx: Router.RouterContext) => { const userId = ctx.params.user; @@ -27,11 +28,11 @@ export default async (ctx: Router.RouterContext) => { return; } - // Verify user - const user = await Users.findOne({ + // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる + const user = await userCache.fetch(userId, () => Users.findOne({ id: userId, host: null, - }); + }).then(x => x || null)); if (user == null) { ctx.status = 404; diff --git a/packages/backend/src/server/activitypub/following.ts b/packages/backend/src/server/activitypub/following.ts index 23110ce873..eb1b7a9d8c 100644 --- a/packages/backend/src/server/activitypub/following.ts +++ b/packages/backend/src/server/activitypub/following.ts @@ -11,6 +11,7 @@ import { setResponseType } from '../activitypub.js'; import { Users, Followings, UserProfiles } from '@/models/index.js'; import { LessThan, FindConditions } from 'typeorm'; import { Following } from '@/models/entities/following.js'; +import { userCache } from './cache.js'; export default async (ctx: Router.RouterContext) => { const userId = ctx.params.user; @@ -28,11 +29,11 @@ export default async (ctx: Router.RouterContext) => { return; } - // Verify user - const user = await Users.findOne({ + // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる + const user = await userCache.fetch(userId, () => Users.findOne({ id: userId, host: null, - }); + }).then(x => x || null)); if (user == null) { ctx.status = 404; diff --git a/packages/backend/src/server/activitypub/outbox.ts b/packages/backend/src/server/activitypub/outbox.ts index 57c126752a..db2a18efcd 100644 --- a/packages/backend/src/server/activitypub/outbox.ts +++ b/packages/backend/src/server/activitypub/outbox.ts @@ -15,6 +15,7 @@ import { Users, Notes } from '@/models/index.js'; import { makePaginationQuery } from '../api/common/make-pagination-query.js'; import { Brackets } from 'typeorm'; import { Note } from '@/models/entities/note.js'; +import { userCache } from './cache.js'; export default async (ctx: Router.RouterContext) => { const userId = ctx.params.user; @@ -35,11 +36,11 @@ export default async (ctx: Router.RouterContext) => { return; } - // Verify user - const user = await Users.findOne({ + // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる + const user = await userCache.fetch(userId, () => Users.findOne({ id: userId, host: null, - }); + }).then(x => x || null)); if (user == null) { ctx.status = 404; diff --git a/packages/backend/src/server/api/endpoints/endpoint.ts b/packages/backend/src/server/api/endpoints/endpoint.ts index 9db140183c..c174126779 100644 --- a/packages/backend/src/server/api/endpoints/endpoint.ts +++ b/packages/backend/src/server/api/endpoints/endpoint.ts @@ -20,9 +20,9 @@ export default define(meta, paramDef, async (ps) => { const ep = endpoints.find(x => x.name === ps.endpoint); if (ep == null) return null; return { - params: Object.entries(ep.meta.params || {}).map(([k, v]) => ({ + params: Object.entries(ep.params.properties || {}).map(([k, v]) => ({ name: k, - type: v.validator.name === 'ID' ? 'String' : v.validator.name, + type: v.type.charAt(0).toUpperCase() + v.type.slice(1), })), }; }); diff --git a/packages/backend/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts index f4b56fc8a5..2fc7b56cc2 100644 --- a/packages/backend/src/server/nodeinfo.ts +++ b/packages/backend/src/server/nodeinfo.ts @@ -4,6 +4,7 @@ import { fetchMeta } from '@/misc/fetch-meta.js'; import { Users, Notes } from '@/models/index.js'; import { MoreThan } from 'typeorm'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; +import { Cache } from '@/misc/cache.js'; const router = new Router(); @@ -81,15 +82,17 @@ const nodeinfo2 = async () => { }; }; +const cache = new Cache>>(1000 * 60 * 10); + router.get(nodeinfo2_1path, async ctx => { - const base = await nodeinfo2(); + const base = await cache.fetch(null, () => nodeinfo2()); ctx.body = { version: '2.1', ...base }; ctx.set('Cache-Control', 'public, max-age=600'); }); router.get(nodeinfo2_0path, async ctx => { - const base = await nodeinfo2(); + const base = await cache.fetch(null, () => nodeinfo2()); delete base.software.repository; diff --git a/packages/backend/src/server/web/index.ts b/packages/backend/src/server/web/index.ts index f57c4bb826..9cd42ea793 100644 --- a/packages/backend/src/server/web/index.ts +++ b/packages/backend/src/server/web/index.ts @@ -10,6 +10,9 @@ import Router from '@koa/router'; import send from 'koa-send'; import favicon from 'koa-favicon'; import views from 'koa-views'; +import { createBullBoard } from '@bull-board/api'; +import { BullAdapter } from '@bull-board/api/bullAdapter.js'; +import { KoaAdapter } from '@bull-board/koa'; import packFeed from './feed.js'; import { fetchMeta } from '@/misc/fetch-meta.js'; @@ -20,6 +23,7 @@ import * as Acct from '@/misc/acct.js'; import { getNoteSummary } from '@/misc/get-note-summary.js'; import { urlPreviewHandler } from './url-preview.js'; import { manifestHandler } from './manifest.js'; +import { queues } from '@/queue/queues.js'; const _filename = fileURLToPath(import.meta.url); const _dirname = dirname(_filename); @@ -32,6 +36,37 @@ const swAssets = `${_dirname}/../../../../../built/_sw_dist_/`; // Init app const app = new Koa(); +//#region Bull Dashboard +const bullBoardPath = '/queue'; + +// Authenticate +app.use(async (ctx, next) => { + if (ctx.path === bullBoardPath || ctx.path.startsWith(bullBoardPath + '/')) { + const token = ctx.cookies.get('token'); + if (token == null) { + ctx.status = 401; + return; + } + const user = await Users.findOne({ token }); + if (user == null || !(user.isAdmin || user.isModerator)) { + ctx.status = 403; + return; + } + } + await next(); +}); + +const serverAdapter = new KoaAdapter(); + +createBullBoard({ + queues: queues.map(q => new BullAdapter(q)), + serverAdapter, +}); + +serverAdapter.setBasePath(bullBoardPath); +app.use(serverAdapter.registerPlugin()); +//#endregion + // Init renderer app.use(views(_dirname + '/views', { extension: 'pug', diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 8c5f133628..b295534cd2 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -35,6 +35,12 @@ import { Channel } from '@/models/entities/channel.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { getAntennas } from '@/misc/antenna-cache.js'; import { endedPollNotificationQueue } from '@/queue/queues.js'; +import { Cache } from '@/misc/cache.js'; +import { UserProfile } from '@/models/entities/user-profile.js'; + +const usersCache = new Cache(Infinity); + +const mutedWordsCache = new Cache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5); type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; @@ -91,6 +97,13 @@ class NotificationManager { } } +type MinimumUser = { + id: User['id']; + host: User['host']; + username: User['username']; + uri: User['uri']; +}; + type Option = { createdAt?: Date | null; name?: string | null; @@ -102,9 +115,9 @@ type Option = { localOnly?: boolean | null; cw?: string | null; visibility?: string; - visibleUsers?: User[] | null; + visibleUsers?: MinimumUser[] | null; channel?: Channel | null; - apMentions?: User[] | null; + apMentions?: MinimumUser[] | null; apHashtags?: string[] | null; apEmojis?: string[] | null; uri?: string | null; @@ -199,7 +212,7 @@ export default async (user: { id: User['id']; username: User['username']; host: tags = tags.filter(tag => Array.from(tag || '').length <= 128).splice(0, 32); if (data.reply && (user.id !== data.reply.userId) && !mentionedUsers.some(u => u.id === data.reply!.userId)) { - mentionedUsers.push(await Users.findOneOrFail(data.reply.userId)); + mentionedUsers.push(await usersCache.fetch(data.reply.userId, () => Users.findOneOrFail(data.reply!.userId))); } if (data.visibility === 'specified') { @@ -212,7 +225,7 @@ export default async (user: { id: User['id']; username: User['username']; host: } if (data.reply && !data.visibleUsers.some(x => x.id === data.reply!.userId)) { - data.visibleUsers.push(await Users.findOneOrFail(data.reply.userId)); + data.visibleUsers.push(await usersCache.fetch(data.reply.userId, () => Users.findOneOrFail(data.reply!.userId))); } } @@ -241,10 +254,12 @@ export default async (user: { id: User['id']; username: User['username']; host: incNotesCountOfUser(user); // Word mute - // TODO: cache - UserProfiles.find({ - enableWordMute: true, - }).then(us => { + mutedWordsCache.fetch(null, () => UserProfiles.find({ + where: { + enableWordMute: true, + }, + select: ['userId', 'mutedWords'], + })).then(us => { for (const u of us) { checkWordMute(note, { id: u.userId }, u.mutedWords).then(shouldMute => { if (shouldMute) { @@ -260,21 +275,13 @@ export default async (user: { id: User['id']; username: User['username']; host: }); // Antenna - Followings.createQueryBuilder('following') - .andWhere(`following.followeeId = :userId`, { userId: note.userId }) - .getMany() - .then(async followings => { - const blockings = await Blockings.find({ blockerId: user.id }); // TODO: キャッシュしたい - const followers = followings.map(f => f.followerId); - for (const antenna of (await getAntennas())) { - if (blockings.some(blocking => blocking.blockeeId === antenna.userId)) continue; // この処理は checkHitAntenna 内でやるようにしてもいいかも - checkHitAntenna(antenna, note, user, followers).then(hit => { - if (hit) { - addNoteToAntenna(antenna, note, user); - } - }); + for (const antenna of (await getAntennas())) { + checkHitAntenna(antenna, note, user).then(hit => { + if (hit) { + addNoteToAntenna(antenna, note, user); } }); + } // Channel if (note.channelId) { @@ -465,7 +472,7 @@ function incRenoteCount(renote: Note) { .execute(); } -async function insertNote(user: { id: User['id']; host: User['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: User[]) { +async function insertNote(user: { id: User['id']; host: User['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]) { const insert = new Note({ id: genId(data.createdAt!), createdAt: data.createdAt!, @@ -597,7 +604,7 @@ async function notifyToWatchersOfReplyee(reply: Note, user: { id: User['id']; }, } } -async function createMentionedEvents(mentionedUsers: User[], note: Note, nm: NotificationManager) { +async function createMentionedEvents(mentionedUsers: MinimumUser[], note: Note, nm: NotificationManager) { for (const u of mentionedUsers.filter(u => Users.isLocalUser(u))) { const threadMuted = await NoteThreadMutings.findOne({ userId: u.id, diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts index cf23656f8f..356dc39727 100644 --- a/packages/backend/src/services/note/delete.ts +++ b/packages/backend/src/services/note/delete.ts @@ -29,6 +29,10 @@ export default async function(user: User, note: Note, quiet = false) { Notes.decrement({ id: note.renoteId }, 'score', 1); } + if (note.replyId) { + await Notes.decrement({ id: note.replyId }, 'repliesCount', 1); + } + if (!quiet) { publishNoteStream(note.id, 'deleted', { deletedAt: deletedAt, diff --git a/packages/backend/test/note.ts b/packages/backend/test/note.ts index 62cea5208b..942b2709df 100644 --- a/packages/backend/test/note.ts +++ b/packages/backend/test/note.ts @@ -333,4 +333,36 @@ describe('Note', () => { assert.strictEqual(res.status, 400); })); }); + + describe('notes/delete', () => { + it('delete a reply', async(async () => { + const mainNoteRes = await request('/notes/create', { + text: 'main post', + }, alice); + const replyOneRes = await request('/notes/create', { + text: 'reply one', + replyId: mainNoteRes.body.createdNote.id + }, alice); + const replyTwoRes = await request('/notes/create', { + text: 'reply two', + replyId: mainNoteRes.body.createdNote.id + }, alice); + + const deleteOneRes = await request('/notes/delete', { + noteId: replyOneRes.body.createdNote.id, + }, alice); + + assert.strictEqual(deleteOneRes.status, 204); + let mainNote = await Notes.findOne({id: mainNoteRes.body.createdNote.id}); + assert.strictEqual(mainNote.repliesCount, 1); + + const deleteTwoRes = await request('/notes/delete', { + noteId: replyTwoRes.body.createdNote.id, + }, alice); + + assert.strictEqual(deleteTwoRes.status, 204); + mainNote = await Notes.findOne({id: mainNoteRes.body.createdNote.id}); + assert.strictEqual(mainNote.repliesCount, 0); + })); + }); }); diff --git a/packages/backend/yarn.lock b/packages/backend/yarn.lock index 67a02742d4..3210259e48 100644 --- a/packages/backend/yarn.lock +++ b/packages/backend/yarn.lock @@ -35,6 +35,34 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@bull-board/api@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@bull-board/api/-/api-3.10.0.tgz#036cb0daed908920acd356c8addc19bcaabda5f2" + integrity sha512-VAoTkb7hflJ1lYHGCMyhpZtUK7sqQqpTqqDU/yqn5+BpyVoPdQ+ULsyEuDotbthWLeegSJZ1gN35jLg/NTV71g== + dependencies: + redis-info "^3.0.8" + +"@bull-board/koa@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@bull-board/koa/-/koa-3.10.0.tgz#5e05bf491cebda8b451727ada8e1f9f07fcb63d7" + integrity sha512-+3PqgHw5kExGXFu025WOQf/1sdLeWuEimus0peyp9/arqaC2+eclqrA3OuB9HrDHGLd7hhq0rPkM1lwEtmQU/A== + dependencies: + "@bull-board/api" "3.10.0" + "@bull-board/ui" "3.10.0" + ejs "^3.1.6" + koa "^2.13.1" + koa-mount "^4.0.0" + koa-router "^10.0.0" + koa-static "^5.0.0" + koa-views "^7.0.1" + +"@bull-board/ui@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@bull-board/ui/-/ui-3.10.0.tgz#5217a265e11bc3cfe41ae662fc9434a7769528af" + integrity sha512-0TkrMAe6p/j/Zy//YRUzFXW0jlAmBNzX8hVx9nQIYZm+o/gkk6a9PgVkhLsQS7AdWLzSKqB8YTRhkxm/8MjGqw== + dependencies: + "@bull-board/api" "3.10.0" + "@cspotcode/source-map-consumer@0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" @@ -61,10 +89,10 @@ ky "^0.25.1" ky-universal "^0.8.2" -"@discordapp/twemoji@13.1.0": - version "13.1.0" - resolved "https://registry.yarnpkg.com/@discordapp/twemoji/-/twemoji-13.1.0.tgz#6b25f3958fa8fd68692248c87776bc737fd009a9" - integrity sha512-KEw/te+ylD2MHutzigafyptv0kdTU05Dbgxr9Y5J9IAQw8PbFz16nKtlPnJtA23BLp9fZQeNXzUmegkRi7fpDA== +"@discordapp/twemoji@13.1.1": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@discordapp/twemoji/-/twemoji-13.1.1.tgz#f750d491ffb740eca619fac0c63650c1de7fff91" + integrity sha512-WDnPjWq/trfCcZk7dzQ2cYH5v5XaIfPzyixJ//O9XKilYYZRVS3p61vFvax5qMwanMMbnNG1iOzeqHKtivO32A== dependencies: fs-extra "^8.0.1" jsonfile "^5.0.0" @@ -82,16 +110,16 @@ pump "^3.0.0" secure-json-parse "^2.1.0" -"@eslint/eslintrc@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.0.tgz#7ce1547a5c46dfe56e1e45c3c9ed18038c721c6a" - integrity sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w== +"@eslint/eslintrc@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" + integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== dependencies: ajv "^6.12.4" debug "^4.3.2" espree "^9.3.1" globals "^13.9.0" - ignore "^4.0.6" + ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" minimatch "^3.0.4" @@ -216,10 +244,10 @@ require-from-string "^2.0.2" uri-js "^4.2.2" -"@redocly/openapi-core@1.0.0-beta.83": - version "1.0.0-beta.83" - resolved "https://registry.yarnpkg.com/@redocly/openapi-core/-/openapi-core-1.0.0-beta.83.tgz#df1324cc6f1874ecf3046e503192cf872f134a2f" - integrity sha512-XwlxMAmNEQeyBfODXVg2iBpSUqzCwT2zI+7o5iKxjUwJ+5ZugNOYjZGGM3Q9rJGqzFVwLKdElM5a1MlhPvlu4Q== +"@redocly/openapi-core@1.0.0-beta.88": + version "1.0.0-beta.88" + resolved "https://registry.yarnpkg.com/@redocly/openapi-core/-/openapi-core-1.0.0-beta.88.tgz#acce3d58451fea3964b448b169c0ef7fbe56f72a" + integrity sha512-E9vkLvumIkzII0ydDFGr6uYbZgI9rHMxBveefzM51OUvobvifryXb6VcnQ1T0P8VoHRiYwpgiWlmZeDsNAdZdg== dependencies: "@redocly/ajv" "^8.6.4" "@types/node" "^14.11.8" @@ -237,7 +265,7 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-3.1.2.tgz#548650de521b344e3781fbdb0ece4aa6f729afb8" integrity sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ== -"@sindresorhus/is@^4.2.0": +"@sindresorhus/is@^4.6.0": version "4.6.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== @@ -757,10 +785,10 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" -"@types/sharp@0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.29.5.tgz#9c7032d30d138ad16dde6326beaff2af757b91b3" - integrity sha512-3TC+S3H5RwnJmLYMHrcdfNjz/CaApKmujjY9b6PU/pE6n0qfooi99YqXGWoW8frU9EWYj/XTI35Pzxa+ThAZ5Q== +"@types/sharp@0.30.0": + version "0.30.0" + resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.30.0.tgz#58cb016c8fdc558b4c5771ad1f3668336685c843" + integrity sha512-bZ0Y/JVlrOyqwlBMJ2taEgnwFavjLnyZmLOLecmOesuG5kR2Lx9b2fM4osgfVjLJi8UlE+t3R1JzRVMxF6MbfA== dependencies: "@types/node" "*" @@ -815,10 +843,10 @@ dependencies: "@types/node" "*" -"@types/ws@8.5.2": - version "8.5.2" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.2.tgz#77e0c2e360e9579da930ffcfa53c5975ea3bdd26" - integrity sha512-VXI82ykONr5tacHEojnErTQk+KQSoYbW1NB6iz6wUwrNd+BqfkfggQNoNdCqhJSzbNumShPERbM+Pc5zpfhlbw== +"@types/ws@8.5.3": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== dependencies: "@types/node" "*" @@ -827,14 +855,14 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== -"@typescript-eslint/eslint-plugin@5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.14.0.tgz#5119b67152356231a0e24b998035288a9cd21335" - integrity sha512-ir0wYI4FfFUDfLcuwKzIH7sMVA+db7WYen47iRSaCGl+HMAZI9fpBwfDo45ZALD3A45ZGyHWDNLhbg8tZrMX4w== +"@typescript-eslint/eslint-plugin@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.15.0.tgz#c28ef7f2e688066db0b6a9d95fb74185c114fb9a" + integrity sha512-u6Db5JfF0Esn3tiAKELvoU5TpXVSkOpZ78cEGn/wXtT2RVqs2vkt4ge6N8cRCyw7YVKhmmLDbwI2pg92mlv7cA== dependencies: - "@typescript-eslint/scope-manager" "5.14.0" - "@typescript-eslint/type-utils" "5.14.0" - "@typescript-eslint/utils" "5.14.0" + "@typescript-eslint/scope-manager" "5.15.0" + "@typescript-eslint/type-utils" "5.15.0" + "@typescript-eslint/utils" "5.15.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -842,69 +870,69 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/parser@5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.14.0.tgz#7c79f898aa3cff0ceee6f1d34eeed0f034fb9ef3" - integrity sha512-aHJN8/FuIy1Zvqk4U/gcO/fxeMKyoSv/rS46UXMXOJKVsLQ+iYPuXNbpbH7cBLcpSbmyyFbwrniLx5+kutu1pw== +"@typescript-eslint/parser@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.15.0.tgz#95f603f8fe6eca7952a99bfeef9b85992972e728" + integrity sha512-NGAYP/+RDM2sVfmKiKOCgJYPstAO40vPAgACoWPO/+yoYKSgAXIFaBKsV8P0Cc7fwKgvj27SjRNX4L7f4/jCKQ== dependencies: - "@typescript-eslint/scope-manager" "5.14.0" - "@typescript-eslint/types" "5.14.0" - "@typescript-eslint/typescript-estree" "5.14.0" + "@typescript-eslint/scope-manager" "5.15.0" + "@typescript-eslint/types" "5.15.0" + "@typescript-eslint/typescript-estree" "5.15.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.14.0.tgz#ea518962b42db8ed0a55152ea959c218cb53ca7b" - integrity sha512-LazdcMlGnv+xUc5R4qIlqH0OWARyl2kaP8pVCS39qSL3Pd1F7mI10DbdXeARcE62sVQE4fHNvEqMWsypWO+yEw== +"@typescript-eslint/scope-manager@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.15.0.tgz#d97afab5e0abf4018d1289bd711be21676cdd0ee" + integrity sha512-EFiZcSKrHh4kWk0pZaa+YNJosvKE50EnmN4IfgjkA3bTHElPtYcd2U37QQkNTqwMCS7LXeDeZzEqnsOH8chjSg== dependencies: - "@typescript-eslint/types" "5.14.0" - "@typescript-eslint/visitor-keys" "5.14.0" + "@typescript-eslint/types" "5.15.0" + "@typescript-eslint/visitor-keys" "5.15.0" -"@typescript-eslint/type-utils@5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.14.0.tgz#711f08105860b12988454e91df433567205a8f0b" - integrity sha512-d4PTJxsqaUpv8iERTDSQBKUCV7Q5yyXjqXUl3XF7Sd9ogNLuKLkxz82qxokqQ4jXdTPZudWpmNtr/JjbbvUixw== +"@typescript-eslint/type-utils@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.15.0.tgz#d2c02eb2bdf54d0a645ba3a173ceda78346cf248" + integrity sha512-KGeDoEQ7gHieLydujGEFLyLofipe9PIzfvA/41urz4hv+xVxPEbmMQonKSynZ0Ks2xDhJQ4VYjB3DnRiywvKDA== dependencies: - "@typescript-eslint/utils" "5.14.0" + "@typescript-eslint/utils" "5.15.0" debug "^4.3.2" tsutils "^3.21.0" -"@typescript-eslint/types@5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.14.0.tgz#96317cf116cea4befabc0defef371a1013f8ab11" - integrity sha512-BR6Y9eE9360LNnW3eEUqAg6HxS9Q35kSIs4rp4vNHRdfg0s+/PgHgskvu5DFTM7G5VKAVjuyaN476LCPrdA7Mw== +"@typescript-eslint/types@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.15.0.tgz#c7bdd103843b1abae97b5518219d3e2a0d79a501" + integrity sha512-yEiTN4MDy23vvsIksrShjNwQl2vl6kJeG9YkVJXjXZnkJElzVK8nfPsWKYxcsGWG8GhurYXP4/KGj3aZAxbeOA== -"@typescript-eslint/typescript-estree@5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.14.0.tgz#78b7f7385d5b6f2748aacea5c9b7f6ae62058314" - integrity sha512-QGnxvROrCVtLQ1724GLTHBTR0lZVu13izOp9njRvMkCBgWX26PKvmMP8k82nmXBRD3DQcFFq2oj3cKDwr0FaUA== +"@typescript-eslint/typescript-estree@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.15.0.tgz#81513a742a9c657587ad1ddbca88e76c6efb0aac" + integrity sha512-Hb0e3dGc35b75xLzixM3cSbG1sSbrTBQDfIScqdyvrfJZVEi4XWAT+UL/HMxEdrJNB8Yk28SKxPLtAhfCbBInA== dependencies: - "@typescript-eslint/types" "5.14.0" - "@typescript-eslint/visitor-keys" "5.14.0" + "@typescript-eslint/types" "5.15.0" + "@typescript-eslint/visitor-keys" "5.15.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.14.0.tgz#6c8bc4f384298cbbb32b3629ba7415f9f80dc8c4" - integrity sha512-EHwlII5mvUA0UsKYnVzySb/5EE/t03duUTweVy8Zqt3UQXBrpEVY144OTceFKaOe4xQXZJrkptCf7PjEBeGK4w== +"@typescript-eslint/utils@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.15.0.tgz#468510a0974d3ced8342f37e6c662778c277f136" + integrity sha512-081rWu2IPKOgTOhHUk/QfxuFog8m4wxW43sXNOMSCdh578tGJ1PAaWPsj42LOa7pguh173tNlMigsbrHvh/mtA== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.14.0" - "@typescript-eslint/types" "5.14.0" - "@typescript-eslint/typescript-estree" "5.14.0" + "@typescript-eslint/scope-manager" "5.15.0" + "@typescript-eslint/types" "5.15.0" + "@typescript-eslint/typescript-estree" "5.15.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.14.0.tgz#1927005b3434ccd0d3ae1b2ecf60e65943c36986" - integrity sha512-yL0XxfzR94UEkjBqyymMLgCBdojzEuy/eim7N9/RIcTNxpJudAcqsU8eRyfzBbcEzGoPWfdM3AGak3cN08WOIw== +"@typescript-eslint/visitor-keys@5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.15.0.tgz#5669739fbf516df060f978be6a6dce75855a8027" + integrity sha512-+vX5FKtgvyHbmIJdxMJ2jKm9z2BIlXJiuewI8dsDYMp5LzPUcuTT78Ya5iwvQg3VqSVdmxyM8Anj1Jeq7733ZQ== dependencies: - "@typescript-eslint/types" "5.14.0" + "@typescript-eslint/types" "5.15.0" eslint-visitor-keys "^3.0.0" "@ungap/promise-all-settled@1.1.2": @@ -1209,6 +1237,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +async@0.9.x: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + async@>=0.2.9: version "3.2.0" resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" @@ -1243,10 +1276,10 @@ autwh@0.1.0: dependencies: oauth "0.9.15" -aws-sdk@2.1079.0: - version "2.1079.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1079.0.tgz#41ede54aa4ba5ce77d4ffe202f9a1ee7869da2a8" - integrity sha512-WHYWiye9f2XYQ33Rj/uVw4VF/Qq/xrB9NDnGlRhgK8Ga7T20+8/iZD5/Z8wICVNZTsfUZ3g6LfkeZ1l+LZhHKw== +aws-sdk@2.1096.0: + version "2.1096.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1096.0.tgz#d41d6c6afe44b00977d4fe4c68e9450941d72931" + integrity sha512-q+hotU57U8bGpz1pf5CkO4z630ay0xGJ9HedahKPZ0Xk3/X0GH+QFYPBWJ5IMTtO30bjfPH0zTaL2vJmMXLBrQ== dependencies: buffer "4.9.2" events "1.1.1" @@ -2101,6 +2134,13 @@ debug@4.3.3: dependencies: ms "2.1.2" +debug@^3.1.0, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -2108,13 +2148,6 @@ debug@^3.2.6: dependencies: ms "^2.1.1" -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - debug@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" @@ -2440,6 +2473,13 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +ejs@^3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a" + integrity sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw== + dependencies: + jake "^10.6.1" + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -2673,12 +2713,12 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@8.10.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.10.0.tgz#931be395eb60f900c01658b278e05b6dae47199d" - integrity sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw== +eslint@8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.11.0.tgz#88b91cfba1356fc10bb9eb592958457dfe09fb37" + integrity sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA== dependencies: - "@eslint/eslintrc" "^1.2.0" + "@eslint/eslintrc" "^1.2.1" "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" @@ -2918,6 +2958,13 @@ file-type@17.1.1: strtok3 "^7.0.0-alpha.7" token-types "^5.0.0-alpha.2" +filelist@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.2.tgz#80202f21462d4d1c2e214119b1807c1bc0380e5b" + integrity sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ== + dependencies: + minimatch "^3.0.4" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -3267,12 +3314,12 @@ got@11.5.1: p-cancelable "^2.0.0" responselike "^2.0.0" -got@12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/got/-/got-12.0.1.tgz#78747f1c5bc7069bbd739636ed8b70c7f2140a39" - integrity sha512-1Zhoh+lDej3t7Ks1BP/Jufn+rNqdiHQgUOcTxHzg2Dao1LQfp5S4Iq0T3iBxN4Zdo7QqCJL+WJUNzDX6rCP2Ew== +got@12.0.2: + version "12.0.2" + resolved "https://registry.yarnpkg.com/got/-/got-12.0.2.tgz#8ce4c3baa50bb18a0858d2539caa0fac19e109bf" + integrity sha512-Zi4yHiqCgaorUbknr/RHFBsC3XqjSodaw0F3qxlqAqyj+OGYZl37/uy01R0qz++KANKQYdY5FHJ0okXZpEzwWQ== dependencies: - "@sindresorhus/is" "^4.2.0" + "@sindresorhus/is" "^4.6.0" "@szmarczak/http-timer" "^5.0.1" "@types/cacheable-request" "^6.0.2" "@types/responselike" "^1.0.0" @@ -3281,7 +3328,7 @@ got@12.0.1: decompress-response "^6.0.0" form-data-encoder "1.7.1" get-stream "^6.0.1" - http2-wrapper "^2.1.9" + http2-wrapper "^2.1.10" lowercase-keys "^3.0.0" p-cancelable "^3.0.0" responselike "^2.0.0" @@ -3480,7 +3527,7 @@ http2-wrapper@^1.0.0-beta.5.0: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -http2-wrapper@^2.1.9: +http2-wrapper@^2.1.10: version "2.1.10" resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.1.10.tgz#307cd0cee2564723692ad34c2d570d12f10e83be" integrity sha512-QHgsdYkieKp+6JbXP25P+tepqiHYd+FVnDwXpxi/BlUcoIB0nsmTOymTNvETuTO+pDuwcSklPE72VR3DqV+Haw== @@ -3551,11 +3598,6 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - ignore@^5.1.4: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" @@ -3943,6 +3985,16 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +jake@^10.6.1: + version "10.8.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b" + integrity sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A== + dependencies: + async "0.9.x" + chalk "^2.4.2" + filelist "^1.0.1" + minimatch "^3.0.4" + jmespath@0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" @@ -4221,7 +4273,7 @@ koa-logger@3.2.1: humanize-number "0.0.2" passthrough-counter "^1.0.0" -koa-mount@4.0.0: +koa-mount@4.0.0, koa-mount@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/koa-mount/-/koa-mount-4.0.0.tgz#e0265e58198e1a14ef889514c607254ff386329c" integrity sha512-rm71jaA/P+6HeCpoRhmCv8KVBIi0tfGuO/dMKicbQnQW/YJntJ6MnnspkodoA4QstMVEZArsCphmd0bJEtoMjQ== @@ -4229,6 +4281,17 @@ koa-mount@4.0.0: debug "^4.0.1" koa-compose "^4.1.0" +koa-router@^10.0.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/koa-router/-/koa-router-10.1.1.tgz#20809f82648518b84726cd445037813cd99f17ff" + integrity sha512-z/OzxVjf5NyuNO3t9nJpx7e1oR3FSBAauiwXtMQu4ppcnuNZzTaQ4p21P8A6r2Es8uJJM339oc4oVW+qX7SqnQ== + dependencies: + debug "^4.1.1" + http-errors "^1.7.3" + koa-compose "^4.1.0" + methods "^1.1.2" + path-to-regexp "^6.1.0" + koa-send@5.0.1, koa-send@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.1.tgz#39dceebfafb395d0d60beaffba3a70b4f543fe79" @@ -4246,6 +4309,14 @@ koa-slow@2.1.0: lodash.isregexp "3.0.5" q "1.4.1" +koa-static@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943" + integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ== + dependencies: + debug "^3.1.0" + koa-send "^5.0.0" + koa-views@*: version "7.0.1" resolved "https://registry.yarnpkg.com/koa-views/-/koa-views-7.0.1.tgz#0c8f8e65d5cd2e08249430cb83dc361e49a17a5a" @@ -4260,7 +4331,7 @@ koa-views@*: pretty "^2.0.0" resolve-path "^1.4.0" -koa-views@7.0.2: +koa-views@7.0.2, koa-views@^7.0.1: version "7.0.2" resolved "https://registry.yarnpkg.com/koa-views/-/koa-views-7.0.2.tgz#c96fd9e2143ef00c29dc5160c5ed639891aa723d" integrity sha512-dvx3mdVeSVuIPEaKAoGbxLcenudvhl821xxyuRbcoA+bOJ2dvN8wlGjkLu0ZFMlkCscXZV6lzxy28rafeazI/w== @@ -4273,7 +4344,7 @@ koa-views@7.0.2: pretty "^2.0.0" resolve-path "^1.4.0" -koa@2.13.4: +koa@2.13.4, koa@^2.13.1: version "2.13.4" resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.4.tgz#ee5b0cb39e0b8069c38d115139c774833d32462e" integrity sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g== @@ -4469,7 +4540,7 @@ lodash.union@^4.6.0: resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= -lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4594,17 +4665,17 @@ mime-db@1.44.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== -mime-db@1.51.0: - version "1.51.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@2.1.34: - version "2.1.34" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" - integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== +mime-types@2.1.35: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - mime-db "1.51.0" + mime-db "1.52.0" mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.24: version "2.1.27" @@ -4633,7 +4704,14 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -4730,10 +4808,10 @@ mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.3: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mocha@9.2.1: - version "9.2.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" - integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== +mocha@9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== dependencies: "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" @@ -4748,9 +4826,9 @@ mocha@9.2.1: he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" - minimatch "3.0.4" + minimatch "4.2.1" ms "2.1.3" - nanoid "3.2.0" + nanoid "3.3.1" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" @@ -4840,10 +4918,10 @@ nano-time@1.0.0: dependencies: big-integer "^1.6.16" -nanoid@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" - integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== +nanoid@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== nanoid@^3.1.30: version "3.1.30" @@ -4923,10 +5001,10 @@ node-fetch@3.0.0-beta.9: data-uri-to-buffer "^3.0.1" fetch-blob "^2.1.1" -node-fetch@3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.2.2.tgz#16d33fbe32ca7c6ca1ca8ba5dfea1dd885c59f04" - integrity sha512-Cwhq1JFIoon15wcIkFzubVNFE5GvXGV82pKf4knXXjvGmn7RJKcypeuqcVNZMGDZsAFWyIRya/anwAJr7TWJ7w== +node-fetch@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.2.3.tgz#a03c9cc2044d21d1a021566bd52f080f333719a6" + integrity sha512-AXP18u4pidSZ1xYXRDPY/8jdv3RAozIt/WLNR/MBGZAz+xjtlr90RvCnsvHQRiXyWliZF/CpytExp32UU67/SA== dependencies: data-uri-to-buffer "^4.0.0" fetch-blob "^3.1.4" @@ -5881,6 +5959,13 @@ redis-errors@^1.0.0, redis-errors@^1.2.0: resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= +redis-info@^3.0.8: + version "3.1.0" + resolved "https://registry.yarnpkg.com/redis-info/-/redis-info-3.1.0.tgz#5e349c8720e82d27ac84c73136dce0931e10469a" + integrity sha512-ER4L9Sh/vm63DkIE0bkSjxluQlioBiBgf5w1UuldaW/3vPcecdljVDisZhmnCMvsxHNiARTTDDHGg9cGwTfrKg== + dependencies: + lodash "^4.17.11" + redis-lock@0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/redis-lock/-/redis-lock-0.1.4.tgz#e83590bee22b5f01cdb65bfbd88d988045356272" @@ -6117,6 +6202,13 @@ seedrandom@3.0.5: resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== +semver@7.3.5, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -6129,13 +6221,6 @@ semver@^7.3.2, semver@^7.3.4: dependencies: lru-cache "^6.0.0" -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -6171,10 +6256,10 @@ sha.js@^2.4.11: inherits "^2.0.1" safe-buffer "^5.0.1" -sharp@0.30.2: - version "0.30.2" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.30.2.tgz#95b309b2740424702dc19b62a62595dd34a458b1" - integrity sha512-mrMeKI5ECTdYhslPlA2TbBtU3nZXMEBcQwI6qYXjPlu1LpW4HBZLFm6xshMI1HpIdEEJ3UcYp5AKifLT/fEHZQ== +sharp@0.30.3: + version "0.30.3" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.30.3.tgz#315a1817423a4d1cde5119a21c99c234a7a6fb37" + integrity sha512-rjpfJFK58ZOFSG8sxYSo3/JQb4ej095HjXp9X7gVu7gEn1aqSG8TCW29h/Rr31+PXrFADo1H/vKfw0uhMQWFtg== dependencies: color "^4.2.1" detect-libc "^2.0.1" @@ -6534,10 +6619,10 @@ syslog-pro@1.0.0: dependencies: moment "^2.22.2" -systeminformation@5.11.6: - version "5.11.6" - resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.11.6.tgz#8624cbb2e95e6fa98a4ebb0d10759427c0e88144" - integrity sha512-7KBXgdnIDxABQ93w+GrPSrK/pup73+fM09VGka4A/+FhgzdlRY0JNGGDFmV8BHnFuzP9zwlI3n64yDbp7emasQ== +systeminformation@5.11.8: + version "5.11.8" + resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.11.8.tgz#fd6244cd13e5fcb863e6dde9cb02edb4a5a3115b" + integrity sha512-u30rM0KwGKiJof44Ak25WeSh9661NU2GshXpHPpv/zGXvvSGI5eALjpVJ3EYnIroceToWzy9+xkuMfjHIx6OiQ== tapable@^2.2.0: version "2.2.0" @@ -6700,10 +6785,10 @@ trace-redirect@1.0.6: resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= -ts-loader@9.2.7: - version "9.2.7" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.7.tgz#948654099ca96992b62ec47bd9cee5632006e101" - integrity sha512-Fxh44mKli9QezgbdCXkEJWxnedQ0ead7DXTH+lfXEPedu+Y9EtMJ2aQ9G3Dj1j7Q612E8931rww8NDZha4Tibg== +ts-loader@9.2.8: + version "9.2.8" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.8.tgz#e89aa32fa829c5cad0a1d023d6b3adecd51d5a48" + integrity sha512-gxSak7IHUuRtwKf3FIPSW1VpZcqF9+MBrHOvBp9cjHh+525SjtCIJKVGjRKIAfxBwDGDGCFF00rTfzB1quxdSw== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" @@ -6741,10 +6826,10 @@ tsc-alias@1.4.1: mylas "^2.1.4" normalize-path "^3.0.0" -tsconfig-paths@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz#f3e9b8f6876698581d94470c03c95b3a48c0e3d7" - integrity sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw== +tsconfig-paths@3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.0.tgz#4fcc48f9ccea8826c41b9ca093479de7f5018976" + integrity sha512-cg/1jAZoL57R39+wiw4u/SCC6Ic9Q5NqjBOb+9xISedOYurfog9ZNmKJSxAnb2m/5Bq4lE9lhUcau33Ml8DM0g== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.1" @@ -6800,6 +6885,11 @@ twemoji-parser@13.1.0, twemoji-parser@13.1.x: resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.1.0.tgz#65e7e449c59258791b22ac0b37077349127e3ea4" integrity sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg== +twemoji-parser@14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-14.0.0.tgz#13dabcb6d3a261d9efbf58a1666b182033bf2b62" + integrity sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" diff --git a/packages/client/package.json b/packages/client/package.json index 7a1ae47c05..b9eb32d20d 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -10,8 +10,8 @@ "lodash": "^4.17.21" }, "dependencies": { - "@discordapp/twemoji": "13.1.0", - "@fortawesome/fontawesome-free": "6.0.0", + "@discordapp/twemoji": "13.1.1", + "@fortawesome/fontawesome-free": "6.1.0", "@syuilo/aiscript": "0.11.1", "@types/escape-regexp": "0.0.1", "@types/glob": "7.2.0", @@ -33,8 +33,8 @@ "@types/webpack": "5.28.0", "@types/webpack-stream": "3.2.12", "@types/websocket": "1.0.5", - "@types/ws": "8.5.2", - "@typescript-eslint/parser": "5.14.0", + "@types/ws": "8.5.3", + "@typescript-eslint/parser": "5.15.0", "@vue/compiler-sfc": "3.2.31", "abort-controller": "3.0.0", "autobind-decorator": "2.4.0", @@ -49,10 +49,10 @@ "compare-versions": "4.1.3", "content-disposition": "0.5.4", "css-loader": "6.7.1", - "cssnano": "5.1.1", + "cssnano": "5.1.4", "date-fns": "2.28.0", "escape-regexp": "0.0.1", - "eslint": "8.10.0", + "eslint": "8.11.0", "eslint-plugin-vue": "8.5.0", "eventemitter3": "4.0.7", "feed": "4.2.2", @@ -62,17 +62,17 @@ "ip-cidr": "3.0.4", "json5": "2.2.0", "json5-loader": "4.0.1", - "katex": "0.15.2", + "katex": "0.15.3", "matter-js": "0.18.0", "mfm-js": "0.21.0", "misskey-js": "0.0.14", - "mocha": "9.2.1", + "mocha": "9.2.2", "ms": "2.1.3", "nested-property": "4.0.0", "parse5": "6.0.1", "photoswipe": "git+https://github.com/dimsemenov/photoswipe#v5-beta", "portscanner": "2.2.0", - "postcss": "8.4.8", + "postcss": "8.4.12", "postcss-loader": "6.2.1", "prismjs": "1.27.0", "private-ip": "2.3.3", @@ -96,10 +96,10 @@ "three": "0.138.3", "throttle-debounce": "3.0.1", "tinycolor2": "1.4.2", - "ts-loader": "9.2.7", + "ts-loader": "9.2.8", "tsc-alias": "1.5.0", - "tsconfig-paths": "3.13.0", - "twemoji-parser": "13.1.0", + "tsconfig-paths": "3.14.0", + "twemoji-parser": "14.0.0", "typescript": "4.6.2", "uuid": "8.3.2", "v-debounce": "0.1.2", @@ -107,7 +107,7 @@ "vue": "3.2.31", "vue-loader": "17.0.0", "vue-prism-editor": "2.0.0-alpha.2", - "vue-router": "4.0.13", + "vue-router": "4.0.14", "vue-style-loader": "4.1.3", "vue-svg-loader": "0.17.0-beta.2", "vuedraggable": "4.0.1", @@ -117,9 +117,9 @@ "ws": "8.5.0" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "5.12.1", + "@typescript-eslint/eslint-plugin": "5.15.0", "cross-env": "7.0.3", - "cypress": "9.5.1", + "cypress": "9.5.2", "eslint-plugin-import": "2.25.4", "start-server-and-test": "1.14.0" } diff --git a/packages/client/src/account.ts b/packages/client/src/account.ts index 4aeceeccab..bcc8a43be0 100644 --- a/packages/client/src/account.ts +++ b/packages/client/src/account.ts @@ -116,6 +116,7 @@ export async function login(token: Account['token'], redirect?: string) { if (_DEV_) console.log('logging as token ', token); const me = await fetchAccount(token); localStorage.setItem('account', JSON.stringify(me)); + document.cookie = `token=${token}; path=/; max-age=31536000`; // bull dashboardの認証とかで使う await addAccount(me.id, token); if (redirect) { diff --git a/packages/client/src/components/notifications.vue b/packages/client/src/components/notifications.vue index ca9b801797..dc900a670d 100644 --- a/packages/client/src/components/notifications.vue +++ b/packages/client/src/components/notifications.vue @@ -17,7 +17,7 @@