feat: Phisherman integration

This commit is contained in:
Dragory 2021-10-31 17:17:31 +02:00
parent f92ee9ba4f
commit 13c94a81cc
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
18 changed files with 681 additions and 17 deletions

View file

@ -0,0 +1,49 @@
import { PluginOptions, typedGuildCommand } from "knub";
import { GuildPingableRoles } from "../../data/GuildPingableRoles";
import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
import { ConfigSchema, PhishermanPluginType } from "./types";
import {
getPhishermanDomainInfo,
hasPhishermanMasterAPIKey,
phishermanApiKeyIsValid,
reportTrackedDomainsToPhisherman,
} from "../../data/Phisherman";
import { mapToPublicFn } from "../../pluginUtils";
import { getDomainInfo } from "./functions/getDomainInfo";
import { pluginInfo } from "./info";
const defaultOptions: PluginOptions<PhishermanPluginType> = {
config: {
api_key: null,
},
overrides: [],
};
export const PhishermanPlugin = zeppelinGuildPlugin<PhishermanPluginType>()({
name: "phisherman",
showInDocs: true,
info: pluginInfo,
configSchema: ConfigSchema,
defaultOptions,
// prettier-ignore
public: {
getDomainInfo: mapToPublicFn(getDomainInfo),
},
async beforeLoad(pluginData) {
pluginData.state.validApiKey = null;
if (!hasPhishermanMasterAPIKey()) {
// tslint:disable-next-line:no-console
console.warn("Could not load Phisherman plugin: master API key is missing");
return;
}
const apiKey = pluginData.config.get().api_key;
if (apiKey && (await phishermanApiKeyIsValid(apiKey).catch(() => false))) {
pluginData.state.validApiKey = apiKey;
}
},
});

View file

@ -0,0 +1,20 @@
import { GuildPluginData } from "knub";
import { PhishermanPluginType } from "../types";
import { PhishermanDomainInfo } from "../../../data/types/phisherman";
import { getPhishermanDomainInfo, phishermanDomainIsSafe, trackPhishermanCaughtDomain } from "../../../data/Phisherman";
export async function getDomainInfo(
pluginData: GuildPluginData<PhishermanPluginType>,
domain: string,
): Promise<PhishermanDomainInfo | null> {
if (!pluginData.state.validApiKey) {
return null;
}
const info = await getPhishermanDomainInfo(domain).catch(() => null);
if (info != null && !phishermanDomainIsSafe(info)) {
trackPhishermanCaughtDomain(pluginData.state.validApiKey, domain);
}
return info;
}

View file

@ -0,0 +1,41 @@
import { trimPluginDescription } from "../../utils";
import { ZeppelinGuildPluginBlueprint } from "../ZeppelinPluginBlueprint";
export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = {
prettyName: "Phisherman",
description: trimPluginDescription(`
Match scam/phishing links using the Phisherman API. See https://phisherman.gg/ for more details!
`),
configurationGuide: trimPluginDescription(`
### Getting started
To get started, request an API key for Phisherman following the instructions at https://docs.phisherman.gg/#/api/getting-started?id=requesting-api-access.
Then, add the api key to the plugin's config:
~~~yml
phisherman:
config:
api_key: "your key here"
~~~
### Note
When using Phisherman features in Zeppelin, Zeppelin reports statistics about checked links back to Phisherman. This only includes the domain (e.g. zeppelin.gg), not the full link.
### Usage with Automod
Once you have configured the Phisherman plugin, you are ready to use it with automod. Currently, Phisherman is available as an option in the \`match_links\` plugin:
~~~yml
automod:
config:
rules:
# Clean any scam links detected by Phisherman
filter_scam_links:
triggers:
- match_links:
phisherman:
include_suspected: true # It's recommended to keep this enabled to catch new scam domains quickly
include_verified: true
actions:
clean: true
~~~
`),
};

View file

@ -0,0 +1,16 @@
import * as t from "io-ts";
import { BasePluginType } from "knub";
import { tNullable } from "../../utils";
export const ConfigSchema = t.type({
api_key: tNullable(t.string),
});
export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export interface PhishermanPluginType extends BasePluginType {
config: TConfigSchema;
state: {
validApiKey: string | null;
};
}