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:
Catalan Lover authored and GitHub committed 2024-10-04 20:32:10 +02:00
1 parent 39eb2984c5
commit 9cc64074e1
45 files changed
+156 -116

No files matched your search

+1 -1
View File
@@ -7,7 +7,7 @@ config/*
!config/default.yaml
# Draupnir test data
mjolnir-registration.yaml
draupnir-registration.yaml
test/harness/mjolnir-data/*
# Misc
+33
View File
@@ -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
View File
@@ -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"]
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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(
+1 -1
View File
@@ -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(
+2 -2
View File
@@ -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
View File
@@ -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;
}
+13 -10
View File
@@ -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");
}
/**
+9 -9
View File
@@ -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(
+2 -2
View File
@@ -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,
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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;
+4 -4
View File
@@ -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[]>;
}
+1 -1
View File
@@ -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) {
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+1 -1
View File
@@ -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`.
+3 -3
View File
@@ -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()
);
}
+2 -2
View File
@@ -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
);
}
+1 -1
View File
@@ -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
);
}
+1 -1
View File
@@ -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
);
}
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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, [
+4 -4
View File
@@ -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);
+1 -1
View File
@@ -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) {
+1 -1
View File
@@ -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)) {
+1 -1
View File
@@ -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
View File
@@ -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));
+4 -4
View File
@@ -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`,
+4 -4
View File
@@ -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`,
+5 -1
View File
@@ -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(
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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?`
);
}
+3 -3
View File
@@ -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}`,
});
}
);
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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) {
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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);
+3 -3
View File
@@ -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.
*/
+1 -1
View File
@@ -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 () {