mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04:00
223 lines
6.7 KiB
TypeScript
223 lines
6.7 KiB
TypeScript
/**
|
|
* A format of messages designed to allow communication with a configurable
|
|
* spamchecker designed around the Synapse Spamcheck API.
|
|
*
|
|
* - We call an implementation of the Synapse Spamcheck API that supports this
|
|
* protocol a *Checker*.
|
|
* - The Checker is configured to receive instructions in a set of rooms
|
|
* Room1, Room2, ... RoomN. This set of rooms does not change during the
|
|
* lifetime of the Checker.
|
|
* - Any member of Room1, ..., RoomN with authorization to send messages
|
|
* (aka a *Controller*) can send instructions to the Checker. We expect
|
|
* that the Controller will be an implementation of Mjölnir or Carlotta.
|
|
*
|
|
* A the time of this writing, the Checker supports only simple rules.
|
|
*
|
|
* - A number of string properties are exposed to rules.
|
|
* - A rule is a string property and a literal/regexp.
|
|
* - During execution, if the regexp appears in the value of the string
|
|
* property, the message/user account creation request is rejected.
|
|
* - Otherwise, it is accepted.
|
|
*/
|
|
|
|
/**
|
|
* ------------------- Messages from controller ----------------------
|
|
*/
|
|
|
|
type MessageFromControllerContent = {
|
|
type: "org.matrix.spamcheck.control",
|
|
content:
|
|
/// Update matchers on a single property.
|
|
StringRuleUpdate | ObjectRuleUpdate
|
|
/// Reset the Checker to remove all rules.
|
|
| ClearEverything
|
|
/// Request a snapshot of the current list of rules from the Checker.
|
|
| ShowMeTheseRules
|
|
};
|
|
|
|
/**
|
|
* ---------------- Properties that the Checker can match against -------
|
|
*/
|
|
|
|
enum StringProperty {
|
|
/// The following properties point to strings.
|
|
"org.matrix.spamcheck.user_may_invite.inviter_user_id",
|
|
"org.matrix.spamcheck.user_may_invite.new_member_user_id",
|
|
"org.matrix.spamcheck.user_may_invite.room_id",
|
|
"org.matrix.spamcheck.user_may_create_room.user_id",
|
|
"org.matrix.spamcheck.user_may_create_room_alias.user_id",
|
|
"org.matrix.spamcheck.user_may_create_room_alias.desired_alias",
|
|
"org.matrix.spamcheck.user_may_publish_room.publisher_user_id",
|
|
"org.matrix.spamcheck.user_may_publish_room.room_id",
|
|
"org.matrix.spamcheck.check_username_for_spam.user_id",
|
|
"org.matrix.spamcheck.check_username_for_spam.display_name",
|
|
"org.matrix.spamcheck.check_username_for_spam.avatar_url",
|
|
"org.matrix.spamcheck.check_registration_for_spam_deny.maybe_user_name",
|
|
"org.matrix.spamcheck.check_registration_for_spam_deny.maybe_email",
|
|
"org.matrix.spamcheck.check_registration_for_spam_deny.user_agent",
|
|
"org.matrix.spamcheck.check_registration_for_spam_deny.ip",
|
|
"org.matrix.spamcheck.check_registration_for_spam_deny.maybe_auth_provider_id",
|
|
"org.matrix.spamcheck.check_registration_for_spam_shadowban.maybe_user_name",
|
|
"org.matrix.spamcheck.check_registration_for_spam_shadowban.maybe_email",
|
|
"org.matrix.spamcheck.check_registration_for_spam_shadowban.user_agent",
|
|
"org.matrix.spamcheck.check_registration_for_spam_shadowban.ip",
|
|
"org.matrix.spamcheck.check_registration_for_spam_shadowban.maybe_auth_provider_id",
|
|
}
|
|
|
|
enum ObjectProperty {
|
|
/// The following properties point to objects.
|
|
"org.matrix.spamcheck.check_event_for_spam.event",
|
|
}
|
|
|
|
/**
|
|
* ---------------- Checker Matching primitives -------
|
|
*/
|
|
|
|
type Matcher =
|
|
/// Matching against a literal string.
|
|
///
|
|
/// If the string property contains this literal string, the rule **matches**
|
|
/// i.e. the spamcheck will **reject** the operation. Matches are case-insensitive.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// If literal `hailhydra` is a matcher for string property
|
|
/// `org.matrix.spamcheck.check_registration_for_spam_deny.maybe_user_name`,
|
|
/// user won't be able to register an account with the name 'hailHydra'.
|
|
{ literal: string }
|
|
|
|
/// Matching against a regexp.
|
|
///
|
|
/// If the string property is matched by this regexp, the rule **matches**
|
|
/// i.e. the spamcheck will **reject** the operation. Matches are case-insensitive.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// If regexp `h[ae]il.*hydra` is a matcher for string property
|
|
/// `org.matrix.spamcheck.check_registration_for_spam_deny.maybe_user_name`,
|
|
/// user won't be able to register an account with the name 'hEil hYdra'.
|
|
| { regexp: string }
|
|
|
|
/**
|
|
* ------------------- Snapshot of rules ----------------------
|
|
*/
|
|
|
|
/**
|
|
* The current matchers on a property that points to an object.
|
|
*/
|
|
type StringPropertyMatchers = {
|
|
property: StringProperty,
|
|
matchers: Matcher[],
|
|
}
|
|
|
|
/**
|
|
* The current matchers on a property that points to an object.
|
|
*/
|
|
type ObjectPropertyMatchers = {
|
|
property: ObjectProperty,
|
|
matchers: {
|
|
[path: string]: Matcher[]
|
|
},
|
|
}
|
|
|
|
/**
|
|
* A list of rules we wish to see.
|
|
*/
|
|
type RuleToShow =
|
|
/// All the matchers for a StringProperty.
|
|
StringProperty
|
|
/// All the matchers for a single path in a ObjectProperty.
|
|
| {
|
|
property: ObjectProperty,
|
|
path: string
|
|
}
|
|
/// All the matchers for all the paths in an ObjectProperty.
|
|
| ObjectProperty;
|
|
|
|
/**
|
|
* Show current rules.
|
|
*/
|
|
type ShowMeTheseRules = {
|
|
"org.matrix.spamcheck.action": "snapshot",
|
|
|
|
/// The list of rules to show:
|
|
///
|
|
/// `*` for all rules
|
|
property: RuleToShow[] | "*";
|
|
}
|
|
|
|
/**
|
|
* A message with a snapshot of rules, as requested per `ShowMeTheseRules`.
|
|
*/
|
|
type RuleSnapshotMessage = {
|
|
type: "org.matrix.spamcheck.snapshot",
|
|
content: {
|
|
dump: (StringPropertyMatchers | ObjectPropertyMatchers)[]
|
|
}
|
|
}
|
|
|
|
|
|
const MESSAGE_RULE_DUMP_TYPE = "org.matrix.spamcheck.dump";
|
|
/**
|
|
* ------------------- Updating rules ----------------------
|
|
*/
|
|
|
|
/// A list of additions/removal.
|
|
///
|
|
/// Resolved in the following order:
|
|
///
|
|
/// 1. remove;
|
|
/// 2. add;
|
|
type Patch = {
|
|
/// Remove some or all items.
|
|
remove?: "org.matrix.spamcheck.clear" | Matcher[],
|
|
|
|
/// Add items.
|
|
add?: Matcher[],
|
|
}
|
|
|
|
|
|
/**
|
|
* An update to a single rule, for a property that points to a string.
|
|
*/
|
|
type StringRuleUpdate = {
|
|
"org.matrix.spamcheck.action": "update",
|
|
|
|
/// The property affected by this rule change.
|
|
property: StringProperty,
|
|
|
|
/// Matchers to add/remove.
|
|
patch: Patch,
|
|
}
|
|
|
|
/**
|
|
* An update to a single rule, for a property that points to an object.
|
|
*/
|
|
type ObjectRuleUpdate = {
|
|
"org.matrix.spamcheck.action": "update",
|
|
|
|
/// The property affected by this rule change.
|
|
///
|
|
/// This property points to an object `o`.
|
|
property: ObjectProperty,
|
|
|
|
/// The path to follow within object `o` to access
|
|
/// a string value.
|
|
///
|
|
/// If the path is not defined or the value is not
|
|
/// a string, the message is considered a non-match,
|
|
/// i.e. it can pass.
|
|
path: string,
|
|
|
|
/// Matchers to add/remove.
|
|
patch: Patch,
|
|
}
|
|
|
|
|
|
/**
|
|
* Remove all the rules.
|
|
*/
|
|
type ClearEverything = {
|
|
"org.matrix.spamcheck.action": "clear",
|
|
}
|