mirror of
https://github.com/the-draupnir-project/Draupnir.git
synced 2026-10-23 17:32:22 +00:00
Rename to Draupnir in Appropriate Places (#591)
* Rename to Draupnir in Appropriate Places * Integrate Code review feedback on CHANGELOG.md
This commit is contained in:
1 parent
39eb2984c5
commit
9cc64074e1
45 files changed
+156
-116
No files matched your search
+1
-1
@@ -7,7 +7,7 @@ config/*
|
||||
!config/default.yaml
|
||||
|
||||
# Draupnir test data
|
||||
mjolnir-registration.yaml
|
||||
draupnir-registration.yaml
|
||||
test/harness/mjolnir-data/*
|
||||
|
||||
# Misc
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2024 Gnuxie <Gnuxie@protonmail.com>
|
||||
|
||||
SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
-->
|
||||
|
||||
# Changelog
|
||||
|
||||
All notable changes to Draupnir will be kept in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased] - 2024-10-04
|
||||
|
||||
### Changed
|
||||
|
||||
* `Dockerfile`: entry-point was renamed from `mjolnir-entrypoint.sh` to `draupnir-entrypoint.sh`.
|
||||
If you have built a Dockerfile based on ours, you may need to make some changes.
|
||||
|
||||
* `Dockerfile`: source code was moved from `/mjolnir` to `/draupnir`. If you have built a custom
|
||||
docker image based on our Dockerfile based on ours, you may need to make some changes.
|
||||
|
||||
* The appservice registration file generator no longer emits `mjolnir-registration.yaml`
|
||||
as it has been renamed to `draupnir-registration.yaml`. This is only a concern if you have
|
||||
automated tooling that generates a registration file.
|
||||
|
||||
## Versions v2.0.0-beta.7 and prior
|
||||
|
||||
Please see [Releases](https://github.com/the-draupnir-project/Draupnir/releases) for more information.
|
||||
|
||||
<!-- Remove me later. Currently points to releases as this is a Unreleased change.
|
||||
As soon as the release is made change the note to point to the release. -->
|
||||
+3
-3
@@ -9,9 +9,9 @@ COPY . /tmp/src
|
||||
RUN cd /tmp/src \
|
||||
&& yarn install --network-timeout 100000 \
|
||||
&& yarn build \
|
||||
&& mv lib/ /mjolnir/ \
|
||||
&& mv lib/ /draupnir/ \
|
||||
&& mv node_modules / \
|
||||
&& mv mjolnir-entrypoint.sh / \
|
||||
&& mv draupnir-entrypoint.sh / \
|
||||
&& mv package.json / \
|
||||
&& mv version.txt / \
|
||||
&& cd / \
|
||||
@@ -21,5 +21,5 @@ ENV NODE_ENV=production
|
||||
ENV NODE_CONFIG_DIR=/data/config
|
||||
|
||||
CMD ["bot"]
|
||||
ENTRYPOINT ["./mjolnir-entrypoint.sh"]
|
||||
ENTRYPOINT ["./draupnir-entrypoint.sh"]
|
||||
VOLUME ["/data"]
|
||||
Executable → Regular
+3
-3
@@ -5,15 +5,15 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 AND AFL-3.0
|
||||
|
||||
# This is used as the entrypoint in the mjolnir Dockerfile.
|
||||
# This is used as the entrypoint in the draupnir Dockerfile.
|
||||
# We want to transition away form people running the image without specifying `bot` or `appservice`.
|
||||
# So if eventually cli arguments are provided for the bot version, we want this to be the opportunity to move to `bot`.
|
||||
# Therefore using arguments without specifying `bot` (or appservice) is unsupported.
|
||||
# We maintain the behaviour where if it looks like someone is providing an executable to `docker run`, then we will execute that instead.
|
||||
# This aids configuration and debugging of the image if for example node needed to be started via another method.
|
||||
case "$1" in
|
||||
bot) shift; set -- node /mjolnir/index.js "$@";;
|
||||
appservice) shift; set -- node /mjolnir/appservice/cli.js "$@";;
|
||||
bot) shift; set -- node /draupnir/index.js "$@";;
|
||||
appservice) shift; set -- node /draupnir/appservice/cli.js "$@";;
|
||||
esac
|
||||
|
||||
exec "$@";
|
||||
+2
-2
@@ -13,7 +13,7 @@ up:
|
||||
- docker run --rm --network host --name mjolnir-test-reverse-proxy -p 127.0.0.1:8081:80 -v $MX_TEST_CWD/test/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx
|
||||
- corepack yarn install
|
||||
- corepack npx ts-node src/appservice/cli.ts -r -u "http://host.docker.internal:9000"
|
||||
- cp mjolnir-registration.yaml $MX_TEST_SYNAPSE_DIR/data/
|
||||
- cp draupnir-registration.yaml $MX_TEST_SYNAPSE_DIR/data/
|
||||
after:
|
||||
# Wait until Synapse is ready
|
||||
- until curl localhost:9999 --stderr /dev/null > /dev/null; do echo "Waiting for Synapse..."; sleep 1s; done
|
||||
@@ -45,7 +45,7 @@ homeserver:
|
||||
enable_registration_without_verification: true
|
||||
|
||||
app_service_config_files:
|
||||
- "/data/mjolnir-registration.yaml"
|
||||
- "/data/draupnir-registration.yaml"
|
||||
|
||||
# We remove rc_message so we can test rate limiting,
|
||||
# but we keep the others because of https://github.com/matrix-org/synapse/issues/11785
|
||||
|
||||
+4
-4
@@ -81,7 +81,7 @@ const log = new Logger("Draupnir");
|
||||
// webAPIS should not be included on the Draupnir class.
|
||||
// That should be managed elsewhere.
|
||||
// It's not actually relevant to the Draupnir instance and it only was connected
|
||||
// to Mjolnir because it needs to be started after Mjolnir started and not before.
|
||||
// to Draupnir because it needs to be started after Draupnir started and not before.
|
||||
// And giving it to the class was a dumb easy way of doing that.
|
||||
|
||||
export class Draupnir implements Client, MatrixAdaptorContext {
|
||||
@@ -99,7 +99,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
|
||||
public readonly managementRoomOutput: ManagementRoomOutput;
|
||||
public readonly managementRoomID: StringRoomID;
|
||||
/*
|
||||
* Config-enabled polling of reports in Synapse, so Mjolnir can react to reports
|
||||
* Config-enabled polling of reports in Synapse, so Draupnir can react to reports
|
||||
*/
|
||||
private reportPoller?: ReportPoller;
|
||||
/**
|
||||
@@ -135,7 +135,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
|
||||
public readonly policyRoomManager: PolicyRoomManager,
|
||||
public readonly roomMembershipManager: RoomMembershipManager,
|
||||
public readonly loggableConfigTracker: LoggableConfigTracker,
|
||||
/** Mjolnir has a feature where you can choose to accept invitations from a space and not just the management room. */
|
||||
/** Draupnir has a feature where you can choose to accept invitations from a space and not just the management room. */
|
||||
public readonly acceptInvitesFromRoom: MatrixRoomID,
|
||||
public readonly acceptInvitesFromRoomIssuer: RoomMembershipRevisionIssuer,
|
||||
public readonly safeModeToggle: SafeModeToggle,
|
||||
@@ -292,7 +292,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
|
||||
try {
|
||||
await this.managementRoomOutput.logMessage(
|
||||
LogLevel.INFO,
|
||||
"Mjolnir@startup",
|
||||
"Draupnir@startup",
|
||||
"Startup complete. Now monitoring rooms."
|
||||
);
|
||||
await sendMatrixEventsFromDeadDocument(
|
||||
|
||||
@@ -34,7 +34,7 @@ const levelToFn = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Allows the different componenets of mjolnir to send messages back to the management room without introducing a dependency on the entirity of a `Mjolnir` instance.
|
||||
* Allows the different componenets of draupnir to send messages back to the management room without introducing a dependency on the entirity of a `Draupnir` instance.
|
||||
*/
|
||||
export default class ManagementRoomOutput {
|
||||
constructor(
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
|
||||
/**
|
||||
* Utility to manage which users have access to the application service,
|
||||
* meaning whether a user is able to provision a mjolnir or continue to use one.
|
||||
* meaning whether a user is able to provision a draupnir or continue to use one.
|
||||
* Internally we use a policy list within matrix to determine who has access via the `AccessControlUnit`.
|
||||
*/
|
||||
export class AccessControl {
|
||||
@@ -41,7 +41,7 @@ export class AccessControl {
|
||||
|
||||
/**
|
||||
* Construct and initialize access control for the `MjolnirAppService`.
|
||||
* @param accessControlListId The room id of a policy list used to manage access to the appservice (who can provision & use mjolniren)
|
||||
* @param accessControlListId The room id of a policy list used to manage access to the appservice (who can provision & use draupnir)
|
||||
* @param bridge The matrix-appservice-bridge, used to get the appservice bot.
|
||||
* @returns A new instance of `AccessControl` to be used by `MjolnirAppService`.
|
||||
*/
|
||||
|
||||
+14
-14
@@ -109,9 +109,9 @@ export class Api {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the management room for a mjolnir.
|
||||
* @param req.body.openId An OpenID token to verify that the sender of the request owns the mjolnir described in `req.body.mxid`.
|
||||
* @param req.body.mxid The mxid of the mjolnir we want to find the management room for.
|
||||
* Finds the management room for a draupnir.
|
||||
* @param req.body.openId An OpenID token to verify that the sender of the request owns the draupnir described in `req.body.mxid`.
|
||||
* @param req.body.mxid The mxid of the draupnir we want to find the management room for.
|
||||
*/
|
||||
private async pathGet(req: express.Request, response: express.Response) {
|
||||
const accessToken = req.body["openId"];
|
||||
@@ -141,7 +141,7 @@ export class Api {
|
||||
userId
|
||||
);
|
||||
if (mjolnir === undefined) {
|
||||
response.status(400).send("unknown mjolnir mxid");
|
||||
response.status(400).send("unknown draupnir mxid");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -149,8 +149,8 @@ export class Api {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mxids of mjolnirs that this user has provisioned.
|
||||
* @param req.body.openId An OpenID token to find the sender of the request with and find their provisioned mjolnirs.
|
||||
* Return the mxids of draupnirs that this user has provisioned.
|
||||
* @param req.body.openId An OpenID token to find the sender of the request with and find their provisioned draupnirs.
|
||||
*/
|
||||
private async pathList(req: express.Request, response: express.Response) {
|
||||
const accessToken = req.body["openId"];
|
||||
@@ -174,9 +174,9 @@ export class Api {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new mjolnir for the requesting user and protects their first room.
|
||||
* @param req.body.roomId The room id that the request to create a mjolnir originates from.
|
||||
* This is so that mjolnir can protect the room once the authenticity of the request has been verified.
|
||||
* Creates a new draupnir for the requesting user and protects their first room.
|
||||
* @param req.body.roomId The room id that the request to create a draupnir originates from.
|
||||
* This is so that draupnir can protect the room once the authenticity of the request has been verified.
|
||||
* @param req.body.openId An OpenID token to find the sender of the request with.
|
||||
*/
|
||||
private async pathCreate(req: express.Request, response: express.Response) {
|
||||
@@ -214,10 +214,10 @@ export class Api {
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a mjolnir to join and protect a room.
|
||||
* @param req.body.openId An OpenID token to find the sender of the request with and that they own the mjolnir described in `req.body.mxid`.
|
||||
* @param req.body.mxid The mxid of the mjolnir that should join the room.
|
||||
* @param req.body.roomId The room that this mjolnir should join and protect.
|
||||
* Request a draupnir to join and protect a room.
|
||||
* @param req.body.openId An OpenID token to find the sender of the request with and that they own the draupnir described in `req.body.mxid`.
|
||||
* @param req.body.mxid The mxid of the draupnir that should join the room.
|
||||
* @param req.body.roomId The room that this draupnir should join and protect.
|
||||
*/
|
||||
private async pathJoin(req: express.Request, response: express.Response) {
|
||||
const accessToken = req.body["openId"];
|
||||
@@ -255,7 +255,7 @@ export class Api {
|
||||
userId
|
||||
);
|
||||
if (mjolnir === undefined) {
|
||||
response.status(400).send("unknown mjolnir mxid");
|
||||
response.status(400).send("unknown draupnir mxid");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,8 +89,8 @@ export class MjolnirAppService {
|
||||
|
||||
/**
|
||||
* Make and initialize the app service from the config, ready to be started.
|
||||
* @param config The appservice's config, not mjolnir's, see `src/appservice/config`.
|
||||
* @param dataStore A datastore to persist infomration about the mjolniren to.
|
||||
* @param config The appservice's config, not draupnirs's, see `src/appservice/config`.
|
||||
* @param dataStore A datastore to persist infomration about the draupnir to.
|
||||
* @param registrationFilePath A file path to the registration file to read the namespace and tokens from.
|
||||
* @returns A new `MjolnirAppService`.
|
||||
*/
|
||||
@@ -109,10 +109,10 @@ export class MjolnirAppService {
|
||||
// to make the code base much simpler. A small hack to pay for an overall less hacky code base.
|
||||
controller: {
|
||||
onUserQuery: () => {
|
||||
throw new Error("Mjolnir uninitialized");
|
||||
throw new Error("Draupnir uninitialized");
|
||||
},
|
||||
onEvent: () => {
|
||||
throw new Error("Mjolnir uninitialized");
|
||||
throw new Error("Draupnir uninitialized");
|
||||
},
|
||||
},
|
||||
suppressEcho: false,
|
||||
@@ -241,11 +241,11 @@ export class MjolnirAppService {
|
||||
return {}; // auto-provision users with no additonal data
|
||||
}
|
||||
|
||||
// Provision a new mjolnir for the invitee when the appservice bot (designated by this.bridge.botUserId) is invited to a room.
|
||||
// Provision a new draupnir for the invitee when the appservice bot (designated by this.bridge.botUserId) is invited to a room.
|
||||
// Acts as an alternative to the web api provided for the widget.
|
||||
private async handleProvisionInvite(mxEvent: WeakEvent): Promise<void> {
|
||||
log.info(
|
||||
`${mxEvent.sender} has sent an invitation to the appservice bot ${this.bridge.botUserId}, attempting to provision them a mjolnir`
|
||||
`${mxEvent.sender} has sent an invitation to the appservice bot ${this.bridge.botUserId}, attempting to provision them a draupnir`
|
||||
);
|
||||
// Join the room and try to send the welcome flow
|
||||
try {
|
||||
@@ -282,7 +282,7 @@ export class MjolnirAppService {
|
||||
);
|
||||
} catch (e: unknown) {
|
||||
log.error(
|
||||
`Failed to provision a mjolnir for ${mxEvent.sender} after they invited ${this.bridge.botUserId}:`,
|
||||
`Failed to provision a draupnir for ${mxEvent.sender} after they invited ${this.bridge.botUserId}:`,
|
||||
e
|
||||
);
|
||||
// continue, we still want to reject this invitation.
|
||||
@@ -296,7 +296,7 @@ export class MjolnirAppService {
|
||||
);
|
||||
}
|
||||
try {
|
||||
// reject the invite to keep the room clean and make sure the invetee doesn't get confused and think this is their mjolnir.
|
||||
// reject the invite to keep the room clean and make sure the invetee doesn't get confused and think this is their draupnir.
|
||||
await this.bridge.getBot().getClient().leaveRoom(mxEvent.room_id);
|
||||
} catch (e: unknown) {
|
||||
log.warn("Unable to reject an invite to a room", e);
|
||||
@@ -341,7 +341,10 @@ export class MjolnirAppService {
|
||||
* @param port The port that the appservice should listen on to receive transactions from the homeserver.
|
||||
*/
|
||||
private async start(port: number) {
|
||||
log.info("Starting MjolnirAppService, Matrix-side to listen on port", port);
|
||||
log.info(
|
||||
"Starting DraupnirAppService, Matrix-side to listen on port",
|
||||
port
|
||||
);
|
||||
this.api.start(this.config.webAPI.port);
|
||||
await this.bridge.listen(port);
|
||||
this.prometheusMetrics.addAppServicePath(this.bridge);
|
||||
@@ -353,7 +356,7 @@ export class MjolnirAppService {
|
||||
res.status(200).send("ok");
|
||||
},
|
||||
});
|
||||
log.info("MjolnirAppService started successfully");
|
||||
log.info("DraupnirAppService started successfully");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,7 +86,7 @@ export class AppServiceDraupnirManager {
|
||||
* @param dataStore The data store interface that has the details for provisioned draupnirs.
|
||||
* @param bridge The bridge abstraction that encapsulates details about the appservice.
|
||||
* @param accessControl Who has access to the bridge.
|
||||
* @returns A new mjolnir manager.
|
||||
* @returns A new Draupnir manager.
|
||||
*/
|
||||
public static async makeDraupnirManager(
|
||||
serverName: string,
|
||||
@@ -113,11 +113,11 @@ export class AppServiceDraupnirManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new mjolnir for a user.
|
||||
* @param requestingUserID The user that is requesting this mjolnir and who will own it.
|
||||
* Creates a new draupnir for a user.
|
||||
* @param requestingUserID The user that is requesting this draupnir and who will own it.
|
||||
* @param managementRoomId An existing matrix room to act as the management room.
|
||||
* @param client A client for the appservice virtual user that the new mjolnir should use.
|
||||
* @returns A new managed mjolnir.
|
||||
* @param client A client for the appservice virtual user that the new draupnir should use.
|
||||
* @returns A new managed draupnir.
|
||||
*/
|
||||
public async makeInstance(
|
||||
localPart: string,
|
||||
@@ -202,7 +202,7 @@ export class AppServiceDraupnirManager {
|
||||
power_level_content_override: {
|
||||
users: {
|
||||
[requestingUserID]: 100,
|
||||
// Give the mjolnir a higher PL so that can avoid issues with managing the management room.
|
||||
// Give the draupnir a higher PL so that can avoid issues with managing the management room.
|
||||
[await mjIntent.matrixClient.getUserId()]: 101,
|
||||
},
|
||||
},
|
||||
@@ -279,9 +279,9 @@ export class AppServiceDraupnirManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to start a mjolnir, and notify its management room of any failure to start.
|
||||
* Attempt to start a draupnir, and notify its management room of any failure to start.
|
||||
* Will be added to `this.unstartedMjolnirs` if we fail to start it AND it is not already running.
|
||||
* @param mjolnirRecord The record for the mjolnir that we want to start.
|
||||
* @param mjolnirRecord The record for the draupnir that we want to start.
|
||||
*/
|
||||
public async startDraupnirFromRecord(
|
||||
mjolnirRecord: MjolnirRecord
|
||||
@@ -330,7 +330,7 @@ export class AppServiceDraupnirManager {
|
||||
mjIntent.matrixClient
|
||||
).catch((e: unknown) => {
|
||||
log.error(
|
||||
`Could not start mjolnir ${mjolnirRecord.local_part} for ${mjolnirRecord.owner}:`,
|
||||
`Could not start draupnir ${mjolnirRecord.local_part} for ${mjolnirRecord.owner}:`,
|
||||
e
|
||||
);
|
||||
this.baseManager.reportUnstartedDraupnir(
|
||||
|
||||
@@ -14,12 +14,12 @@ import { IConfig } from "./config/config";
|
||||
import { Task } from "matrix-protection-suite";
|
||||
|
||||
/**
|
||||
* This file provides the entrypoint for the appservice mode for mjolnir.
|
||||
* This file provides the entrypoint for the appservice mode for draupnir.
|
||||
* A registration file can be generated `ts-node src/appservice/cli.ts -r -u "http://host.docker.internal:9000"`
|
||||
* and the appservice can be started with `ts-node src/appservice/cli -p 9000 -c your-confg.yaml`.
|
||||
*/
|
||||
const cli = new Cli({
|
||||
registrationPath: "mjolnir-registration.yaml",
|
||||
registrationPath: "draupnir-registration.yaml",
|
||||
bridgeConfig: {
|
||||
schema: {},
|
||||
affectsRegistration: false,
|
||||
|
||||
@@ -4,7 +4,7 @@ homeserver:
|
||||
# The url for the appservice to call the client server API from.
|
||||
url: http://localhost:8081
|
||||
|
||||
# Database configuration for storing which Mjolnirs have been provisioned.
|
||||
# Database configuration for storing which Draupnirs have been provisioned.
|
||||
db:
|
||||
engine: "postgres"
|
||||
connectionString: "postgres://mjolnir-tester:mjolnir-test@localhost:8083/mjolnir-test-db"
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface IConfig {
|
||||
webAPI: {
|
||||
port: number;
|
||||
};
|
||||
/** The admin room for the appservice bot. Not called managementRoom like mjolnir on purpose, so they're not mixed in code somehow. */
|
||||
/** The admin room for the appservice bot. Not called managementRoom like draupnir on purpose, so they're not mixed in code somehow. */
|
||||
adminRoom: string;
|
||||
/** configuration for matrix-appservice-bridge's Logger */
|
||||
logging?: LoggingOpts;
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface MjolnirRecord {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to persist mjolnirs that have been provisioned by the mjolnir manager.
|
||||
* Used to persist draupnirs that have been provisioned by the draupnir manager.
|
||||
*/
|
||||
export interface DataStore {
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ export interface DataStore {
|
||||
close(): Promise<void>;
|
||||
|
||||
/**
|
||||
* List all of the mjolnirs we have provisioned.
|
||||
* List all of the draupnirs we have provisioned.
|
||||
*/
|
||||
list(): Promise<MjolnirRecord[]>;
|
||||
|
||||
@@ -44,12 +44,12 @@ export interface DataStore {
|
||||
store(mjolnirRecord: MjolnirRecord): Promise<void>;
|
||||
|
||||
/**
|
||||
* @param owner The mxid of the user who provisioned this mjolnir.
|
||||
* @param owner The mxid of the user who provisioned this draupnir.
|
||||
*/
|
||||
lookupByOwner(owner: string): Promise<MjolnirRecord[]>;
|
||||
|
||||
/**
|
||||
* @param localPart the mxid of the provisioned mjolnir.
|
||||
* @param localPart the mxid of the provisioned draupnir.
|
||||
*/
|
||||
lookupByLocalPart(localPart: string): Promise<MjolnirRecord[]>;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ export const SynapseAdminHijackRoomCommand = describeCommand({
|
||||
!isAdmin.ok
|
||||
) {
|
||||
return ActionError.Result(
|
||||
"Either the command is disabled or Mjolnir is not running as homeserver administrator."
|
||||
"Either the command is disabled or Draupnir is not running as homeserver administrator."
|
||||
);
|
||||
}
|
||||
if (draupnir.synapseAdminClient === undefined) {
|
||||
|
||||
@@ -79,7 +79,7 @@ async function unbanUserFromRooms(
|
||||
await managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"Unban",
|
||||
`Attempted to unban ${member.userID} in ${revision.room.toRoomIDOrAlias()} but Mjolnir is running in no-op mode`,
|
||||
`Attempted to unban ${member.userID} in ${revision.room.toRoomIDOrAlias()} but Draupnir is running in no-op mode`,
|
||||
revision.room.toRoomIDOrAlias()
|
||||
);
|
||||
}
|
||||
|
||||
+9
-9
@@ -34,11 +34,11 @@ export interface IConfig {
|
||||
};
|
||||
dataPath: string;
|
||||
/**
|
||||
* If true, Mjolnir will only accept invites from users present in managementRoom.
|
||||
* If true, Draupnir will only accept invites from users present in managementRoom.
|
||||
* Otherwise a space must be provided to `acceptInvitesFromSpace`.
|
||||
*/
|
||||
autojoinOnlyIfManager: boolean;
|
||||
/** Mjolnir will accept invites from members of this space if `autojoinOnlyIfManager` is false. */
|
||||
/** Draupnir will accept invites from members of this space if `autojoinOnlyIfManager` is false. */
|
||||
acceptInvitesFromSpace: string | undefined;
|
||||
recordIgnoredInvites: boolean;
|
||||
managementRoom: string;
|
||||
@@ -270,14 +270,14 @@ export function read(): IConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a config for each newly provisioned mjolnir in appservice mode.
|
||||
* @param managementRoomId A room that has been created to serve as the mjolnir's management room for the owner.
|
||||
* @returns A config that can be directly used by the new mjolnir.
|
||||
* Provides a config for each newly provisioned draupnir in appservice mode.
|
||||
* @param managementRoomId A room that has been created to serve as the draupnir's management room for the owner.
|
||||
* @returns A config that can be directly used by the new draupnir.
|
||||
*/
|
||||
export function getProvisionedMjolnirConfig(managementRoomId: string): IConfig {
|
||||
// These are keys that are allowed to be configured for provisioned mjolnirs.
|
||||
// These are keys that are allowed to be configured for provisioned draupnirs.
|
||||
// We need a restricted set so that someone doesn't accidentally enable webservers etc
|
||||
// on every created Mjolnir, which would result in very confusing error messages.
|
||||
// on every created Draupnir, which would result in very confusing error messages.
|
||||
const allowedKeys = [
|
||||
"commands",
|
||||
"verboseLogging",
|
||||
@@ -290,14 +290,14 @@ export function getProvisionedMjolnirConfig(managementRoomId: string): IConfig {
|
||||
"backgroundDelayMS",
|
||||
"safeMode",
|
||||
];
|
||||
const configTemplate = read(); // we use the standard bot config as a template for every provisioned mjolnir.
|
||||
const configTemplate = read(); // we use the standard bot config as a template for every provisioned draupnir.
|
||||
const unusedKeys = Object.keys(configTemplate).filter(
|
||||
(key) => !allowedKeys.includes(key)
|
||||
);
|
||||
if (unusedKeys.length > 0) {
|
||||
LogService.warn(
|
||||
"config",
|
||||
"The config provided for provisioned mjolnirs contains keys which are not used by the appservice.",
|
||||
"The config provided for provisioned draupnirs contains keys which are not used by the appservice.",
|
||||
unusedKeys
|
||||
);
|
||||
}
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ void (async function () {
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`Failed to setup mjolnir from the config ${config.dataPath}: ${err}`
|
||||
`Failed to setup draupnir from the config ${config.dataPath}: ${err}`
|
||||
);
|
||||
await bot?.stopEverything();
|
||||
throw err;
|
||||
@@ -119,7 +119,7 @@ void (async function () {
|
||||
await bot.encryptionInitialized();
|
||||
healthz.isHealthy = true;
|
||||
} catch (err) {
|
||||
console.error(`Mjolnir failed to start: ${err}`);
|
||||
console.error(`Draupnir failed to start: ${err}`);
|
||||
await bot.stopEverything();
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ interface BanPropagationMessageContext {
|
||||
|
||||
/**
|
||||
* Prompt the management room to propagate a user ban to a policy list of their choice.
|
||||
* @param mjolnir Mjolnir.
|
||||
* @param mjolnir Draupnir.
|
||||
* @param event The ban event.
|
||||
* @param roomId The room that the ban happened in.
|
||||
* @returns An event id which can be used by the `PromptResponseListener`.
|
||||
|
||||
@@ -62,7 +62,7 @@ describeProtection<
|
||||
name: "BasicFloodingProtection",
|
||||
description: `If a user posts more than ${DEFAULT_MAX_PER_MINUTE} messages in 60s they'll be
|
||||
banned for spam. This does not publish the ban to any of your ban lists.
|
||||
This is a legacy protection from Mjolnir and contains bugs.`,
|
||||
This is a legacy protection from Draupnir and contains bugs.`,
|
||||
capabilityInterfaces: {
|
||||
userConsequences: "UserConsequences",
|
||||
eventConsequences: "EventConsequences",
|
||||
@@ -216,7 +216,7 @@ export class BasicFloodingProtection
|
||||
await this.draupnir.managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"BasicFlooding",
|
||||
`Tried to ban ${event["sender"]} in ${room.toRoomIDOrAlias()} but Mjolnir is running in no-op mode`,
|
||||
`Tried to ban ${event["sender"]} in ${room.toRoomIDOrAlias()} but Draupnir is running in no-op mode`,
|
||||
room.toRoomIDOrAlias()
|
||||
);
|
||||
}
|
||||
@@ -240,7 +240,7 @@ export class BasicFloodingProtection
|
||||
await this.draupnir.managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"BasicFlooding",
|
||||
`Tried to redact messages for ${event["sender"]} in ${room.toRoomIDOrAlias()} but Mjolnir is running in no-op mode`,
|
||||
`Tried to redact messages for ${event["sender"]} in ${room.toRoomIDOrAlias()} but Draupnir is running in no-op mode`,
|
||||
room.toRoomIDOrAlias()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ export class FirstMessageIsImageProtection
|
||||
await this.draupnir.managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"FirstMessageIsImage",
|
||||
`Tried to ban ${event["sender"]} in ${roomID} but Mjolnir is running in no-op mode`,
|
||||
`Tried to ban ${event["sender"]} in ${roomID} but Draupnir is running in no-op mode`,
|
||||
roomID
|
||||
);
|
||||
}
|
||||
@@ -172,7 +172,7 @@ export class FirstMessageIsImageProtection
|
||||
await this.draupnir.managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"FirstMessageIsImage",
|
||||
`Tried to redact ${event["event_id"]} in ${roomID} but Mjolnir is running in no-op mode`,
|
||||
`Tried to redact ${event["event_id"]} in ${roomID} but Draupnir is running in no-op mode`,
|
||||
roomID
|
||||
);
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ export class JoinWaveShortCircuitProtection
|
||||
await this.draupnir.managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"JoinWaveShortCircuit",
|
||||
`Tried to set ${roomID} to invite-only, but Mjolnir is running in no-op mode`,
|
||||
`Tried to set ${roomID} to invite-only, but Draupnir is running in no-op mode`,
|
||||
roomID
|
||||
);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export class MessageIsMediaProtection
|
||||
await this.draupnir.managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"MessageIsMedia",
|
||||
`Tried to redact ${event["event_id"]} in ${roomID} but Mjolnir is running in no-op mode`,
|
||||
`Tried to redact ${event["event_id"]} in ${roomID} but Draupnir is running in no-op mode`,
|
||||
roomID
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ export class MessageIsVoiceProtection
|
||||
await this.draupnir.managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"MessageIsVoice",
|
||||
`Tried to redact ${event["event_id"]} in ${roomID} but Mjolnir is running in no-op mode`,
|
||||
`Tried to redact ${event["event_id"]} in ${roomID} but Draupnir is running in no-op mode`,
|
||||
roomID
|
||||
);
|
||||
return Ok(undefined);
|
||||
|
||||
@@ -57,7 +57,7 @@ export class RedactUserInRoom implements QueuedRedaction {
|
||||
) {
|
||||
await managementRoom.logMessage(
|
||||
LogLevel.DEBUG,
|
||||
"Mjolnir",
|
||||
"Draupnir",
|
||||
`Redacting events from ${this.userID} in room ${this.roomID}.`
|
||||
);
|
||||
await redactUserMessagesIn(client, managementRoom, this.userID, [
|
||||
|
||||
@@ -30,8 +30,8 @@ export class ProtectedRoomActivityTracker {
|
||||
private activeRoomsCache: null | string[] = null;
|
||||
|
||||
/**
|
||||
* Inform the tracker that a new room is being protected by Mjolnir.
|
||||
* @param roomId The room Mjolnir is now protecting.
|
||||
* Inform the tracker that a new room is being protected by Draupnir.
|
||||
* @param roomId The room Draupnir is now protecting.
|
||||
*/
|
||||
public addProtectedRoom(roomId: string): void {
|
||||
this.protectedRoomActivities.set(roomId, /* epoch */ 0);
|
||||
@@ -39,8 +39,8 @@ export class ProtectedRoomActivityTracker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inform the trakcer that a room is no longer being protected by Mjolnir.
|
||||
* @param roomId The roomId that is no longer being protected by Mjolnir.
|
||||
* Inform the trakcer that a room is no longer being protected by Draupnir.
|
||||
* @param roomId The roomId that is no longer being protected by Draupnir.
|
||||
*/
|
||||
public removeProtectedRoom(roomId: string): void {
|
||||
this.protectedRoomActivities.delete(roomId);
|
||||
|
||||
@@ -56,7 +56,7 @@ export class UnlistedUserRedactionQueue {
|
||||
await draupnir.managementRoomOutput.logMessage(
|
||||
LogLevel.WARN,
|
||||
"AutomaticRedactionQueue",
|
||||
`Tried to redact ${permalink} but Mjolnir is running in no-op mode`
|
||||
`Tried to redact ${permalink} but Draupnir is running in no-op mode`
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -207,7 +207,7 @@ export class ReportManager {
|
||||
);
|
||||
if (originalEvent.sender !== this.draupnir.clientUserID) {
|
||||
// Let's not handle reactions to events we didn't send as
|
||||
// some setups have two or more Mjolnir's in the same management room.
|
||||
// some setups have two or more Draupnir's in the same management room.
|
||||
return;
|
||||
}
|
||||
if (!("content" in originalEvent)) {
|
||||
|
||||
@@ -199,7 +199,7 @@ export class ReportPoller {
|
||||
void Task(
|
||||
managementRoomOutput.logMessage(
|
||||
LogLevel.INFO,
|
||||
"Mjolnir@startup",
|
||||
"Draupnir@startup",
|
||||
"report poll setting does not exist yet"
|
||||
)
|
||||
);
|
||||
|
||||
+3
-3
@@ -139,7 +139,7 @@ export async function redactUserMessagesIn(
|
||||
await managementRoom.logMessage(
|
||||
LogLevel.WARN,
|
||||
"utils#redactUserMessagesIn",
|
||||
`Tried to redact ${victimEvent["event_id"]} in ${targetRoomId} but Mjolnir is running in no-op mode`,
|
||||
`Tried to redact ${victimEvent["event_id"]} in ${targetRoomId} but Draupnir is running in no-op mode`,
|
||||
targetRoomId
|
||||
);
|
||||
}
|
||||
@@ -474,7 +474,7 @@ function patchMatrixClientForRetry() {
|
||||
} else {
|
||||
if (attempt >= MAX_REQUEST_ATTEMPTS) {
|
||||
LogService.warn(
|
||||
"Mjolnir.client",
|
||||
"Draupnir.client",
|
||||
`Retried request ${params.method} ${params.uri} ${attempt} times, giving up.`
|
||||
);
|
||||
}
|
||||
@@ -500,7 +500,7 @@ function patchMatrixClientForRetry() {
|
||||
}
|
||||
}
|
||||
LogService.debug(
|
||||
"Mjolnir.client",
|
||||
"Draupnir.client",
|
||||
`Waiting ${retryAfterMs}ms before retrying ${params.method} ${params.uri}`
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, retryAfterMs));
|
||||
|
||||
@@ -19,7 +19,7 @@ interface Context extends Mocha.Context {
|
||||
appservice?: MjolnirAppService | undefined;
|
||||
}
|
||||
|
||||
describe("Test that the app service can provision a mjolnir on invite of the appservice bot", function () {
|
||||
describe("Test that the app service can provision a draupnir on invite of the appservice bot", function () {
|
||||
afterEach(function (this: Context) {
|
||||
this.moderator?.stop();
|
||||
if (this.appservice) {
|
||||
@@ -29,7 +29,7 @@ describe("Test that the app service can provision a mjolnir on invite of the app
|
||||
return Promise.resolve(); // TS7030: Not all code paths return a value.
|
||||
}
|
||||
});
|
||||
it("A moderator that requests a mjolnir via a matrix invitation will be invited to a new policy and management room", async function (this: Context) {
|
||||
it("A moderator that requests a draupnir via a matrix invitation will be invited to a new policy and management room", async function (this: Context) {
|
||||
const config = readTestConfig();
|
||||
this.appservice = await setupHarness();
|
||||
const appservice = this.appservice;
|
||||
@@ -38,7 +38,7 @@ describe("Test that the app service can provision a mjolnir on invite of the app
|
||||
name: { contains: "test" },
|
||||
});
|
||||
const roomWeWantProtecting = await moderator.createRoom();
|
||||
// have the moderator invite the appservice bot in order to request a new mjolnir
|
||||
// have the moderator invite the appservice bot in order to request a new draupnir
|
||||
this.moderator = moderator;
|
||||
const roomsInvitedTo: string[] = [];
|
||||
await new Promise((resolve) => {
|
||||
@@ -66,7 +66,7 @@ describe("Test that the app service can provision a mjolnir on invite of the app
|
||||
if (managementRoomId === undefined) {
|
||||
throw new TypeError(`Unable to find management room`);
|
||||
}
|
||||
// Check that the newly provisioned mjolnir is actually responsive.
|
||||
// Check that the newly provisioned draupnir is actually responsive.
|
||||
await getFirstReply(moderator, managementRoomId, () => {
|
||||
return moderator.sendMessage(managementRoomId, {
|
||||
body: `!draupnir status`,
|
||||
|
||||
@@ -24,7 +24,7 @@ interface Context extends Mocha.Context {
|
||||
moderator?: MatrixClient;
|
||||
}
|
||||
|
||||
describe("Test that the app service can provision a mjolnir when requested from the web API", function () {
|
||||
describe("Test that the app service can provision a draupnir when requested from the web API", function () {
|
||||
afterEach(function (this: Context) {
|
||||
this.moderator?.stop();
|
||||
if (this.appservice) {
|
||||
@@ -34,7 +34,7 @@ describe("Test that the app service can provision a mjolnir when requested from
|
||||
return Promise.resolve(); // TS7030: Not all code paths return a value.
|
||||
}
|
||||
});
|
||||
it("A moderator that requests a mjolnir via a matrix invitation will be invited to a new policy and management room", async function (this: Context) {
|
||||
it("A moderator that requests a draupnir via a matrix invitation will be invited to a new policy and management room", async function (this: Context) {
|
||||
const config = readTestConfig();
|
||||
this.appservice = await setupHarness();
|
||||
// create a moderator
|
||||
@@ -49,7 +49,7 @@ describe("Test that the app service can provision a mjolnir when requested from
|
||||
preset: "public_chat",
|
||||
});
|
||||
|
||||
// have the moderator invite the appservice bot in order to request a new mjolnir
|
||||
// have the moderator invite the appservice bot in order to request a new draupnir
|
||||
this.moderator = moderator;
|
||||
const roomsInvitedTo: string[] = [];
|
||||
const mjolnirDetails: CreateMjolnirResponse = await new Promise(
|
||||
@@ -77,7 +77,7 @@ describe("Test that the app service can provision a mjolnir when requested from
|
||||
if (managementRoomId !== mjolnirDetails.managementRoomId) {
|
||||
throw new TypeError(`Unable to find the management room`);
|
||||
}
|
||||
// Check that the newly provisioned mjolnir is actually responsive.
|
||||
// Check that the newly provisioned draupnir is actually responsive.
|
||||
const event = await getFirstReply(moderator, managementRoomId, () => {
|
||||
return moderator.sendMessage(managementRoomId, {
|
||||
body: `!draupnir status`,
|
||||
|
||||
@@ -31,7 +31,11 @@ export async function setupHarness(): Promise<MjolnirAppService> {
|
||||
name: { contains: "utility" },
|
||||
});
|
||||
await ensureAliasedRoomExists(utilityUser, config.adminRoom);
|
||||
return await MjolnirAppService.run(9000, config, "mjolnir-registration.yaml");
|
||||
return await MjolnirAppService.run(
|
||||
9000,
|
||||
config,
|
||||
"draupnir-registration.yaml"
|
||||
);
|
||||
}
|
||||
|
||||
export async function isPolicyRoom(
|
||||
|
||||
@@ -448,7 +448,7 @@ describe("Test: Reporting abuse", () => {
|
||||
const mjolnirRooms = new Set(await draupnir.client.getJoinedRooms());
|
||||
assert.ok(
|
||||
mjolnirRooms.has(roomId),
|
||||
"Mjölnir should be a member of the room"
|
||||
"Draupnir should be a member of the room"
|
||||
);
|
||||
|
||||
// Find the notice
|
||||
|
||||
@@ -118,7 +118,7 @@ export async function registerUser(
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
`Retried registration ${REGISTRATION_ATTEMPTS} times, is Mjolnir or Synapse misconfigured?`
|
||||
`Retried registration ${REGISTRATION_ATTEMPTS} times, is Draupnir or Synapse misconfigured?`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -218,10 +218,10 @@ export async function getFirstEventMatching(details: {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new banlist for mjolnir to watch and return the shortcode that can be used to refer to the list in future commands.
|
||||
* Create a new banlist for draupnir to watch and return the shortcode that can be used to refer to the list in future commands.
|
||||
* @param managementRoom The room to send the create command to.
|
||||
* @param mjolnir A syncing matrix client.
|
||||
* @param client A client that isn't mjolnir to send the message with, as you will be invited to the room.
|
||||
* @param client A client that isn't draupnir to send the message with, as you will be invited to the room.
|
||||
* @returns The shortcode for the list that can be used to refer to the list in future commands.
|
||||
*/
|
||||
export async function createBanList(
|
||||
@@ -236,7 +236,7 @@ export async function createBanList(
|
||||
async () => {
|
||||
return await client.sendMessage(managementRoom, {
|
||||
msgtype: "m.text",
|
||||
body: `!mjolnir list create ${listName} ${listName}`,
|
||||
body: `!draupnir list create ${listName} ${listName}`,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ describe("Test: The rooms commands", function () {
|
||||
});
|
||||
|
||||
it(
|
||||
"Mjolnir can protect a room, show that it is protected and then stop protecting the room.",
|
||||
"Draupnir can protect a room, show that it is protected and then stop protecting the room.",
|
||||
async function (this: RoomsTestContext) {
|
||||
// Create a few users and a room.
|
||||
const draupnir = this.draupnir;
|
||||
|
||||
@@ -26,7 +26,7 @@ describe("Test: shutdown command", function () {
|
||||
this.afterEach(async function () {
|
||||
client.stop();
|
||||
});
|
||||
it("Mjolnir asks synapse to shut down a channel", async function (
|
||||
it("Draupnir asks synapse to shut down a channel", async function (
|
||||
this: DraupnirTestContext
|
||||
) {
|
||||
this.timeout(20000);
|
||||
|
||||
@@ -25,11 +25,11 @@ import { MatrixRoomReference } from "@the-draupnir-project/matrix-basic-types";
|
||||
|
||||
patchMatrixClient();
|
||||
|
||||
// When Mjolnir starts (src/index.ts) it clobbers the config by resolving the management room
|
||||
// When Draupnir starts (src/index.ts) it clobbers the config by resolving the management room
|
||||
// alias specified in the config (config.managementRoom) and overwriting that with the room ID.
|
||||
// Unfortunately every piece of code importing that config imports the same instance, including
|
||||
// testing code, which is problematic when we want to create a fresh management room for each test.
|
||||
// So there is some code in here to "undo" the mutation after we stop Mjolnir syncing.
|
||||
// So there is some code in here to "undo" the mutation after we stop Draupnir syncing.
|
||||
export const mochaHooks = {
|
||||
beforeEach: [
|
||||
async function (this: DraupnirTestContext) {
|
||||
|
||||
@@ -25,7 +25,7 @@ describe("Test: !help command", function () {
|
||||
this.afterEach(async function () {
|
||||
client.stop();
|
||||
} as unknown as Mocha.AsyncFunc);
|
||||
it("Mjolnir responded to !mjolnir help", async function (
|
||||
it("Draupnir responded to !mjolnir help", async function (
|
||||
this: DraupnirTestContext
|
||||
) {
|
||||
this.timeout(30000);
|
||||
|
||||
@@ -122,7 +122,7 @@ let globalMjolnir: Draupnir | null;
|
||||
let globalSafeEmitter: SafeMatrixEmitter | undefined;
|
||||
|
||||
/**
|
||||
* Return a test instance of Mjolnir.
|
||||
* Return a test instance of Draupnir.
|
||||
*/
|
||||
export async function makeBotModeToggle(
|
||||
config: IConfig,
|
||||
@@ -186,7 +186,7 @@ export async function makeBotModeToggle(
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the alias and leave the room, can't be implicitly provided from the config because Mjolnir currently mutates it.
|
||||
* Remove the alias and leave the room, can't be implicitly provided from the config because Draupnir currently mutates it.
|
||||
* @param client The client to use to leave the room.
|
||||
* @param roomId The roomId of the room to leave.
|
||||
* @param alias The alias to remove from the room.
|
||||
|
||||
@@ -31,7 +31,7 @@ describe("Test: Report polling", function () {
|
||||
name: { contains: "protection-settings" },
|
||||
});
|
||||
});
|
||||
it("Mjolnir correctly retrieves a report from synapse", async function (
|
||||
it("Draupnir correctly retrieves a report from synapse", async function (
|
||||
this: DraupnirTestContext
|
||||
) {
|
||||
this.timeout(40000);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { strict as assert } from "assert";
|
||||
import { newTestUser } from "./clientHelper";
|
||||
import { getMessagesByUserIn } from "../../src/utils";
|
||||
|
||||
describe("Test: throttled users can function with Mjolnir.", function () {
|
||||
describe("Test: throttled users can function with Draupnir.", function () {
|
||||
it("throttled users survive being throttled by synapse", async function () {
|
||||
const throttledUser = await newTestUser(this.config.homeserverUrl, {
|
||||
name: { contains: "throttled" },
|
||||
@@ -48,7 +48,7 @@ describe("Test: throttled users can function with Mjolnir.", function () {
|
||||
});
|
||||
|
||||
/**
|
||||
* We used to have a test here that tested whether Mjolnir was going to carry out a redact order the default limits in a reasonable time scale.
|
||||
* We used to have a test here that tested whether Draupnir was going to carry out a redact order the default limits in a reasonable time scale.
|
||||
* Now I think that's never going to happen without writing a new algorithm for respecting rate limiting.
|
||||
* Which is not something there is time for.
|
||||
*
|
||||
@@ -59,5 +59,5 @@ describe("Test: throttled users can function with Mjolnir.", function () {
|
||||
*
|
||||
* https://github.com/matrix-org/mjolnir/commit/b850e4554c6cbc9456e23ab1a92ede547d044241
|
||||
*
|
||||
* Honestly I don't think we can expect anyone to be able to use Mjolnir under default rate limits.
|
||||
* Honestly I don't think we can expect anyone to be able to use Draupnir under default rate limits.
|
||||
*/
|
||||
@@ -15,7 +15,7 @@ import { getMessagesByUserIn } from "../../src/utils";
|
||||
import { TextMessageContent } from "matrix-protection-suite";
|
||||
|
||||
/**
|
||||
* Ensure that Mjolnir paginates only the necessary segment of the room timeline when backfilling.
|
||||
* Ensure that Draupnir paginates only the necessary segment of the room timeline when backfilling.
|
||||
*/
|
||||
describe("Test: timeline pagination", function () {
|
||||
it("does not paginate across the entire room history while backfilling.", async function () {
|
||||
|
||||
Reference in new issue
Block a user