# anope21-contrib Custom third-party modules for [Anope IRC Services **2.1**](https://www.anope.org/) by Jean "reverse" Chevronnet. | Module | Purpose | | ------ | ------- | | [`m_apiauth`](#m_apiauth) | Authenticate users against an external HTTP API instead of the internal Anope database, with optional SASL SCRAM-SHA-256/512 support. | | [`m_nickserv_oauth`](#m_nickserv_oauth) | Adds `NickServ IDENTIFYOAUTH` for JWT/OAuth token login (used by web chat clients). | | [`m_youtube`](#m_youtube) | BotServ reads YouTube links posted in channels and replies with video details. | > These are **contrib** modules — they are not part of the Anope core and are > not supported by the Anope team. Test on a staging network before deploying. --- ## Building & installing Anope 2.1 builds third-party modules from `modules/third/`. Drop the `.cpp` files there (or symlink this repo), then configure and build: ```bash # from your Anope source tree cp /path/to/anope21-contrib/*.cpp modules/third/ ./Config # regenerate the build cd build make -j$(nproc) make install ``` Each module declares its own build/link requirements at the top of the source file (parsed by Anope's CMake glue). Install the dependencies below **before** building, or the affected module will be skipped: | Module | Build dependencies | | ------ | ------------------ | | `m_apiauth` | OpenSSL (`libssl`/`libcrypto`), libcurl, [`nlohmann/json`](https://github.com/nlohmann/json), [`jwt-cpp`](https://github.com/Thalhammer/jwt-cpp) | | `m_nickserv_oauth` | OpenSSL (`libssl`/`libcrypto`), [`jwt-cpp`](https://github.com/Thalhammer/jwt-cpp) | | `m_youtube` | libcurl, OpenSSL, [`yyjson`](https://github.com/ibireme/yyjson) | On Debian/Ubuntu the system packages are roughly: ```bash sudo apt install libssl-dev libcurl4-openssl-dev nlohmann-json3-dev # jwt-cpp and yyjson are header/lib-only; install from source or your package manager ``` After installing, load and configure each module in your Anope configuration (typically `modules.conf` / your services config). Every example below is a `module { ... }` block — add it and `/msg OperServ RELOAD` (or restart) to apply. --- ## m_apiauth Delegates NickServ authentication to an external HTTP API. When a user identifies, Anope POSTs (or GETs) the credentials to your endpoint; a `2xx` response authenticates the user. Optionally validates JWTs returned by the API and provides SASL **SCRAM-SHA-256** / **SCRAM-SHA-512** mechanisms. ```ini module { name = "m_apiauth" # ── External auth endpoint ─────────────────────────────── api_url = "https://accounts.example.com/api/login_token/" api_method = "POST" # POST (default) or GET api_username_param = "username" # form field carrying the nick api_password_param = "password" # form field carrying the password api_email_field = "email" # JSON field to read the email back from api_key = "changeme-shared-secret" # sent to the API; keep secret # ── TLS verification for the API call ──────────────────── verify_ssl = "true" # "true"/"false" #capath = "/etc/ssl/certs" # optional CA directory #cainfo = "/etc/ssl/cert.pem" # optional CA bundle file # ── Optional JWT validation of the API response ────────── # Leave jwt_secret empty to skip signature verification. jwt_secret = "your-hmac-signing-secret" jwt_issuer = "accounts.example.com" # ── User-facing URLs shown in replies ──────────────────── profile_url = "https://accounts.example.com/profile/%s/" # %s = account register_url = "https://accounts.example.com/register/" # ── Redirect built-in commands to the web app (optional) ─ # If set, these NickServ commands are blocked with the given reason. disable_reason = "Please register on the website: https://accounts.example.com/register/" disable_email_reason = "Change your email address on the website instead." # ── Optional group/role sync endpoint ──────────────────── #group_api_url = "https://accounts.example.com/api/groups/" # ── SASL SCRAM mechanisms (optional) ───────────────────── enable_sasl_scram_sha256 = "yes" # advertise SCRAM-SHA-256 (default yes) enable_sasl_scram_sha512 = "no" # advertise SCRAM-SHA-512 (default no) scram_iterations = "4096" # PBKDF2 iteration count scram_saltlen = "16" # salt length in bytes #scram_debug = "no" # verbose SASL logging #scram_attr_b64_nopad = "no" # base64 without padding for SCRAM attrs } ``` **Notes** - `api_key` and `jwt_secret` are secrets — do not commit real values. - The API must accept the configured `api_method` and return `2xx` on success. - `%s` in `profile_url` is replaced with the account name. - SCRAM verifiers are stored per-account; enabling SCRAM requires the API/flow to provision them. --- ## m_nickserv_oauth Adds the `IDENTIFYOAUTH` command to NickServ, letting a user identify with a JWT bearer token instead of a password. Intended to be driven automatically by a web chat client after the user logs into your web app. ```ini module { name = "m_nickserv_oauth" # HMAC secret used to verify the JWT signature (HS256). # If left empty, signature verification is DISABLED (not recommended). jwt_secret = "your-hmac-signing-secret" # Expected "iss" claim. Only enforced when both this and the token set it. jwt_issuer = "accounts.example.com" } ``` **Usage** ``` /msg NickServ IDENTIFYOAUTH YourNick eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` The token's `sub` / `name` / `username` claim must match the requested account, and the token must not be expired (`exp`). Tip: share the same `jwt_secret` and `jwt_issuer` here and in `m_apiauth` so one signing key covers both flows. --- ## m_youtube A BotServ add-on: when a channel bot sees a YouTube link, it fetches the video details from the YouTube Data API v3 and posts a formatted reply. Includes an anti-spam throttle and a persistent cache. ```ini module { name = "m_youtube" # YouTube Data API v3 key (required). youtube_api_key = "AIza...your-key..." # ── Reply formatting ───────────────────────────────────── prefix = "\x02\x03""01,00You\x03""00,04Tube\x0F\x02" # colored "YouTube" tag duration_text = "Duration: " seen_text = "Seen: " times_text = " times." #response_format = "" # optional custom format string # ── Anti-spam (per channel) ────────────────────────────── spam_limit = "3" # max links... spam_window = "60" # ...per this many seconds spam_kick = "yes" # kick offenders? spam_kick_reason = "YouTube link spam" cache_ttl = "300" # video-info cache lifetime (seconds) } ``` **Commands** (require the `SAY` channel privilege or `botserv/administration`): | Command | Description | | ------- | ----------- | | `BotServ youtube` | Handle/announce a YouTube link. | | `BotServ ytstats` | Show module usage statistics. | **Notes** - Get an API key from the [Google Cloud Console](https://console.cloud.google.com/) with the **YouTube Data API v3** enabled. - The cache is persisted to `m_youtube.module.json` in the Anope data directory. - Assign the BotServ bot to a channel (`/msg BotServ ASSIGN #chan Bot`) for link detection to work there. --- ## License Unless a source file states otherwise, these modules are distributed under the **GNU General Public License**. See the header of each `.cpp` file for details.