|
|
@@ -113,6 +113,50 @@ verify_mail_runtime() {
|
|
|
return 1
|
|
|
}
|
|
|
|
|
|
+ docker compose exec -T app </dev/null node -e '
|
|
|
+ const tls = require("node:tls");
|
|
|
+
|
|
|
+ const socket = tls.connect({
|
|
|
+ host: "dovecot",
|
|
|
+ port: 31993,
|
|
|
+ servername: process.env.MAIL_HOSTNAME || "mailhub.local",
|
|
|
+ rejectUnauthorized: false
|
|
|
+ });
|
|
|
+ socket.setEncoding("utf8");
|
|
|
+
|
|
|
+ let buffer = "";
|
|
|
+ let finished = false;
|
|
|
+ let loginSent = false;
|
|
|
+ const timer = setTimeout(() => finish(false), 5000);
|
|
|
+
|
|
|
+ function finish(ok) {
|
|
|
+ if (finished) return;
|
|
|
+ finished = true;
|
|
|
+ clearTimeout(timer);
|
|
|
+ socket.destroy();
|
|
|
+ process.exit(ok ? 0 : 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ socket.on("data", (chunk) => {
|
|
|
+ buffer += chunk;
|
|
|
+ const lines = buffer.split(/\r?\n/).filter(Boolean);
|
|
|
+ if (!loginSent && lines.some((line) => /^\* OK\b/i.test(line))) {
|
|
|
+ loginSent = true;
|
|
|
+ socket.write("A1 LOGIN \"mailhub-healthcheck@invalid.invalid\" \"mailhub-healthcheck-invalid-password\"\r\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ const tagged = lines.find((line) => /^A1\b/i.test(line));
|
|
|
+ if (!tagged) return;
|
|
|
+ if (/temporary authentication failure|unavailable/i.test(tagged)) return finish(false);
|
|
|
+ finish(/\bNO\b/i.test(tagged) && /auth/i.test(tagged));
|
|
|
+ });
|
|
|
+ socket.on("error", () => finish(false));
|
|
|
+ socket.on("end", () => finish(false));
|
|
|
+ ' >/dev/null 2>&1 || {
|
|
|
+ echo "Dovecot IMAPS authentication path check failed." >&2
|
|
|
+ return 1
|
|
|
+ }
|
|
|
+
|
|
|
if ! docker compose exec -T --user 1000:1000 dovecot </dev/null sh -ec '
|
|
|
test -r /run/secrets/dovecot_auth_secret
|
|
|
test -s /run/secrets/dovecot_auth_secret
|