redis()->hGet('DKIM_PUB_KEYS', $domain); if (!is_string($pubkey) || $pubkey === '') { return null; } $selector = (string)$this->redis()->hGet('DKIM_SELECTORS', $domain); return ['selector' => $selector, 'pubkey' => $pubkey, 'privkey' => (string)$this->redis()->hGet('DKIM_PRIV_KEYS', $selector . '.' . $domain)]; } /** Stores a DKIM key like dkim('import') does */ public function addDkim(string $domain, string $selector, string $pubkey, string $privkey): void { $this->redis()->hSet('DKIM_PUB_KEYS', $domain, $pubkey); $this->redis()->hSet('DKIM_SELECTORS', $domain, $selector); $this->redis()->hSet('DKIM_PRIV_KEYS', $selector . '.' . $domain, $privkey); } /** * @param string[] $objects domains or mailboxes * @return array object => rate limit ("10 / 1h") of those with one */ public function rateLimits(array $objects): array { if (empty($objects)) { return []; } $values = $this->redis()->hMGet('RL_VALUE', array_values($objects)); return array_filter(is_array($values) ? $values : [], fn(mixed $value): bool => is_string($value) && $value !== ''); } public function setRateLimit(string $object, string $value): void { $this->redis()->hSet('RL_VALUE', $object, $value); } /** The domain is local for rspamd (legacy domain and alias domain add) */ public function addDomainMap(string $domain): void { $this->redis()->hSet('DOMAIN_MAP', $domain, 1); } /** * SOGo reads its domains at start: restart it after a domain was added (like the "restart SOGo" option of the form) * * @return ?string null on success, else the error of dockerapi */ public function restartSogo(): ?string { $result = json_decode((string)$this->dockerRestart('sogo-mailcow'), true); return (($result['type'] ?? '') === 'success') ? null : (string)($result['msg'] ?? 'dockerapi did not answer'); } protected function redis(): Redis { return $this->redis ?? throw new RuntimeException('Redis is not connected'); } protected function dockerRestart(string $service): mixed { return docker('post', $service, 'restart'); } }