keys = $keys; $this->connections = $connections; $this->service = $service; $this->preview = $preview; } public function register(): void { $this->route('/keys', 'GET', fn () => array_map([KeyRepository::class, 'to_api'], $this->keys->all())); $this->route('/keys', 'POST', function (\WP_REST_Request $r) { $made = $this->keys->create((string) $r->get_param('label'), (string) $r->get_param('permission'), KeyRepository::expires_at($r->get_param('expires')), !empty($r->get_param('one_time'))); return new \WP_REST_Response([ 'key' => KeyRepository::to_api($made['key']), 'connection_string' => ConnectionString::encode(home_url(), $made['key']['id'], $made['secret']), ], 201); }); $this->route('/keys/(?P[a-z0-9]{12})', 'DELETE', function (\WP_REST_Request $r) { $this->keys->revoke($r['id']); return ['revoked' => true]; }); $this->route('/mode', 'GET', fn () => SiteMode::to_api()); $this->route('/mode', 'POST', function (\WP_REST_Request $r) { if ($r->get_param('mode') !== null) { SiteMode::set((string) $r->get_param('mode')); } if ($r->get_param('auto_lock') !== null) { SiteMode::set_auto_lock((bool) $r->get_param('auto_lock')); } return SiteMode::to_api(); }); $this->route('/connections', 'GET', fn () => array_map([ConnectionRepository::class, 'to_api'], $this->connections->all())); $this->route('/connections', 'POST', function (\WP_REST_Request $r) { $basic = is_array($r->get_param('basic_auth')) ? $r->get_param('basic_auth') : null; $made = $this->service->connect((string) $r->get_param('connection_string'), (string) $r->get_param('label'), !empty($r->get_param('allow_insecure')), $basic); return new \WP_REST_Response(['connection' => ConnectionRepository::to_api($made['connection'])] + $made, 201); }); $this->route('/connections/(?P[0-9a-f-]{36})', 'POST', function (\WP_REST_Request $r) { $basic = is_array($r->get_param('basic_auth')) ? $r->get_param('basic_auth') : null; return ConnectionRepository::to_api($this->connections->set_basic_auth($r['id'], $basic)); }); $this->route('/connections/(?P[0-9a-f-]{36})', 'DELETE', function (\WP_REST_Request $r) { $this->connections->delete($r['id']); return ['deleted' => true]; }); $this->route('/connections/(?P[0-9a-f-]{36})/describe', 'POST', fn (\WP_REST_Request $r) => ['connection' => ConnectionRepository::to_api($this->connections->get($r['id']))] + $this->service->describe($this->connections->get($r['id']), (int) $r->get_param('subsite'))); // Who joins a network before a pull or push into one of its subsites (spec 2026-10-16 ยง5.5). $this->route('/connections/(?P[0-9a-f-]{36})/users-preview', 'POST', function (\WP_REST_Request $r) { $connection = $this->connections->get($r['id']); return $r->get_param('direction') === 'push' ? $this->preview->push($connection, (int) $r->get_param('subsite'), (int) $r->get_param('remote_subsite'), is_array($r->get_param('remote_new_subsite')) ? $r->get_param('remote_new_subsite') : null) : $this->preview->pull($connection, (int) $r->get_param('subsite'), (int) $r->get_param('remote_subsite')); }); } }