Valithor's official webserver for BYOND user verification.
Verifier-Server is a web server designed to handle BYOND user verification.
- Handles GET and POST requests for user verification.
- Supports both filesystem and SQL (SQLite/MySQL) storage.
- Configurable via
.envfile. - Logger mode for detailed request and response logging.
- Graceful shutdown support on all systems with ReactPHP.
- Optional Discord (
/dwa) and Space Station 14 (/ss14wa) OAuth2 login endpoints with cookie-based browser sessions and non-blocking provider calls. - A legacy stream-socket mode (
init(null, true)) remains for compatibility but is deprecated: it reads 1 KiB per request, cannot parse form bodies and does not serve the OAuth2 endpoints.
-
Clone the repository:
git clone https://github.com/Valgorithms/Verifier-server.git cd Verifier-server -
Install dependencies (PHP 8.2 or newer):
composer install
-
Create and configure the
.envfile:cp example.env .env
Edit the
.envfile to match your configuration:HOST_ADDR=127.0.0.1 HOST_PORT=8080 TOKEN=changeme STORAGE_TYPE=filesystem JSON_PATH=json/verify.json # SQLite configuration #DB_DSN=sqlite:verify.db #DB_USERNAME= #DB_PASSWORD= #DB_OPTIONS= # MySQL configuration #DB_DSN=mysql:host=127.0.0.1;port=3306;dbname=verify_list #DB_PORT=3306 #DB_USERNAME=your_username #DB_PASSWORD=your_password #DB_OPTIONS={"option1":"value1","option2":"value2"}
The
.envfile lives in the repository root regardless of the working directory; variables set in the real environment take precedence over it. The OAuth2 web endpoints (SS14_OAUTH2_CLIENT_ID/SECRET,dwa_client_id/dwa_client_secret) are optional and only registered when both halves are set.
-
Start the server:
php run.php
-
The server will listen on the address and port specified in the
.envfile.
GET /verified: Retrieve the list of verified users.POST /verified: Add or delete a verified user. Requires a valid token.GET /ss14verifiedandPOST /ss14verified: the same contract for Space Station 14 accounts, with anss14field instead ofckey.
A trailing slash is accepted (/verified/), and / is an alias of /verified.
This is the contract Civilizationbot
relies on for approveme; keep it backward compatible.
[{"discord": "123456789012345678", "ss13": "alice", "create_time": "2026-01-01 12:00:00"}]Each record links exactly one Discord user id to one BYOND ckey. A ckey is
stored in its normalised form: lowercased, with ., _, -, + and spaces
removed, which is how BYOND and the bot compare keys.
Body: application/x-www-form-urlencoded (the legacy Field: value header
form is still accepted for in-process callers). Fields:
| Field | Required | Meaning |
|---|---|---|
token |
yes | Must equal the configured TOKEN. |
discord |
insert | Discord user id, 17 to 20 digits. |
ckey |
insert | BYOND key, normalised before storage. |
method |
no | delete removes the record matching ckey, else discord. Anything else inserts. |
Status codes:
| Status | Meaning |
|---|---|
| 200 | Inserted (body: the full list) or deleted (body: the removed records). |
| 400 | discord or ckey is malformed. Nothing was stored. |
| 401 | Missing or wrong token, or the server still uses the default token. |
| 403 | The Discord id or the (normalised) ckey is already registered. |
| 404 | delete found no matching record. |
| 405 | Unsupported HTTP method. |
Returns the full list as JSON. There is no read token; do not host the server on a public interface unless that is intended.
/dwa (Discord) and /ss14wa (Space Station 14) run the authorization-code
flow for a browser: ?login redirects to the provider, the provider returns
to ?code=…&state=…, ?user returns the cached profile as JSON, ?remove
revokes the token and ?logout forgets the session.
The browser is identified by the verifier_session cookie (random id,
HttpOnly, SameSite=Lax, 24 h idle expiry), which both endpoints share so one
browser's Discord and SS14 logins are stored under the same key:
Server::getSessions()[<endpoint>][<session id>]. Nothing is keyed by client
IP. Provider calls use ReactPHP's Browser with a 10 s timeout and never
block the event loop; the in-process handleEndpoint() adapter serves only
requests that need no provider round trip and answers 503 otherwise.
To run the tests, execute the following command:
php runtests.phpTo get the list of verified users, run the following script:
./scripts/get_verified.shTo insert a new ss13 and discord record, run the following script:
./scripts/post_verified.shThis project is licensed under the MIT License.
Run php scripts/lint.php to parse all package source, entry points, scripts, and tests.
CI checks PHP 8.2, 8.3, 8.4, and 8.5.
Run php vendor/bin/phpunit --bootstrap vendor/autoload.php tests/isolated.
These contract tests inject storage that never writes files or opens databases;
they do not load .env, bind a listening socket, or contact verification services.
A server loading test constructs the server and routes a synthetic request without
initializing its network listener.
The older tests outside this directory use configured storage and are not run by CI.
Run php -d xdebug.mode=off scripts/benchmark_lookups.php for a synthetic
lookup comparison. It uses in-memory lists and performs no persistence or HTTP.
Lookup columns are cached until the list changes, preserving existing loose
comparison semantics and original row keys. A snapshot and columns consume
additional memory; database reads still follow the configured storage behavior.
Verification HTTP requests accept application/x-www-form-urlencoded bodies.
Body fields override corresponding legacy headers. Internal header-string calls
remain supported. Successful registrations explicitly return HTTP 200.