diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..d3c6e9c8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + groups: + development-dependencies: + dependency-type: "development" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/docker-hub-develop.yml b/.github/workflows/docker-hub-develop.yml index c38fa992..d6b1edf3 100644 --- a/.github/workflows/docker-hub-develop.yml +++ b/.github/workflows/docker-hub-develop.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Unshallow for git describe so we can create version.txt run: git fetch --prune --unshallow --tags --all --force - name: Prepare version file @@ -29,10 +29,10 @@ jobs: uses: docker/setup-qemu-action@v2.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.6.0 + uses: docker/setup-buildx-action@v2.10.0 - name: Log in to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/docker-hub-release.yml b/.github/workflows/docker-hub-release.yml index d6aecc13..b23d1796 100644 --- a/.github/workflows/docker-hub-release.yml +++ b/.github/workflows/docker-hub-release.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Get release tag run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - name: Unshallow for git describe so we can create version.txt @@ -28,10 +28,10 @@ jobs: uses: docker/setup-qemu-action@v2.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.6.0 + uses: docker/setup-buildx-action@v2.10.0 - name: Log in to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/mjolnir.yml b/.github/workflows/mjolnir.yml index 898f7612..1283ba3f 100644 --- a/.github/workflows/mjolnir.yml +++ b/.github/workflows/mjolnir.yml @@ -15,7 +15,7 @@ jobs: name: Build & Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Specifically use node 18 like in the readme. uses: actions/setup-node@v3 @@ -28,7 +28,7 @@ jobs: name: Unit tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Specifically use node 18 like in the readme. uses: actions/setup-node@v3 with: @@ -40,12 +40,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 60 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: '18' - name: Fetch and build mx-tester (cached across runs) - uses: baptiste0928/cargo-install@v1 + uses: baptiste0928/cargo-install@v2 with: crate: mx-tester version: "0.3.3" @@ -62,12 +62,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: '18' - name: Fetch and build mx-tester (cached across runs) - uses: baptiste0928/cargo-install@v1 + uses: baptiste0928/cargo-install@v2 with: crate: mx-tester version: "0.3.3" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b461f17d..f49c1e20 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,13 +4,15 @@ Draupnir is licensed under the Cooperative Software License. The reason for the license is simply because this project was something that I was previously employed to work on. -I have not decided whether I will accept contributions under the same license -or another license or a CLA yet. -I will welcome advice, but I will not welcome attempts to parsuade me to re-adopt -and relicense under Apache-2.0 unless being offered compensation. +I have not decided whether I will accept contributions under the +same license or another license or a CLA yet. +I will welcome advice, but I will not welcome attempts to parsuade +me to re-adopt and relicense under Apache-2.0 unless being offered +compensation. -The easiest way forwards would be for me to accept individual contributions under -Apache-2.0. +As of now, I am accepting contributions under the Apache-2.0 license +in the same way as Mjolnir. This allows me the option to relicense +Draupnir under Apache-2.0 without needing to chase up all contributors. ## How to contribute @@ -185,3 +187,58 @@ matrix together all the fragmented communication technologies out there we are reliant on contributions and collaboration from the community to do so. So please get involved - and we hope you have as much fun hacking on Matrix as we do! + +## Further notes on license and its relation to business in general + +Ultimately most open source software contributions start by gifting +labour without any obligation or transaction. + +There is no ethical way to directly sell this labour. + +Many so called post open source[^post-open-source] ideas fixate on +finding a way to conduct business in an ethical way, +and this is problematic. + +Once you start working within capitalism with capitalism, and exchange +your power and influence over a work to monitize the work itself, +the work will gain inertia and a power of its own that you cannot control. +You will work for the work, for external interests, and these won't +be the interests of your powerless users who you were among to begin with. + +It would be extreme, but I am tempted to suggest that by performing a +buisness this way, you are part of an effort +which not only reinforces capitalism but works to make it more +efficient. Effectively working to make capitalism more powerful. +Congratulations. + +Another point that is often brought up in these discussions is how +software licensing relies on an appeal to state power, the power of +the law. + +Therefore I propose a new licensing model, one which appeals +to the power of public pressure rather than the law. + +Such a license would be liberal, allowing incorperation into +proprietary works provided it retained a notice. +However, any work which is used in any way to conduct business must +report all software being used by the buisness with this license, +all turnover made by the buisness, all profit made by the buisness +and an estimation of both profit and turnover made by the buisness in +relation to the collection of software reported. + +It is not clear to me how often these figures should be reported +and when, or even where they should be reported to (ideally they could +be found centrally). It is also unclear how to create the legalise +required. + +With the information these licenses would provide, public pressure +could then be used to demand reperations for the profits made by +pillaging and destructive businesses. +It is not clear yet how any reperations would be distributed, +probably through some system of +[venture communes](https://wiki.p2pfoundation.net/Venture_Commune). +The idea is to ensure that the developers and users of projects +would not be distracted from providing each other mutual +support and to give them a hope of escaping. + +[^post-open-source] https://applied-langua.ge/posts/the-poverty-of-post-open-source.html. diff --git a/README.md b/README.md index edc48a45..382de1be 100644 --- a/README.md +++ b/README.md @@ -5,34 +5,59 @@ for more information. > I offer you the ring, which was burned, laid upon the pyre of Baldr by Odin. -This is a hard fork of [Mjolnir](https://github.com/matrix-org/mjolnir), +This is a continuation and fork of [Mjolnir](https://github.com/matrix-org/mjolnir), with an entirely new framework for interacting with Matrix written to overcome some of the burdens there were holding development of mjolnir. ## Status -The command handler is currently being refactored and the syntax will become -incompatible with legacy Mjolnir commands. The UX will be overhauled -as such and we will consider the launch of Draupnir a 2.0.0 release. +The command handler is currently being refactored and some command syntax will become +incompatible with legacy Mjolnir commands. +The UX is being overhauled and Draupnir is slowly moving towards a 2.0.0 release. -As Draupnir heads towards `v2.0.0` releases will appear [here](https://github.com/Gnuxie/Draupnir/releases). -Until `v2.0.0` there will be frequent changes to commands. +As Draupnir heads towards `v2.0.0`, releases will appear [here](https://github.com/Gnuxie/Draupnir/releases). +Until `v2.0.0` there will be frequent changes to commands but all of these +will be noted in the changes for that release. -Migrating from Mjolnir is straightforward, and Draupnir remains backwards compatible. -So it is possible to try Draupnir and still have the option to switch back to Mjolnir. +### Migration + +Migrating from Mjolnir is straightforward and requires no manual steps, +migration for your setup is likely as simple as changing your server config to +pull the latest Draupnir docker image instead of a mjolnir one. +Draupnir remains backwards compatible so that it is possible to try Draupnir +and still have the option to switch back to Mjolnir. + +Any problems with migration should be reported to our [support room](https://matrix.to/#/#draupnir:matrix.org). ## Features -As an all-in-one moderation tool, it can protect your server from malicious invites, spam -messages, and whatever else you don't want. In addition to server-level protection, Draupnir -is great for communities wanting to protect their rooms without having to use their personal -accounts for moderation. +As an all-in-one moderation tool, Draupnir can protect your community by +applying policies from both your own and community curated policy lists. The bot by default includes support for bans, redactions, anti-spam, server ACLs, room -directory changes, room alias transfers, account deactivation, room shutdown, and more. +directory changes and room alias transfers. -A Synapse module is also available to apply the same rulesets the bot uses across an entire -homeserver. +Support is also provided for some Synapse admin functions such as account +deactivation and room shutdown. + +A Synapse module is also available to apply the same rulesets the bot is watching +across an entire homeserver. + +### Differences from Mjolnir + +The main difference from Mjolnir is that it is no longer necessary to use +commands for some functions. Banning a user in a protected room from your +Matrix client will cause Draupnir to show a prompt in the management room, +which will offer to add the ban to a policy list. + +If you do still wish to use the ban command, please note that users +and other entities that are being banned are now the first argument +to the ban command. It is now also possible to provide only the entity to +Draupnir and have Draupnir prompt you for the policy list and the ban reason. + +In general, any command that has been migrated to the new interface will +feature better error messages for common problems and allow admins +to trace the cause of unexpected errors much more easily. ## Setting up @@ -88,7 +113,12 @@ server can only receive requests from your reverse proxy (e.g. `localhost`). ## Development -TODO. It's a TypeScript project with a linter. +Draupnir is a TypeScript project that depends on the labour of a handful of +developers, testers and users. The code base is in relatively good shape, +and if you would like to contribute or gain an understanding of the workings +of Draupnir, please read our [context document](./docs/context.md). + +Once you have done that, go ahead and read our [contributing document](./CONTRIBUTING.md) ### Development and testing with mx-tester diff --git a/config/default.yaml b/config/default.yaml index 42257323..a90b6d38 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -51,9 +51,11 @@ recordIgnoredInvites: false # (see verboseLogging to adjust this a bit.) managementRoom: "#moderators:example.org" +# Deprecated and will be removed in a future version. +# Running with verboseLogging is unsupported. # Whether Draupnir should log a lot more messages in the room, # mainly involves "all-OK" messages, and debugging messages for when draupnir checks bans in a room. -verboseLogging: true +verboseLogging: false # The log level of terminal (or container) output, # can be one of DEBUG, INFO, WARN and ERROR, in increasing order of importance and severity. @@ -73,6 +75,10 @@ verifyPermissionsOnStartup: true # turn on to trial some untrusted configuration or lists. noop: false +# Whether or not Draupnir should apply `m.room.server_acl` events. +# DO NOT change this to `true` unless you are very confident that you know what you are doing. +disableServerACL: false + # Whether Draupnir should check member lists quicker (by using a different endpoint), # keep in mind that enabling this will miss invited (but not joined) users. # diff --git a/config/harness.yaml b/config/harness.yaml index 18b992fa..9e9303d5 100644 --- a/config/harness.yaml +++ b/config/harness.yaml @@ -47,8 +47,12 @@ recordIgnoredInvites: false # Note: Mjolnir is fairly verbose - expect a lot of messages from it. managementRoom: "#moderators:localhost:9999" -# Set to false to make the management room a bit quieter. -verboseLogging: true +# Deprecated and will be removed in a future version. +# Running with verboseLogging is unsupported. +# Whether Draupnir should log a lot more messages in the room, +# mainly involves "all-OK" messages, and debugging messages for when draupnir checks bans in a room. +verboseLogging: false + # The log level for the logs themselves. One of DEBUG, INFO, WARN, and ERROR. # This should be at INFO or DEBUG in order to get support for Mjolnir problems. diff --git a/docs/context.md b/docs/context.md index 3535e7be..fcaee47e 100644 --- a/docs/context.md +++ b/docs/context.md @@ -1,9 +1,9 @@ ## Context for developing Draupnir -#### And also context that is essential if you are developing anything -that uses Policy Lists. +alternatively context that is essential for developing +anything that uses Policy Lists. -### Sync loop +### The synchronisation loop In order to understand how Draupnir works you have to first understand the sync loop of Matrix Clients. All Matrix clients have a sync loop. @@ -122,6 +122,34 @@ begin synchronising policies with with the protected rooms. Draupnir starts synchronising rooms by visiting the most recently active room first. +### A history of moderation projects + +Mjolnir was originally created by +[Travis Ralston](https://github.com/turt2live) as a good enough +solution temprarily made permanent. +The abstract architecture of Mjolnir remains today and we are +thankful for good foundations, and significantly +[policies](https://spec.matrix.org/latest/client-server-api/#moderation-policy-lists) +that were +[proposed](https://github.com/matrix-org/matrix-spec-proposals/pull/2313) +by [Matthew Hodgson](https://github.com/ara4n). + +There were several other similar solutions known to us that were +developed and deployed at the same time as Mjolnir in the earlier days +and either directly or indirectly had influence on things to come. +Notably [Fly Swatter](https://github.com/serra-allgood/matrix-fly-swatter) +and [Luna](https://gitlab.com/Gnuxie/luna). + +After a period of maintenance, Mjolnir was then developed by other +contributors from Element who restructured the project, tackled +usability concerns and would go on to produce a multi-tenancy +appservice mode of deployment called "Mjolnir for all". +With the eventual aim of integrating the functions of Mjolnir +transparently with both homeservers and clients. + +This effort is now continued by the Matrix community in the form +of Draupnir and [MTRNord](https://github.com/MTRNord)'s +[Draupnir4all deployment](https://docs.draupnir.midnightthoughts.space/). [^full-state]: matrix-bot-sdk could be modified to sync with `full_state` set to true. This has been diff --git a/package.json b/package.json index cf225044..200b9d94 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "draupnir", - "version": "1.84.0", + "version": "1.85.1", "description": "A moderation tool for Matrix", "main": "lib/index.js", "repository": "https://github.com/MTRNord/Draupnir.git", @@ -15,34 +15,34 @@ "lint": "tslint --project ./tsconfig.json -t stylish", "start:dev": "yarn build && node --async-stack-traces lib/index.js", "test": "ts-mocha --project ./tsconfig.json test/commands/**/*.ts", - "test:integration": "NODE_ENV=harness ts-mocha --async-stack-traces --require test/integration/fixtures.ts --timeout 300000 --project ./tsconfig.json \"test/integration/**/*Test.ts\"", + "test:integration": "NODE_ENV=harness ts-mocha --async-stack-traces --forbid-only --require test/integration/fixtures.ts --timeout 300000 --project ./tsconfig.json \"test/integration/**/*Test.ts\"", "test:integration:single": "NODE_ENV=harness npx ts-mocha --require test/integration/fixtures.ts --timeout 300000 --project ./tsconfig.json", - "test:appservice:integration": "NODE_ENV=harness ts-mocha --async-stack-traces --timeout 300000 --project ./tsconfig.json \"test/appservice/integration/**/*Test.ts\"", + "test:appservice:integration": "NODE_ENV=harness ts-mocha --async-stack-traces --forbid-only --timeout 300000 --project ./tsconfig.json \"test/appservice/integration/**/*Test.ts\"", "test:appservice:integration:single": "NODE_ENV=harness npx ts-mocha --timeout 300000 --project ./tsconfig.json", "test:manual": "NODE_ENV=harness ts-node test/integration/manualLaunchScript.ts", "version": "sed -i '/# version automated/s/[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][^\"]*/'$npm_package_version'/' synapse_antispam/setup.py && git add synapse_antispam/setup.py && cat synapse_antispam/setup.py" }, "devDependencies": { - "@types/config": "^3.3.0", - "@types/crypto-js": "^4.0.2", + "@types/config": "^3.3.1", + "@types/crypto-js": "^4.1.2", "@types/express": "^4.17.13", "@types/html-to-text": "^8.0.1", "@types/humanize-duration": "^3.27.1", "@types/js-yaml": "^4.0.5", "@types/jsdom": "^16.2.11", - "@types/mocha": "^9.0.0", - "@types/nedb": "^1.8.12", - "@types/node": "^18.16.7", + "@types/mocha": "^10.0.1", + "@types/nedb": "^1.8.13", + "@types/node": "^20.6.0", "@types/pg": "^8.6.5", "@types/request": "^2.48.8", "@types/shell-quote": "1.7.1", "crypto-js": "^4.1.1", - "eslint": "^7.32", - "expect": "^27.0.6", - "mocha": "^9.0.1", - "ts-mocha": "^9.0.2", + "eslint": "^8.49", + "expect": "^29.6.4", + "mocha": "^10.2.0", + "ts-mocha": "^10.0.0", "tslint": "^6.1.3", - "typescript": "^5.1.6", + "typescript": "^5.2.2", "typescript-formatter": "^7.2" }, "dependencies": { @@ -57,7 +57,7 @@ "@sentry/tracing": "^7.17.2", "await-lock": "^2.2.2", "body-parser": "^1.20.1", - "config": "^3.3.8", + "config": "^3.3.9", "express": "^4.17", "html-to-text": "^8.0.0", "humanize-duration": "^3.27.1", @@ -69,7 +69,7 @@ "pg": "^8.8.0", "shell-quote": "^1.7.3", "ulidx": "^0.3.0", - "yaml": "^2.2.2" + "yaml": "^2.3.2" }, "overrides": { "matrix-appservice-bridge": { diff --git a/src/ErrorCache.ts b/src/ErrorCache.ts deleted file mode 100644 index 4b57f71d..00000000 --- a/src/ErrorCache.ts +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (C) 2022 Gnuxie - * All rights reserved. - * - * This file is modified and is NOT licensed under the Apache License. - * This modified file incorperates work from mjolnir - * https://github.com/matrix-org/mjolnir - * which included the following license notice: - -Copyright 2019 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - * - * However, this file is modified and the modifications in this file - * are NOT distributed, contributed, committed, or licensed under the Apache License. - */ - -import { trace } from "./utils"; - -export const ERROR_KIND_PERMISSION = "permission"; -export const ERROR_KIND_FATAL = "fatal"; - -const TRIGGER_INTERVALS: { [key: string]: number } = { - [ERROR_KIND_PERMISSION]: 3 * 60 * 60 * 1000, // 3 hours - [ERROR_KIND_FATAL]: 15 * 60 * 1000, // 15 minutes -}; - -/** - * The ErrorCache is used to suppress the same error messages for the same error state. - * An example would be when mjolnir has been told to protect a room but is missing some permission such as the ability to send `m.room.server_acl`. - * Each time `Mjolnir` synchronizes policies to protected rooms Mjolnir will try to log to the management room that Mjolnir doesn't have permission to send `m.room.server_acl`. - * The ErrorCache is an attempt to make sure the error is reported only once. - */ -export default class ErrorCache { - private roomsToErrors: Map> = new Map(); - - constructor() { - } - - /** - * Reset the error cache for a room/kind in the situation where circumstances have changed e.g. if Mjolnir has been informed via sync of a `m.room.power_levels` event in the room, we would want to clear `ERROR_KIND_PERMISSION` - * so that a user can see if their changes worked. - * @param roomId The room to reset the error cache for. - * @param kind The kind of error we are resetting. - */ - @trace - public resetError(roomId: string, kind: string) { - if (!this.roomsToErrors.has(roomId)) { - this.roomsToErrors.set(roomId, new Map()); - } - this.roomsToErrors.get(roomId)?.set(kind, 0); - } - - /** - * Register the error with the cache. - * @param roomId The room where the error is occuring or related to. - * @param kind What kind of error, either `ERROR_KIND_PERMISSION` or `ERROR_KIND_FATAL`. - * @returns True if the error kind has been triggered in that room, - * meaning it has been longer than the time specified in `TRIGGER_INTERVALS` since the last trigger (or the first trigger). Otherwise false. - */ - @trace - public triggerError(roomId: string, kind: string): boolean { - if (!this.roomsToErrors.get(roomId)) { - this.roomsToErrors.set(roomId, new Map()); - } - - const triggers = this.roomsToErrors.get(roomId)!; - if (!triggers.has(kind)) { - triggers?.set(kind, 0); - } - - const lastTriggerTime = triggers.get(kind)!; - const now = new Date().getTime(); - const interval = TRIGGER_INTERVALS[kind]; - - if ((now - lastTriggerTime) >= interval) { - triggers.set(kind, now); - return true; - } else { - return false; - } - } -} diff --git a/src/Mjolnir.ts b/src/Mjolnir.ts index ef8f0c19..687a6e41 100644 --- a/src/Mjolnir.ts +++ b/src/Mjolnir.ts @@ -339,6 +339,9 @@ export class Mjolnir { this.currentState = STATE_RUNNING; await this.managementRoomOutput.logMessage(LogLevel.INFO, "Mjolnir@startup", "Startup complete. Now monitoring rooms."); + if (this.config.verboseLogging) { + await this.managementRoomOutput.logMessage(LogLevel.WARN, "Mjolnir@startup", "The use of verbose logging is deprecated and will be removed in a future version, check your config."); + } } catch (err) { try { LogService.error("Mjolnir", "Error during startup:", err); diff --git a/src/ProtectedRoomsSet.ts b/src/ProtectedRoomsSet.ts index 6ed55609..4279d7ff 100644 --- a/src/ProtectedRoomsSet.ts +++ b/src/ProtectedRoomsSet.ts @@ -25,16 +25,15 @@ limitations under the License. * are NOT distributed, contributed, committed, or licensed under the Apache License. */ -import { LogLevel, LogService, MatrixGlob, UserID } from "matrix-bot-sdk"; -import { Permalinks } from "./commands/interface-manager/Permalinks"; +import { LogLevel, MatrixGlob, UserID } from "matrix-bot-sdk"; +import { CommandExceptionKind } from "./commands/interface-manager/CommandException"; import { IConfig } from "./config"; -import ErrorCache, { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION } from "./ErrorCache"; import ManagementRoomOutput from "./ManagementRoomOutput"; import { MatrixSendClient } from "./MatrixEmitter"; import AccessControlUnit, { Access } from "./models/AccessControlUnit"; import { RULE_ROOM, RULE_SERVER, RULE_USER } from "./models/ListRule"; import PolicyList, { ListRuleChange, Revision } from "./models/PolicyList"; -import { RoomUpdateError } from "./models/RoomUpdateError"; +import { printActionResult, IRoomUpdateError, RoomUpdateException } from "./models/RoomUpdateError"; import { ProtectionManager } from "./protections/ProtectionManager"; import { EventRedactionQueue, RedactUserInRoom } from "./queues/EventRedactionQueue"; import { ProtectedRoomActivityTracker } from "./queues/ProtectedRoomActivityTracker"; @@ -75,8 +74,6 @@ export class ProtectedRoomsSet { */ private readonly eventRedactionQueue = new EventRedactionQueue(); - private readonly errorCache = new ErrorCache(); - /** * These are globs sourced from `config.automaticallyRedactForReasons` that are matched against the reason of an * `m.ban` recommendation against a user. @@ -191,7 +188,7 @@ export class ProtectedRoomsSet { * @returns The list of errors encountered, for reporting to the management room. */ @trace - public async processRedactionQueue(roomId?: string): Promise { + public async processRedactionQueue(roomId?: string): Promise { return await this.eventRedactionQueue.process(this.client, this.managementRoomOutput, roomId); } @@ -213,24 +210,22 @@ export class ProtectedRoomsSet { } this.protectedRoomActivityTracker.handleEvent(roomId, event); if (event['type'] === 'm.room.power_levels' && event['state_key'] === '') { - // power levels were updated - recheck permissions - this.errorCache.resetError(roomId, ERROR_KIND_PERMISSION); await this.managementRoomOutput.logMessage(LogLevel.DEBUG, "Mjolnir", `Power levels changed in ${roomId} - checking permissions...`, roomId); const errors = await this.protectionManager.verifyPermissionsIn(roomId); - const hadErrors = await this.printActionResult(errors); - if (!hadErrors) { - await this.managementRoomOutput.logMessage(LogLevel.DEBUG, "Mjolnir", `All permissions look OK.`); - } + await this.printActionResult(errors, { title: "There were errors verifying permissions.", noErrorsText: "All permissions look OK." }); return; } else if (event['type'] === "m.room.member") { // The reason we have to apply bans on each member change is because // we cannot eagerly ban users (that is to ban them when they have never been a member) // as they can be force joined to a room they might not have known existed. // Only apply bans and then redactions in the room we are currently looking at. - const banErrors = await this.applyUserBans([roomId]); - const redactionErrors = await this.processRedactionQueue(roomId); - await this.printActionResult(banErrors); - await this.printActionResult(redactionErrors); + const errors = [ + await this.applyUserBans([roomId]), + await this.processRedactionQueue(roomId), + ].flat(); + if (errors.length > 0) { + await this.printActionResult(errors, { title: 'There were errors updating member bans.' }); + } } } @@ -239,26 +234,12 @@ export class ProtectedRoomsSet { */ @trace private async syncRoomsWithPolicies() { - let hadErrors = false; - const [aclErrors, banErrors] = await Promise.all([ + const errors = (await Promise.all([ this.applyServerAcls(this.policyLists, this.protectedRoomsByActivity()), - this.applyUserBans(this.protectedRoomsByActivity()) - ]); - const redactionErrors = await this.processRedactionQueue(); - hadErrors = hadErrors || await this.printActionResult(aclErrors, "Errors updating server ACLs:"); - hadErrors = hadErrors || await this.printActionResult(banErrors, "Errors updating member bans:"); - hadErrors = hadErrors || await this.printActionResult(redactionErrors, "Error updating redactions:"); - - if (!hadErrors) { - const html = `Done updating rooms - no errors`; - const text = "Done updating rooms - no errors"; - await this.client.sendMessage(this.managementRoomId, { - msgtype: "m.notice", - body: text, - format: "org.matrix.custom.html", - formatted_body: html, - }); - } + this.applyUserBans(this.protectedRoomsByActivity()), + this.processRedactionQueue() + ])).flat(); + await this.printActionResult(errors, { title: "There were errors synchronising the protected rooms." }); } /** @@ -324,9 +305,12 @@ export class ProtectedRoomsSet { * @param {Mjolnir} mjolnir The Mjolnir client to apply the ACLs with. */ @trace - private async applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { + private async applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { // we need to provide mutual exclusion so that we do not have requests updating the m.room.server_acl event // finish out of order and therefore leave the room out of sync with the policy lists. + if (this.config.disableServerACL) { + return []; + } return new Promise((resolve, reject) => { this.aclChain = this.aclChain .then(() => this._applyServerAcls(lists, roomIds)) @@ -334,7 +318,7 @@ export class ProtectedRoomsSet { }); } - private async _applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { + private async _applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { const serverName: string = new UserID(await this.client.getUserId()).domain; // Construct a server ACL first @@ -346,7 +330,7 @@ export class ProtectedRoomsSet { await this.client.sendNotice(this.managementRoomId, `Constructed server ACL:\n${JSON.stringify(finalAcl, null, 2)}`); } - const errors: RoomUpdateError[] = []; + const errors: IRoomUpdateError[] = []; for (const roomId of roomIds) { try { await this.managementRoomOutput.logMessage(LogLevel.DEBUG, "ApplyAcl", `Checking ACLs for ${roomId}`, roomId); @@ -371,8 +355,8 @@ export class ProtectedRoomsSet { } } catch (e) { const message = e.message || (e.body ? e.body.error : ''); - const kind = message && message.includes("You don't have permission to post that to the room") ? ERROR_KIND_PERMISSION : ERROR_KIND_FATAL; - errors.push({ roomId, errorMessage: message, errorKind: kind }); + const kind = message && message.includes("You don't have permission to post that to the room") ? CommandExceptionKind.Known : CommandExceptionKind.Unknown; + errors.push(new RoomUpdateException(roomId, kind, e, message)) } } return errors; @@ -385,17 +369,18 @@ export class ProtectedRoomsSet { * @param {Mjolnir} mjolnir The Mjolnir client to apply the bans with. */ @trace - private async applyUserBans(roomIds: string[]): Promise { + private async applyUserBans(roomIds: string[]): Promise { // We can only ban people who are not already banned, and who match the rules. - const errors: RoomUpdateError[] = []; + const errors: IRoomUpdateError[] = []; const addErrorToReport = (roomId: string, e: any) => { const message = e.message || (e.body ? e.body.error : ''); - errors.push({ + errors.push(new RoomUpdateException( roomId, - errorMessage: message, - errorKind: message && message.includes("You don't have permission to ban") ? ERROR_KIND_PERMISSION : ERROR_KIND_FATAL, - }); + message && message.includes("You don't have permission to ban") ? CommandExceptionKind.Known : CommandExceptionKind.Unknown, + e, + message + )); }; for (const roomId of roomIds) { @@ -493,42 +478,29 @@ export class ProtectedRoomsSet { return true; } - private async printActionResult(errors: RoomUpdateError[], title: string | null = null, logAnyways = false) { - if (errors.length <= 0) return false; + private async printActionResult( + errors: IRoomUpdateError[], + renderOptions: { title?: string, noErrorsText?: string } + ): Promise { + await printActionResult(this.client, this.managementRoomId, errors, renderOptions); + } - if (!logAnyways) { - errors = errors.filter(e => this.errorCache.triggerError(e.roomId, e.errorKind)); - if (errors.length <= 0) { - LogService.warn("Mjolnir", "Multiple errors are happening, however they are muted. Please check the management room."); - return true; + public async unbanUser(user: string): Promise { + const errors: IRoomUpdateError[] = []; + for (const room of this.protectedRoomActivityTracker.protectedRoomsByActivity()) { + try { + await this.client.unbanUser(user, room); + } catch (e) { + const message = e.message || (e.body ? e.body.error : ''); + errors.push(new RoomUpdateException( + room, + message && message.includes("You don't have permission to ban") ? CommandExceptionKind.Known : CommandExceptionKind.Unknown, + e, + message + )); } } - - let html = ""; - let text = ""; - - const htmlTitle = title ? `${title}
` : ''; - const textTitle = title ? `${title}\n` : ''; - - html += `${htmlTitle}${errors.length} errors updating protected rooms!
    `; - text += `${textTitle}${errors.length} errors updating protected rooms!\n`; - const viaServers = [(new UserID(await this.client.getUserId())).domain]; - for (const error of errors) { - const alias = (await this.client.getPublishedAlias(error.roomId)) || error.roomId; - const url = Permalinks.forRoom(alias, viaServers); - html += `
  • ${alias} - ${error.errorMessage}
  • `; - text += `${url} - ${error.errorMessage}\n`; - } - html += "
"; - - const message = { - msgtype: "m.notice", - body: text, - format: "org.matrix.custom.html", - formatted_body: html, - }; - await this.client.sendMessage(this.managementRoomId, message); - return true; + return errors; } public requiredProtectionPermissions() { @@ -536,22 +508,14 @@ export class ProtectedRoomsSet { } @trace - public async verifyPermissions(verbose = true, printRegardless = false) { - const errors: RoomUpdateError[] = []; + public async verifyPermissions() { + const errors: IRoomUpdateError[] = []; for (const roomId of this.protectedRooms) { errors.push(...(await this.protectionManager.verifyPermissionsIn(roomId))); } - - const hadErrors = await this.printActionResult(errors, "Permission errors in protected rooms:", printRegardless); - if (!hadErrors && verbose) { - const html = `All permissions look OK.`; - const text = "All permissions look OK."; - await this.client.sendMessage(this.managementRoomId, { - msgtype: "m.notice", - body: text, - format: "org.matrix.custom.html", - formatted_body: html, - }); - } + await this.printActionResult(errors, { + title: "There are permission errors in protected rooms.", + noErrorsText: "All permissions look OK." + }); } } diff --git a/src/commands/CommandHandler.ts b/src/commands/CommandHandler.ts index df39c90c..f2212db3 100644 --- a/src/commands/CommandHandler.ts +++ b/src/commands/CommandHandler.ts @@ -48,7 +48,7 @@ import { BaseFunction, CommandTable, defineCommandTable, findCommandTable, findT import { findMatrixInterfaceAdaptor, MatrixContext } from "./interface-manager/MatrixInterfaceAdaptor"; import { ArgumentStream } from "./interface-manager/ParameterParsing"; import { CommandResult } from "./interface-manager/Validation"; -import { CommandException } from "./interface-manager/CommandException"; +import { CommandException, CommandExceptionKind } from "./interface-manager/CommandException"; import { tickCrossRenderer } from "./interface-manager/MatrixHelpRenderer"; import "./interface-manager/MatrixPresentations"; @@ -133,7 +133,7 @@ export async function handleCommand(roomId: string, event: { content: { body: st try { return await adaptor.invoke(mjolnirContext, mjolnirContext, ...stream.rest()); } catch (e) { - const commandError = new CommandException(e, 'Unknown Unexpected Error'); + const commandError = new CommandException(CommandExceptionKind.Unknown, e, 'Unknown Unexpected Error'); await tickCrossRenderer.call(mjolnirContext, mjolnir.client, roomId, event, CommandResult.Err(commandError)); } } diff --git a/src/commands/PermissionCheckCommand.ts b/src/commands/PermissionCheckCommand.ts index ad384a7a..765c2d85 100644 --- a/src/commands/PermissionCheckCommand.ts +++ b/src/commands/PermissionCheckCommand.ts @@ -29,5 +29,5 @@ import { Mjolnir } from "../Mjolnir"; // !mjolnir verify export async function execPermissionCheckCommand(roomId: string, event: any, mjolnir: Mjolnir) { - return mjolnir.protectedRoomsTracker.verifyPermissions(true, true); + return mjolnir.protectedRoomsTracker.verifyPermissions(); } diff --git a/src/commands/Rooms.tsx b/src/commands/Rooms.tsx index d5cd70a2..eaf80613 100644 --- a/src/commands/Rooms.tsx +++ b/src/commands/Rooms.tsx @@ -30,7 +30,7 @@ import { findPresentationType, parameters } from "./interface-manager/ParameterP import { MjolnirContext } from "./CommandHandler"; import { MatrixRoomID, MatrixRoomReference } from "./interface-manager/MatrixRoomReference"; import { CommandResult } from "./interface-manager/Validation"; -import { CommandException } from "./interface-manager/CommandException"; +import { CommandException, CommandExceptionKind } from "./interface-manager/CommandException"; import { defineMatrixInterfaceAdaptor } from "./interface-manager/MatrixInterfaceAdaptor"; import { tickCrossRenderer } from "./interface-manager/MatrixHelpRenderer"; import { DocumentNode } from "./interface-manager/DeadDocument"; @@ -92,7 +92,7 @@ defineInterfaceCommand({ return CommandException.Result( `The homeserver that Draupnir is hosted on cannot join this room using the room reference provided.\ Try an alias or the "share room" button in your client to obtain a valid reference to the room.`, - { exception: e } + { exception: e, exceptionKind: CommandExceptionKind.Unknown } ); } })(); @@ -121,7 +121,10 @@ defineInterfaceCommand({ try { await this.mjolnir.client.leaveRoom(roomID.toRoomIdOrAlias()); } catch (exception) { - return CommandException.Result(`Failed to leave ${roomRef.toPermalink()} - the room is no longer being protected, but the bot could not leave.`, { exception }); + return CommandException.Result( + `Failed to leave ${roomRef.toPermalink()} - the room is no longer being protected, but the bot could not leave.`, + { exceptionKind: CommandExceptionKind.Unknown, exception } + ); } return CommandResult.Ok(undefined); }, diff --git a/src/commands/Rules.tsx b/src/commands/Rules.tsx index c5e605a8..5116d7fe 100644 --- a/src/commands/Rules.tsx +++ b/src/commands/Rules.tsx @@ -60,7 +60,7 @@ async function renderListMatches( ) } -function renderListRules(list: ListMatches) { +export function renderListRules(list: ListMatches) { const renderRuleSummary = (rule: ListRule, entityDescription: string) => { return
  • {entityDescription} ({rule.recommendation}): {rule.entity} ({rule.reason}) diff --git a/src/commands/interface-manager/CommandException.ts b/src/commands/interface-manager/CommandException.ts index 762b1f7f..13d85e9b 100644 --- a/src/commands/interface-manager/CommandException.ts +++ b/src/commands/interface-manager/CommandException.ts @@ -6,6 +6,22 @@ import { randomUUID } from "crypto"; import * as api from '@opentelemetry/api'; import { CommandError, CommandResult } from "./Validation"; import { trace } from "../../utils"; +import { LogService } from "matrix-bot-sdk"; + +export enum CommandExceptionKind { + /** + * This class is for exceptions that need to be reported to the user, + * but are mostly irrelevant to the developers because the behaviour is well + * understood and expected. These exceptions will never be logged to the error + * level. + */ + Known = 'Known', + /** + * This class is to be used for reporting unexpected or unknown exceptions + * that the developers need to know about. + */ + Unknown = 'Unknown', +} // FIXME: I wonder if we could allow message to be JSX? // Then room references could be put into the DM and actually mean something. @@ -13,13 +29,25 @@ export class CommandException extends CommandError { public readonly uuid: string = api.trace.getSpan(api.context.active())?.spanContext().traceId ?? randomUUID(); constructor( + public readonly exceptionKind: CommandExceptionKind, public readonly exception: Error | unknown, message: string) { super(message) + this.log(); } @trace - public static Result(message: string, options: { exception: Error }): CommandResult { - return CommandResult.Err(new CommandException(options.exception, message)); + public static Result(message: string, options: { exception: Error, exceptionKind: CommandExceptionKind }): CommandResult { + return CommandResult.Err(new CommandException(options.exceptionKind, options.exception, message)); + } + + @trace + protected log(): void { + const logArguments: Parameters = ["CommandException", this.exceptionKind, this.uuid, this.message, this.exception]; + if (this.exceptionKind === CommandExceptionKind.Known) { + LogService.info(...logArguments); + } else { + LogService.error(...logArguments); + } } } diff --git a/src/commands/interface-manager/DeadDocument.ts b/src/commands/interface-manager/DeadDocument.ts index e390fcbc..1c01a38b 100644 --- a/src/commands/interface-manager/DeadDocument.ts +++ b/src/commands/interface-manager/DeadDocument.ts @@ -67,6 +67,7 @@ export enum NodeTag { Fragment = 'fragment', Details = 'details', Summary = 'summary', + Font = 'font', } /** diff --git a/src/commands/interface-manager/DeadDocumentHtml.ts b/src/commands/interface-manager/DeadDocumentHtml.ts index 5166b4aa..1b2e202a 100644 --- a/src/commands/interface-manager/DeadDocumentHtml.ts +++ b/src/commands/interface-manager/DeadDocumentHtml.ts @@ -4,9 +4,26 @@ */ import { htmlEscape } from "../../utils"; -import { FringeLeafRenderFunction, FringeType, LeafNode, NodeTag, SimpleFringeRenderer } from "./DeadDocument"; +import { DocumentNode, FringeLeafRenderFunction, FringeType, LeafNode, NodeTag, SimpleFringeRenderer, TagDynamicEnvironment } from "./DeadDocument"; import { blank, staticString, TransactionalOutputContext } from "./DeadDocumentMarkdown"; +function writeAttributableNode(tagName: string, _fringe: FringeType, node: DocumentNode, context: TransactionalOutputContext, _environment: TagDynamicEnvironment) { + context.output.writeString(`<${tagName}`); + if (node.attributeMap.size > 0) { + for (const [key, value] of node.attributeMap.entries()) { + context.output.writeString(` ${htmlEscape(key)}="${htmlEscape(value)}"`); + } + } + context.output.writeString('>') +} + +function attributableNode(tagName: string) { + return function(fringe: FringeType, node: DocumentNode, context: TransactionalOutputContext, environment: TagDynamicEnvironment) { + writeAttributableNode(tagName, fringe, node, context, environment); + } +} + + export const HTML_RENDERER = new SimpleFringeRenderer(); HTML_RENDERER.registerRenderer>( @@ -52,16 +69,11 @@ HTML_RENDERER.registerRenderer'), staticString('') ).registerInnerNode(NodeTag.Anchor, - function(_fringe, node, context, _environment) { - context.output.writeString(' 0) { - for (const [key, value] of node.attributeMap.entries()) { - context.output.writeString(` ${htmlEscape(key)}="${htmlEscape(value)}"`); - } - } - context.output.writeString('>') - }, + attributableNode('a'), staticString('') +).registerInnerNode(NodeTag.Font, + attributableNode('font'), + staticString('') ).registerInnerNode(NodeTag.Root, blank, blank diff --git a/src/commands/interface-manager/DeadDocumentMarkdown.ts b/src/commands/interface-manager/DeadDocumentMarkdown.ts index 0694c0dd..19651dba 100644 --- a/src/commands/interface-manager/DeadDocumentMarkdown.ts +++ b/src/commands/interface-manager/DeadDocumentMarkdown.ts @@ -142,4 +142,7 @@ MARKDOWN_RENDERER.registerRenderer'), staticString('') +).registerInnerNode(NodeTag.Font, + blank, + blank ); diff --git a/src/commands/interface-manager/DeadDocumentMatrix.ts b/src/commands/interface-manager/DeadDocumentMatrix.ts index b9980232..81f1489f 100644 --- a/src/commands/interface-manager/DeadDocumentMatrix.ts +++ b/src/commands/interface-manager/DeadDocumentMatrix.ts @@ -31,6 +31,7 @@ export async function renderMatrix(node: DocumentNode, cb: SendMatrixEventCB): P context.output.commit(commitNode); }; if (node.tag !== NodeTag.Root) { + // rendering has to start (and end) with a committable node. throw new TypeError("Tried to render a node without a root, this will not be committable"); } const markdownOutput = new PagedDuplexStream(); diff --git a/src/commands/interface-manager/Validation.ts b/src/commands/interface-manager/Validation.ts index bde0e6c0..aef34f93 100644 --- a/src/commands/interface-manager/Validation.ts +++ b/src/commands/interface-manager/Validation.ts @@ -95,7 +95,7 @@ export class CommandError { public constructor( public readonly message: string, ) { - + // nothing to do. } /** diff --git a/src/config.ts b/src/config.ts index 01be3e3d..31e27b6d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -63,6 +63,7 @@ export interface IConfig { logMutedModules: string[], syncOnStartup: boolean; verifyPermissionsOnStartup: boolean; + disableServerACL: boolean; noop: boolean; protectedRooms: string[]; // matrix.to urls fasterMembershipChecks: boolean; @@ -158,6 +159,7 @@ const defaultConfig: IConfig = { syncOnStartup: true, verifyPermissionsOnStartup: true, noop: false, + disableServerACL: false, protectedRooms: [], fasterMembershipChecks: false, automaticallyRedactForReasons: ["spam", "advertising"], diff --git a/src/models/RoomUpdateError.ts b/src/models/RoomUpdateError.ts deleted file mode 100644 index f3ab3588..00000000 --- a/src/models/RoomUpdateError.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2022 Gnuxie - * All rights reserved. - * - * This file is modified and is NOT licensed under the Apache License. - * This modified file incorperates work from mjolnir - * https://github.com/matrix-org/mjolnir - * which included the following license notice: - -Copyright 2019 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - * - * However, this file is modified and the modifications in this file - * are NOT distributed, contributed, committed, or licensed under the Apache License. - */ - -export interface RoomUpdateError { - roomId: string; - errorMessage: string; - errorKind: string; -} diff --git a/src/models/RoomUpdateError.tsx b/src/models/RoomUpdateError.tsx new file mode 100644 index 00000000..e760d281 --- /dev/null +++ b/src/models/RoomUpdateError.tsx @@ -0,0 +1,131 @@ +/** + * Copyright (C) 2022 Gnuxie + * All rights reserved. + * + * This file is modified and is NOT licensed under the Apache License. + * This modified file incorperates work from mjolnir + * https://github.com/matrix-org/mjolnir + * which included the following license notice: + +Copyright 2019 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + * + * However, this file is modified and the modifications in this file + * are NOT distributed, contributed, committed, or licensed under the Apache License. + */ + +import { UserID } from "matrix-bot-sdk"; +import { CommandException, CommandExceptionKind } from "../commands/interface-manager/CommandException"; +import { DocumentNode } from "../commands/interface-manager/DeadDocument"; +import { renderMatrixAndSend } from "../commands/interface-manager/DeadDocumentMatrix"; +import { JSXFactory } from "../commands/interface-manager/JSXFactory"; +import { Permalinks } from "../commands/interface-manager/Permalinks"; +import { CommandError, CommandResult } from "../commands/interface-manager/Validation"; +import { MatrixSendClient } from "../MatrixEmitter"; + +export interface IRoomUpdateError extends CommandError { + readonly roomId: string, +} + +export class PermissionError extends CommandError implements IRoomUpdateError { + constructor( + public readonly roomId: string, + message: string + ) { + super(message); + } +} + +export class RoomUpdateException extends CommandException implements IRoomUpdateError { + constructor(public readonly roomId: string, ...args: ConstructorParameters) { + super(...args); + } + + public static Result( + message: string, + options: { + exception: Error, + exceptionKind: CommandExceptionKind, + roomId: string + }): CommandResult { + return CommandResult.Err(new RoomUpdateException(options.roomId, options.exceptionKind, options.exception, message)); + } +} + +function renderErrorItem(error: IRoomUpdateError, viaServers: string[]): DocumentNode { + return
  • + {error.roomId} - {error.message} +
  • +} + +/** + * Render a message to show to the user after taking an action in a room or a set of rooms. + * @param client A matrix client. + * @param errors Any errors associated with the action. + * @param options.title To give context about what the action was, shown when there are errors. + * @param options.noErrorsText To show when there are no errors. + * @param options.skipNoErrors is ineffective and does nothing, it is an option for the accompnying `printActionResult`. + * @returns A `DocumentNode` fragment that can be sent to Matrix or incorperated into another message. + */ +export async function renderActionResult( + client: MatrixSendClient, + errors: IRoomUpdateError[], + { title = 'There were errors updating protected rooms.', noErrorsText = 'Done updating rooms - no errors.'}: { title?: string, noErrorsText?: string } = {} +): Promise { + if (errors.length === 0) { + return {noErrorsText} + } + // This is a little unfortunate because for some reason we don't have a way to keep + // room references around that have vias and are meaningful + // there isn't really any easy way to do this :( + const viaServers = [(new UserID(await client.getUserId())).domain]; + return + + {title}
    +
    +
    + + + {errors.length} errors updating protected rooms!
    +
    +
    +
      + {errors.map(error => renderErrorItem(error, viaServers))} +
    +
    +
    +} + +/** + * Render a message to represent the outcome of an action in an update. + * @param client A matrix client to send a notice with. + * @param roomId The room to send the notice to. + * @param errors Any errors that are a result of the action. + * @param options.title To give context about what the action was, shown when there are errors. + * @param options.noErrorsText To show when there are no errors. + * @returns + */ +export async function printActionResult( + client: MatrixSendClient, + roomId: string, + errors: IRoomUpdateError[], + renderOptions: { title?: string, noErrorsText?: string } = {} +): Promise { + await renderMatrixAndSend( + {await renderActionResult(client, errors, renderOptions)}, + roomId, + undefined, + client, + ) +} diff --git a/src/protections/BanPropagation.tsx b/src/protections/BanPropagation.tsx index 6de482e5..dbadbc26 100644 --- a/src/protections/BanPropagation.tsx +++ b/src/protections/BanPropagation.tsx @@ -23,6 +23,9 @@ limitations under the License. * * However, this file is modified and the modifications in this file * are NOT distributed, contributed, committed, or licensed under the Apache License. + * + * In addition to the above, I want to add that this protection was inspired by + * a Mjolnir PR that was originally created by Gergő Fándly https://github.com/matrix-org/mjolnir/pull/223 */ import { Protection } from "./Protection"; @@ -31,18 +34,21 @@ import { LogService } from "matrix-bot-sdk"; import { JSXFactory } from "../commands/interface-manager/JSXFactory"; import { renderMatrixAndSend } from "../commands/interface-manager/DeadDocumentMatrix"; import { renderMentionPill } from "../commands/interface-manager/MatrixHelpRenderer"; -import { RULE_USER } from "../models/ListRule"; +import { RULE_USER, ListRule } from "../models/ListRule"; import { UserID } from "matrix-bot-sdk"; -import { ReactionListener } from "../commands/interface-manager/MatrixReactionHandler"; -import { PolicyListManager } from "../models/PolicyListManager"; import { MatrixRoomReference } from "../commands/interface-manager/MatrixRoomReference"; import { findPolicyListFromRoomReference } from "../commands/Ban"; import { trace } from '../utils'; +import PolicyList from "../models/PolicyList"; +import { renderListRules } from "../commands/Rules"; +import { printActionResult, IRoomUpdateError, RoomUpdateException } from "../models/RoomUpdateError"; +import { CommandExceptionKind } from "../commands/interface-manager/CommandException"; -const PROPAGATION_PROMPT_LISTENER = 'ge.applied-langua.ge.draupnir.ban_propagation'; +const BAN_PROPAGATION_PROMPT_LISTENER = 'ge.applied-langua.ge.draupnir.ban_propagation'; +const UNBAN_PROPAGATION_PROMPT_LISTENER = 'ge.applied-langua.ge.draupnir.unban_propagation'; -function makePolicyListShortcodeReferenceMap(lists: PolicyListManager): Map { - return lists.lists.reduce((map, list, index) => (map.set(`${index + 1}.`, list.roomRef), map), new Map()) +function makePolicyListShortcodeReferenceMap(lists: PolicyList[]): Map { + return lists.reduce((map, list, index) => (map.set(`${index + 1}.`, list.roomRef), map), new Map()) } // would be nice to be able to use presentation types here idk. @@ -63,7 +69,7 @@ async function promptBanPropagation( event: any, roomId: string ): Promise { - const reactionMap = makePolicyListShortcodeReferenceMap(mjolnir.policyListManager); + const reactionMap = makePolicyListShortcodeReferenceMap(mjolnir.policyListManager.lists); const promptEventId = (await renderMatrixAndSend( The user {renderMentionPill(event["state_key"], event["content"]?.["displayname"] ?? event["state_key"])} was banned in {roomId} by {new UserID(event["sender"])} for {event["content"]?.["reason"] ?? ''}.
    @@ -76,7 +82,7 @@ async function promptBanPropagation( undefined, mjolnir.client, mjolnir.reactionHandler.createAnnotation( - PROPAGATION_PROMPT_LISTENER, + BAN_PROPAGATION_PROMPT_LISTENER, reactionMap, { target: event["state_key"], @@ -88,6 +94,119 @@ async function promptBanPropagation( return promptEventId; } +async function promptUnbanPropagation( + mjolnir: Mjolnir, + event: any, + roomId: string, + rulesMatchingUser: Map +): Promise { + const reactionMap = new Map(Object.entries({ 'unban from all': 'unban from all'})); + // shouldn't we warn them that the unban will be futile? + const promptEventId = (await renderMatrixAndSend( + + The user {renderMentionPill(event["state_key"], event["content"]?.["displayname"] ?? event["state_key"])} was unbanned + from the room {roomId} by {new UserID(event["sender"])} for {event["content"]?.["reason"] ?? ''}.
    + However there are rules in Draupnir's watched lists matching this user: +
      + { + [...rulesMatchingUser.entries()] + .map(([list, rules]) =>
    • {renderListRules({ + shortcode: list.listShortcode, + roomRef: list.roomRef, + roomId: list.roomId, + matches: rules + })}
    • ) + } +
    + Would you like to remove these rules and unban the user from all protected rooms? +
    , + mjolnir.managementRoomId, + undefined, + mjolnir.client, + mjolnir.reactionHandler.createAnnotation( + UNBAN_PROPAGATION_PROMPT_LISTENER, + reactionMap, + { + target: event["state_key"], + reason: event["content"]?.["reason"], + } + ) + )).at(0) as string; + await mjolnir.reactionHandler.addReactionsToEvent(mjolnir.client, mjolnir.managementRoomId, promptEventId, reactionMap); + return promptEventId; +} + +interface ListenerContext { + mjolnir: Mjolnir, +} + +async function banReactionListener(this: ListenerContext, key: string, item: unknown, context: BanPropagationMessageContext) { + try { + if (typeof item === 'string') { + const listRef = MatrixRoomReference.fromPermalink(item); + const listResult = await findPolicyListFromRoomReference(this.mjolnir, listRef); + if (listResult.isOk()) { + return await listResult.ok.banEntity(RULE_USER, context.target, context.reason); + } else { + LogService.warn("BanPropagation", "Timed out waiting for a response to a room level ban", listResult.err); + return; + } + } else { + throw new TypeError("The ban prompt event's reaction map is malformed.") + } + } catch (e) { + LogService.error('BanPropagation', "Encountered an error while prompting the user for instructions to propagate a room level ban", e); + } +} + +async function unbanFromAllLists(mjolnir: Mjolnir, user: string): Promise { + const errors: IRoomUpdateError[] = []; + for (const list of mjolnir.policyListManager.lists) { + try { + await list.unbanEntity(RULE_USER, user); + } catch (e) { + LogService.info('BanPropagation', `Could not unban ${user} from ${list.roomRef}`, e); + const message = e.message || (e.body ? e.body.error : ''); + errors.push(new RoomUpdateException( + list.roomId, + message.includes("You don't have permission") ? CommandExceptionKind.Known : CommandExceptionKind.Unknown, + e, + message + )); + } + } + return errors; +} + +async function unbanUserReactionListener(this: ListenerContext, _key: string, item: unknown, context: BanPropagationMessageContext): Promise { + try { + if (item === 'unban from all') { + const listErrors = await unbanFromAllLists(this.mjolnir, context.target); + if (listErrors.length > 0) { + await printActionResult( + this.mjolnir.client, + this.mjolnir.managementRoomId, + listErrors, + { title: `There were errors unbanning ${context.target} from all lists.`} + ); + } else { + const unbanErrors = await this.mjolnir.protectedRoomsTracker.unbanUser(context.target); + await printActionResult( + this.mjolnir.client, + this.mjolnir.managementRoomId, + unbanErrors, + { + title: `There were errors unbanning ${context.target} from protected rooms.`, + noErrorsText: `Done unbanning ${context.target} from protected rooms - no errors.` + } + ); + } + } + } catch (e) { + LogService.error(`BanPropagationProtection`, "Unexpected error unbanning a user", e); + } +} + export class BanPropagation extends Protection { settings = {}; @@ -103,40 +222,36 @@ export class BanPropagation extends Protection { @trace public async registerProtection(mjolnir: Mjolnir): Promise { - const listener: ReactionListener = async (key, item, context: BanPropagationMessageContext) => { - try { - if (typeof item === 'string') { - const listRef = MatrixRoomReference.fromPermalink(item); - const listResult = await findPolicyListFromRoomReference(mjolnir, listRef); - if (listResult.isOk()) { - return listResult.ok.banEntity(RULE_USER, context.target, context.reason); - } else { - LogService.warn("BanPropagation", "Timed out waiting for a response to a room level ban", listResult.err); - return; - } - } else { - throw new TypeError("The ban prompt event's reaction map is malformed.") - } - } catch (e) { - LogService.error('BanPropagation', "Encountered an error while prompting the user for instructions to propagate a room level ban", e); - } - }; - mjolnir.reactionHandler.on(PROPAGATION_PROMPT_LISTENER, listener); + mjolnir.reactionHandler.on(BAN_PROPAGATION_PROMPT_LISTENER, banReactionListener.bind({ mjolnir })); + mjolnir.reactionHandler.on(UNBAN_PROPAGATION_PROMPT_LISTENER, unbanUserReactionListener.bind({ mjolnir })); } @trace public async handleEvent(mjolnir: Mjolnir, roomId: string, event: any): Promise { - if (event['type'] !== 'm.room.member' || event['content']?.['membership'] !== 'ban') { + if (event['type'] !== 'm.room.member' + || !(event['content']?.['membership'] === 'ban' || event['content']?.['membership'] === 'leave')) { return; } - if (mjolnir.policyListManager.lists.map( - list => list.rulesMatchingEntity(event['state_key'], RULE_USER) - ).some(rules => rules.length > 0) - ) { - return; // The user is already banned. + const rulesMatchingUser = mjolnir.policyListManager.lists.reduce( + (listMap, list) => { + const rules = list.rulesMatchingEntity(event['state_key'], RULE_USER); + if (rules.length > 0) { + listMap.set(list, rules) + }; + return listMap + }, new Map() + ); + const userMembership = event['content']?.['membership']; + if (userMembership === 'ban') { + if (rulesMatchingUser.size > 0) { + return; // The user is already banned. + } + // do not await, we don't want to block the protection manager + promptBanPropagation(mjolnir, event, roomId) + } else if (userMembership === 'leave' && rulesMatchingUser.size > 0) { + // Then this is a banned user being unbanned. + // do not await, we don't want to block the protection manager + promptUnbanPropagation(mjolnir, event, roomId, rulesMatchingUser); } - // do not await, we don't want to block the protection manager - promptBanPropagation(mjolnir, event, roomId) - } } diff --git a/src/protections/ProtectionManager.ts b/src/protections/ProtectionManager.ts index e669142c..244805ff 100644 --- a/src/protections/ProtectionManager.ts +++ b/src/protections/ProtectionManager.ts @@ -39,11 +39,11 @@ import { LogLevel, LogService } from "matrix-bot-sdk"; import { ProtectionSettingValidationError } from "./ProtectionSettings"; import { Consequence } from "./consequence"; import { htmlEscape, trace } from "../utils"; -import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION } from "../ErrorCache"; -import { RoomUpdateError } from "../models/RoomUpdateError"; +import { IRoomUpdateError, PermissionError, RoomUpdateException } from "../models/RoomUpdateError"; import { BanPropagation } from "./BanPropagation"; import { MatrixDataManager, RawSchemedData, SchemaMigration, SCHEMA_VERSION_KEY } from "../models/MatrixDataManager"; import { Permalinks } from "../commands/interface-manager/Permalinks"; +import { CommandExceptionKind } from "../commands/interface-manager/CommandException"; const PROTECTIONS: Protection[] = [ new FirstMessageIsImage(), @@ -403,8 +403,8 @@ export class ProtectionManager { } @trace - public async verifyPermissionsIn(roomId: string): Promise { - const errors: RoomUpdateError[] = []; + public async verifyPermissionsIn(roomId: string): Promise { + const errors: IRoomUpdateError[] = []; const additionalPermissions = this.requiredProtectionPermissions(); try { @@ -432,35 +432,21 @@ export class ProtectionManager { const userLevel = plDefault(users[ownUserId], usersDefault); const aclLevel = plDefault(events["m.room.server_acl"], stateDefault); - // Wants: ban, kick, redact, m.room.server_acl + const addErrorToReport = (message: string) => { + errors.push(new PermissionError(roomId, message)) + } if (userLevel < ban) { - errors.push({ - roomId, - errorMessage: `Missing power level for bans: ${userLevel} < ${ban}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for bans: ${userLevel} < ${ban}`); } if (userLevel < kick) { - errors.push({ - roomId, - errorMessage: `Missing power level for kicks: ${userLevel} < ${kick}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for kicks: ${userLevel} < ${kick}`); } if (userLevel < redact) { - errors.push({ - roomId, - errorMessage: `Missing power level for redactions: ${userLevel} < ${redact}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for redactions: ${userLevel} < ${redact}`); } - if (userLevel < aclLevel) { - errors.push({ - roomId, - errorMessage: `Missing power level for server ACLs: ${userLevel} < ${aclLevel}`, - errorKind: ERROR_KIND_PERMISSION, - }); + if (!this.mjolnir.config.disableServerACL && userLevel < aclLevel) { + addErrorToReport(`Missing power level for server ACLs: ${userLevel} < ${aclLevel}`); } // Wants: Additional permissions @@ -469,24 +455,15 @@ export class ProtectionManager { const permLevel = plDefault(events[additionalPermission], stateDefault); if (userLevel < permLevel) { - errors.push({ - roomId, - errorMessage: `Missing power level for "${additionalPermission}" state events: ${userLevel} < ${permLevel}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for "${additionalPermission}" state events: ${userLevel} < ${permLevel}`); } } // Otherwise OK } catch (e) { - LogService.error("Mjolnir", e); - errors.push({ - roomId, - errorMessage: e.message || (e.body ? e.body.error : ''), - errorKind: ERROR_KIND_FATAL, - }); + const message = `Unexpected error when attempting to verify the permissions in ${roomId}`; + errors.push(new RoomUpdateException(roomId, CommandExceptionKind.Unknown, e, message)); } - return errors; } diff --git a/src/queues/EventRedactionQueue.ts b/src/queues/EventRedactionQueue.ts index d65b27f8..a1040d25 100644 --- a/src/queues/EventRedactionQueue.ts +++ b/src/queues/EventRedactionQueue.ts @@ -25,11 +25,11 @@ limitations under the License. * are NOT distributed, contributed, committed, or licensed under the Apache License. */ import { LogLevel, MatrixClient } from "matrix-bot-sdk" -import { ERROR_KIND_FATAL } from "../ErrorCache"; -import { RoomUpdateError } from "../models/RoomUpdateError"; +import { IRoomUpdateError, RoomUpdateException } from "../models/RoomUpdateError"; import { redactUserMessagesIn, trace } from "../utils"; import ManagementRoomOutput from "../ManagementRoomOutput"; import { MatrixSendClient } from "../MatrixEmitter"; +import { CommandExceptionKind } from "../commands/interface-manager/CommandException"; export interface QueuedRedaction { /** The room which the redaction will take place in. */ @@ -124,25 +124,21 @@ export class EventRedactionQueue { * @returns A description of any errors encountered by each QueuedRedaction that was processed. */ @trace - public async process(client: MatrixSendClient, managementRoom: ManagementRoomOutput, limitToRoomId?: string): Promise { - const errors: RoomUpdateError[] = []; + public async process(client: MatrixSendClient, managementRoom: ManagementRoomOutput, limitToRoomId?: string): Promise { + const errors: IRoomUpdateError[] = []; const redact = async (currentBatch: QueuedRedaction[]) => { for (const redaction of currentBatch) { try { await redaction.redact(client, managementRoom); } catch (e) { - let roomError: RoomUpdateError; - if (e.roomId && e.errorMessage && e.errorKind) { - roomError = e; - } else { - const message = e.message || (e.body ? e.body.error : ''); - roomError = { - roomId: redaction.roomId, - errorMessage: message, - errorKind: ERROR_KIND_FATAL, - }; - } - errors.push(roomError); + const message = e.message || (e.body ? e.body.error : ''); + const error = new RoomUpdateException( + redaction.roomId, + CommandExceptionKind.Unknown, + e, + message + ); + errors.push(error); } } } diff --git a/synapse_antispam/setup.py b/synapse_antispam/setup.py index dd7ec4a3..1aed3c95 100644 --- a/synapse_antispam/setup.py +++ b/synapse_antispam/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="mjolnir", - version="1.84.0", # version automated in package.json - Do not edit this line, use `yarn version`. + version="1.85.1", # version automated in package.json - Do not edit this line, use `yarn version`. packages=find_packages(), description="Mjolnir Antispam", include_package_data=True, diff --git a/test/integration/banListTest.ts b/test/integration/banListTest.ts index 5bfca29c..a0320720 100644 --- a/test/integration/banListTest.ts +++ b/test/integration/banListTest.ts @@ -597,7 +597,7 @@ describe('Test: Creating policy lists.', function() { }) }) -describe.only('Test: Continue to ban other marked members when one member cannot be banned', function() { +describe('Test: Continue to ban other marked members when one member cannot be banned', function() { it('Failing to ban a moderator should not stop other members being banned.', async function(this: MjolnirTestContext) { if (this.mjolnir === undefined) { throw new TypeError("Mjolnir was never created.") diff --git a/test/integration/banPropagationTest.ts b/test/integration/banPropagationTest.ts index 9b5e24d5..86b5e4c3 100644 --- a/test/integration/banPropagationTest.ts +++ b/test/integration/banPropagationTest.ts @@ -54,5 +54,26 @@ describe("Ban propagation test", function() { expect(rules.length).toBe(1); expect(rules[0].entity).toBe('@test:example.com'); expect(rules[0].reason).toBe('spam'); + + // now unban them >:3 + const unbanPrompt = await getFirstEventMatching({ + matrix: mjolnir.matrixEmitter, + targetRoom: mjolnir.managementRoomId, + lookAfterEvent: async function () { + // ban a user in one of our protected rooms using the moderator + await moderator.unbanUser('@test:example.com', protectedRooms[0]); + return undefined; + }, + predicate: function (event: any): boolean { + return (event['content']?.['body'] ?? '').startsWith('The user') + } + }); + + await moderator.unstableApis.addReactionToEvent( + mjolnir.managementRoomId, unbanPrompt['event_id'], 'unban from all' + ); + await new Promise(resolve => setTimeout(resolve, 10000)); + const rulesAfterUnban = policyList.rulesMatchingEntity('@test:example.com', RULE_USER); + expect(rulesAfterUnban.length).toBe(0); }) }) diff --git a/yarn.lock b/yarn.lock index f523b8d7..b5c824e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,18 +2,16 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@alloc/quick-lru@^5.2.0": version "5.2.0" resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13": version "7.14.5" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz" @@ -26,7 +24,7 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz" integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== -"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": +"@babel/highlight@^7.14.5": version "7.14.5" resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz" integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== @@ -49,21 +47,38 @@ enabled "2.0.x" kuler "^2.0.0" -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.6.1": + version "4.8.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.0.tgz#11195513186f68d42fbf449f9a7136b2c0c92005" + integrity sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg== + +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" + js-yaml "^4.1.0" + minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/js@8.49.0": + version "8.49.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.49.0.tgz#86f79756004a97fa4df866835093f1df3d03c333" + integrity sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w== + "@grpc/grpc-js@^1.7.1": version "1.9.2" resolved "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.2.tgz" @@ -153,29 +168,49 @@ "@hapi/hoek" "^9.0.0" "@hapi/topo" "^5.0.0" -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== +"@humanwhocodes/config-array@^0.11.11": + version "0.11.11" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.11.tgz#88a04c570dbbc7dd943e4712429c3df09bc32844" + integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA== dependencies: - "@humanwhocodes/object-schema" "^1.2.0" + "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" + minimatch "^3.0.5" -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@jest/types@^27.2.4": - version "27.2.4" - resolved "https://registry.npmjs.org/@jest/types/-/types-27.2.4.tgz" - integrity sha512-IDO2ezTxeMvQAHxzG/ZvEyA47q0aVfzT95rGFl7bZs/Go0aIucvfDbS2rmnoEdXxlLQhcolmoG/wvL/uKx4tKA== +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jest/expect-utils@^29.6.4": + version "29.6.4" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.4.tgz#17c7dfe6cec106441f218b0aff4b295f98346679" + integrity sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg== dependencies: + jest-get-type "^29.6.3" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" - "@types/yargs" "^16.0.0" + "@types/yargs" "^17.0.8" chalk "^4.0.0" "@matrix-org/matrix-sdk-crypto-nodejs@0.1.0-beta.6": @@ -186,6 +221,27 @@ https-proxy-agent "^5.0.1" node-downloader-helper "^2.1.5" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@opentelemetry/api-logs@0.41.2": version "0.41.2" resolved "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.41.2.tgz" @@ -974,6 +1030,11 @@ resolved "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" @@ -1011,10 +1072,10 @@ resolved "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz" integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== -"@types/config@^3.3.0": - version "3.3.0" - resolved "https://registry.npmjs.org/@types/config/-/config-3.3.0.tgz" - integrity sha512-9kZSbl3/X3TVNowLCu5HFQdQmD+4287Om55avknEYkuo6R2dDrsp/EXEHUFvfYeG7m1eJ0WYGj+cbcUIhARJAQ== +"@types/config@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/config/-/config-3.3.1.tgz#eb385f254cd08381db4dda7b9bef4cc2fd400e5d" + integrity sha512-ZhBk8IVIbc3cuES10j2I+xa3L68rpl1X35FdsNce/AiE7yJnhQaA7tvO5MRZblqpBny4OIddJ+WQL04I1933Zg== "@types/connect@*", "@types/connect@3.4.35": version "3.4.35" @@ -1038,10 +1099,10 @@ "@types/keygrip" "*" "@types/node" "*" -"@types/crypto-js@^4.0.2": - version "4.0.2" - resolved "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.0.2.tgz" - integrity sha512-sCVniU+h3GcGqxOmng11BRvf9TfN9yIs8KKjB8C8d75W69cpTfZG80gau9yTx5SxF3gvHGbJhdESzzvnjtf3Og== +"@types/crypto-js@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.1.2.tgz#fb56b34f397d9ae2335611e416f15e7d65e276e6" + integrity sha512-t33RNmTu5ufG/sorROIafiCVJMx3jz95bXUMoPAZcUD14fxMXnuTzqzXZoxpR0tNx2xpw11Dlmem9vGCsrSOfA== "@types/express-serve-static-core@^4.17.33": version "4.17.36" @@ -1053,7 +1114,7 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express@*", "@types/express@4.17.17", "@types/express@^4.17.13": +"@types/express@*", "@types/express@4.17.17": version "4.17.17" resolved "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz" integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== @@ -1063,6 +1124,16 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/hapi__catbox@*": version "10.2.4" resolved "https://registry.npmjs.org/@types/hapi__catbox/-/hapi__catbox-10.2.4.tgz" @@ -1211,10 +1282,10 @@ resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz" integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== -"@types/mocha@^9.0.0": - version "9.0.0" - resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz" - integrity sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA== +"@types/mocha@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" + integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== "@types/mysql@2.15.21": version "2.15.21" @@ -1223,14 +1294,19 @@ dependencies: "@types/node" "*" -"@types/nedb@^1.8.12": - version "1.8.12" - resolved "https://registry.npmjs.org/@types/nedb/-/nedb-1.8.12.tgz" - integrity sha512-ICDoQMORMjOSqfNFXT4ENXfwwCir1BPblXNm0SPH7C4Q10ou+pvVagcFAJ+rrzf3A47tGU4K/KbzKu7wO9j45Q== +"@types/nedb@^1.8.13": + version "1.8.13" + resolved "https://registry.yarnpkg.com/@types/nedb/-/nedb-1.8.13.tgz#31c608d5b155d33b3c98b946339086703d215865" + integrity sha512-x/aIeHmmiDq1kMzgHvjygxl5RZGzIabFcq2HpRzB3X26AdfPg5Y70EwWrcZM/TuJwNHtWRruD/telSTvPEY6Xw== dependencies: "@types/node" "*" -"@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0", "@types/node@^18.16.7": +"@types/node@*", "@types/node@^20.6.0": + version "20.6.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.0.tgz#9d7daa855d33d4efec8aea88cd66db1c2f0ebe16" + integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg== + +"@types/node@>=12.12.47", "@types/node@>=13.7.0": version "18.16.7" resolved "https://registry.npmjs.org/@types/node/-/node-18.16.7.tgz" integrity sha512-MFg7ua/bRtnA1hYE3pVyWxGd/r7aMqjNOdHvlSsXV3n8iaeGKkOaPzpJh6/ovf4bEXWcojkeMJpTsq3mzXW4IQ== @@ -1333,18 +1409,13 @@ resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz" integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== -"@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== +"@types/yargs@^17.0.8": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== dependencies: "@types/yargs-parser" "*" -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz" @@ -1376,9 +1447,9 @@ acorn-import-assertions@^1.9.0: resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz" integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== -acorn-jsx@^5.3.1: +acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^7.1.1: @@ -1386,7 +1457,7 @@ acorn-walk@^7.1.1: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.1.1, acorn@^7.4.0: +acorn@^7.1.1: version "7.4.1" resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -1396,7 +1467,7 @@ acorn@^8.2.4: resolved "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz" integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== -acorn@^8.8.2: +acorn@^8.8.2, acorn@^8.9.0: version "8.10.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== @@ -1408,7 +1479,7 @@ agent-base@6: dependencies: debug "4" -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1418,16 +1489,6 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.11.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - another-json@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/another-json/-/another-json-0.2.0.tgz" @@ -1438,7 +1499,7 @@ ansi-color@^0.2.1: resolved "https://registry.npmjs.org/ansi-color/-/ansi-color-0.2.1.tgz" integrity sha512-bF6xLaZBLpOQzgYUtYEhJx090nPSZk1BQ/q2oyBK9aMMcJHzx9uXGCjI2Y+LebsN4Jwoykr0V9whbPiogdyHoQ== -ansi-colors@4.1.1, ansi-colors@^4.1.1: +ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== @@ -1509,11 +1570,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - async-lock@^1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/async-lock/-/async-lock-1.3.2.tgz" @@ -1647,6 +1703,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -1749,6 +1812,11 @@ chokidar@3.5.3: optionalDependencies: fsevents "~2.3.2" +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + cjs-module-lexer@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz" @@ -1842,12 +1910,12 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -config@^3.3.8: - version "3.3.8" - resolved "https://registry.npmjs.org/config/-/config-3.3.8.tgz" - integrity sha512-rFzF6VESOdp7wAXFlB9IOZI4ouL05g3A03v2eRcTHj2JBQaTNJ40zhAUl5wRbWHqLZ+uqp/7OE0BWWtAVgrong== +config@^3.3.9: + version "3.3.9" + resolved "https://registry.yarnpkg.com/config/-/config-3.3.9.tgz#27fae95b43e0e1d5723e54143c090954d8e49572" + integrity sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg== dependencies: - json5 "^2.2.1" + json5 "^2.2.3" content-disposition@0.5.4: version "0.5.4" @@ -1935,10 +2003,10 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@4.3.3, debug@^4.0.1, debug@^4.1.1: - version "4.3.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" @@ -1977,10 +2045,10 @@ destroy@1.2.0: resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -diff-sequences@^27.0.6: - version "27.5.1" - resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz" - integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== diff@5.0.0: version "5.0.0" @@ -2109,13 +2177,6 @@ encodeurl@~1.0.2: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - entities@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" @@ -2171,95 +2232,80 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" - estraverse "^4.1.1" + estraverse "^5.2.0" -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.49: + version "8.49.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.49.0.tgz#09d80a89bdb4edee2efcf6964623af1054bf6d42" + integrity sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ== dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint@^7.32: - version "7.32.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" - ajv "^6.10.0" + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "8.49.0" + "@humanwhocodes/config-array" "^0.11.11" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.9" + optionator "^0.9.3" + strip-ansi "^6.0.1" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -2270,11 +2316,6 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" @@ -2295,17 +2336,16 @@ eventemitter3@^4.0.4: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -expect@^27.0.6: - version "27.2.4" - resolved "https://registry.npmjs.org/expect/-/expect-27.2.4.tgz" - integrity sha512-gOtuonQ8TCnbNNCSw2fhVzRf8EFYDII4nB5NmG4IEV0rbUnW1I5zXvoTntU4iicB/Uh0oZr20NGlOLdJiwsOZA== +expect@^29.6.4: + version "29.6.4" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.4.tgz#a6e6f66d4613717859b2fe3da98a739437b6f4b8" + integrity sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA== dependencies: - "@jest/types" "^27.2.4" - ansi-styles "^5.0.0" - jest-get-type "^27.0.6" - jest-matcher-utils "^27.2.4" - jest-message-util "^27.2.4" - jest-regex-util "^27.0.6" + "@jest/expect-utils" "^29.6.4" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.6.4" + jest-message-util "^29.6.3" + jest-util "^29.6.3" express-rate-limit@^6.7.0: version "6.7.0" @@ -2379,6 +2419,13 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + fecha@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz" @@ -2418,7 +2465,7 @@ finalhandler@1.2.0: statuses "2.0.1" unpipe "~1.0.0" -find-up@5.0.0: +find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -2520,11 +2567,6 @@ function-bind@^1.1.1: resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - gaxios@^5.0.0: version "5.1.3" resolved "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz" @@ -2578,7 +2620,14 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -2590,7 +2639,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.2.0, glob@^7.1.1: +glob@7.2.0: version "7.2.0" resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -2602,7 +2651,7 @@ glob@7.2.0, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: +glob@^7.1.1, glob@^7.1.3: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -2614,10 +2663,10 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^13.6.0, globals@^13.9.0: - version "13.11.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz" - integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g== +globals@^13.19.0: + version "13.21.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.21.0.tgz#163aae12f34ef502f5153cfbdd3600f36c63c571" + integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg== dependencies: type-fest "^0.20.2" @@ -2626,15 +2675,15 @@ graceful-fs@^4.1.3: resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -graceful-fs@^4.2.4: - version "4.2.8" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -growl@1.10.5: - version "1.10.5" - resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== har-schema@^2.0.0: version "2.0.0" @@ -2812,17 +2861,17 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== immediate@~3.0.5: version "3.0.6" resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -2908,7 +2957,7 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -2936,6 +2985,11 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" @@ -2997,50 +3051,57 @@ jaeger-client@^3.15.0: uuid "^8.3.2" xorshift "^1.1.1" -jest-diff@^27.2.4: - version "27.2.4" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.4.tgz" - integrity sha512-bLAVlDSCR3gqUPGv+4nzVpEXGsHh98HjUL7Vb2hVyyuBDoQmja8eJb0imUABsuxBeUVmf47taJSAd9nDrwWKEg== +jest-diff@^29.6.4: + version "29.6.4" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.4.tgz#85aaa6c92a79ae8cd9a54ebae8d5b6d9a513314a" + integrity sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw== dependencies: chalk "^4.0.0" - diff-sequences "^27.0.6" - jest-get-type "^27.0.6" - pretty-format "^27.2.4" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.6.3" -jest-get-type@^27.0.6: - version "27.0.6" - resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz" - integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== -jest-matcher-utils@^27.2.4: - version "27.2.4" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.4.tgz" - integrity sha512-nQeLfFAIPPkyhkDfifAPfP/U5wm1x0fLtAzqXZSSKckXDNuk2aaOfQiDYv1Mgf5GY6yOsxfUnvNm3dDjXM+BXw== +jest-matcher-utils@^29.6.4: + version "29.6.4" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz#327db7ababea49455df3b23e5d6109fe0c709d24" + integrity sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ== dependencies: chalk "^4.0.0" - jest-diff "^27.2.4" - jest-get-type "^27.0.6" - pretty-format "^27.2.4" + jest-diff "^29.6.4" + jest-get-type "^29.6.3" + pretty-format "^29.6.3" -jest-message-util@^27.2.4: - version "27.2.4" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.4.tgz" - integrity sha512-wbKT/BNGnBVB9nzi+IoaLkXt6fbSvqUxx+IYY66YFh96J3goY33BAaNG3uPqaw/Sh/FR9YpXGVDfd5DJdbh4nA== +jest-message-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.3.tgz#bce16050d86801b165f20cfde34dc01d3cf85fbf" + integrity sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.2.4" + "@jest/types" "^29.6.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^27.2.4" + pretty-format "^29.6.3" slash "^3.0.0" stack-utils "^2.0.3" -jest-regex-util@^27.0.6: - version "27.0.6" - resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz" - integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== +jest-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.3.tgz#e15c3eac8716440d1ed076f09bc63ace1aebca63" + integrity sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" joi@^17.3.0: version "17.10.1" @@ -3128,11 +3189,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - json-schema@0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" @@ -3155,10 +3211,10 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonpointer@^5.0.0: version "5.0.1" @@ -3227,21 +3283,11 @@ lodash.camelcase@^4.3.0: resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" - integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== - lodash@4, lodash@^4.17.19, lodash@^4.7.0: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" @@ -3297,7 +3343,7 @@ lru-cache@^4.1.5: lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" @@ -3423,14 +3469,14 @@ minimalistic-assert@^1.0.1: resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== dependencies: - brace-expansion "^1.1.7" + brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -3461,32 +3507,29 @@ mkdirp@~0.5.1: dependencies: minimist "^1.2.6" -mocha@^9.0.1: - version "9.2.2" - resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" - integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== +mocha@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== dependencies: - "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" browser-stdout "1.3.1" chokidar "3.5.3" - debug "4.3.3" + debug "4.3.4" diff "5.0.0" escape-string-regexp "4.0.0" find-up "5.0.0" glob "7.2.0" - growl "1.10.5" he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" - minimatch "4.2.1" + minimatch "5.0.1" ms "2.1.3" - nanoid "3.3.1" + nanoid "3.3.3" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" + workerpool "6.2.1" yargs "16.2.0" yargs-parser "20.2.4" yargs-unparser "2.0.0" @@ -3532,10 +3575,10 @@ ms@2.1.3, ms@^2.1.1: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@3.3.1: - version "3.3.1" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== nanoid@^3.3.4: version "3.3.4" @@ -3672,17 +3715,17 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" p-finally@^1.0.0: version "1.0.0" @@ -3905,26 +3948,20 @@ prelude-ls@~1.1.2: resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -pretty-format@^27.2.4: - version "27.2.4" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.4.tgz" - integrity sha512-NUjw22WJHldzxyps2YjLZkUj6q1HvjqFezkB9Y2cklN8NtVZN/kZEXGZdFw4uny3oENzV5EEMESrkI0YDUH8vg== +pretty-format@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.3.tgz#d432bb4f1ca6f9463410c3fb25a0ba88e594ace7" + integrity sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw== dependencies: - "@jest/types" "^27.2.4" - ansi-regex "^5.0.1" + "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" - react-is "^17.0.1" + react-is "^18.0.0" process@^0.10.0: version "0.10.1" resolved "https://registry.npmjs.org/process/-/process-0.10.1.tgz" integrity sha512-dyIett8dgGIZ/TXKUzeYExt7WA6ldDzys9vTDU/cCA9L17Ypme+KzS+NjQCjpn9xsvi/shbMC+yP/BcFMBz0NA== -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - prom-client@^14.1.0: version "14.1.0" resolved "https://registry.npmjs.org/prom-client/-/prom-client-14.1.0.tgz" @@ -3997,6 +4034,11 @@ qs@~6.5.2: resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + railroad-diagrams@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz" @@ -4032,10 +4074,10 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" @@ -4053,11 +4095,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -regexpp@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - request-promise-core@1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz" @@ -4106,11 +4143,6 @@ require-directory@^2.1.1: resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - require-in-the-middle@^7.1.1: version "7.2.0" resolved "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz" @@ -4139,6 +4171,11 @@ ret@~0.1.10: resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" @@ -4146,6 +4183,13 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" @@ -4197,7 +4241,7 @@ semver@^5.3.0, semver@^5.6.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^7.2.1, semver@^7.5.1, semver@^7.5.4: +semver@^7.5.1, semver@^7.5.4: version "7.5.4" resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -4293,15 +4337,6 @@ slash@^3.0.0: resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" @@ -4412,7 +4447,7 @@ strip-bom@^3.0.0: resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -4448,18 +4483,6 @@ symbol-tree@^3.2.4: resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^6.0.9: - version "6.7.1" - resolved "https://registry.npmjs.org/table/-/table-6.7.1.tgz" - integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== - dependencies: - ajv "^8.0.1" - lodash.clonedeep "^4.5.0" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - tdigest@^0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz" @@ -4532,10 +4555,10 @@ triple-beam@^1.3.0: resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== -ts-mocha@^9.0.2: - version "9.0.2" - resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz" - integrity sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw== +ts-mocha@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" + integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw== dependencies: ts-node "7.0.1" optionalDependencies: @@ -4648,9 +4671,9 @@ typescript-formatter@^7.2: commandpost "^1.0.0" editorconfig "^0.15.0" -typescript@^5.1.6: +typescript@^5.2.2: version "5.2.2" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== ulidx@^0.3.0: @@ -4702,11 +4725,6 @@ uuid@^8.3.2: resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" @@ -4779,7 +4797,7 @@ whatwg-url@^8.0.0, whatwg-url@^8.5.0: tr46 "^2.1.0" webidl-conversions "^6.1.0" -which@2.0.2, which@^2.0.1: +which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -4821,15 +4839,15 @@ winston@^3.3.3: triple-beam "^1.3.0" winston-transport "^4.5.0" -word-wrap@^1.2.3, word-wrap@~1.2.3: +word-wrap@~1.2.3: version "1.2.4" resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz" integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== wrap-ansi@^7.0.0: version "7.0.0" @@ -4885,10 +4903,10 @@ yallist@^4.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^2.2.2: - version "2.2.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz" - integrity sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA== +yaml@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.2.tgz#f522db4313c671a0ca963a75670f1c12ea909144" + integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg== yargs-parser@20.2.4: version "20.2.4"