"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = logout; const tools_js_1 = require("../tools.js"); // How long to wait for the server to answer LOGOUT before closing the socket anyway. Without a // bound of its own, an unanswered LOGOUT kept logout() pending until the socket timeout. const LOGOUT_TIMEOUT = 10 * 1000; /** * Logs out the user and closes the connection. * * @param connection - IMAP connection instance * @returns True if logout command succeeded, false otherwise */ async function logout(connection) { if (connection.state === connection.states.LOGOUT) { // nothing to do here return false; } if (connection.state === connection.states.NOT_AUTHENTICATED) { // Not yet authenticated, no LOGOUT command needed; just close the socket. connection.state = connection.states.LOGOUT; connection.close(); return false; } let response; // close() rejects the pending LOGOUT with NoConnection, which counts as a completed logout let timer = setTimeout(() => connection.close(), LOGOUT_TIMEOUT); try { response = await connection.exec('LOGOUT'); return true; } catch (err) { // If the connection is already gone, treat as successful logout if (err.code === 'NoConnection') { return true; } connection.log.warn({ err, cid: connection.id }); return false; /* c8 ignore next */ // the catch above is exhaustive (never re-throws), so finally is only ever reached via normal completion } finally { // Set state to LOGOUT before closing to prevent any further commands from // being queued. The socket is closed unconditionally in this finally block // regardless of whether the LOGOUT command succeeded or failed. (0, tools_js_1.clearTimer)(timer); connection.state = connection.states.LOGOUT; if (response && typeof response.next === 'function') { response.next(); } connection.close(); } } module.exports = exports.default; Object.defineProperty(module.exports, 'default', { value: exports.default, enumerable: false, writable: true, configurable: true });