mirror of
https://github.com/lone-cloud/prism
synced 2026-06-03 19:54:44 -07:00
proton mail IMAP reconnection, wait to re-gen the QR code until daemon has fully started up
This commit is contained in:
parent
0e3eb43531
commit
128aa9ffe5
3 changed files with 52 additions and 20 deletions
|
|
@ -60,7 +60,7 @@ const cspConfig = {
|
||||||
defaultSrc: ["'self'"],
|
defaultSrc: ["'self'"],
|
||||||
scriptSrc: ["'self'"],
|
scriptSrc: ["'self'"],
|
||||||
styleSrc: ["'self'", "'unsafe-inline'"],
|
styleSrc: ["'self'", "'unsafe-inline'"],
|
||||||
imgSrc: ["'self'", 'data:', 'https://api.qrserver.com'],
|
imgSrc: ["'self'", 'data:'],
|
||||||
formAction: ["'self'"],
|
formAction: ["'self'"],
|
||||||
frameAncestors: ["'none'"],
|
frameAncestors: ["'none'"],
|
||||||
objectSrc: ["'none'"],
|
objectSrc: ["'none'"],
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,18 @@ import { logError, logInfo, logSuccess, logVerbose, logWarn } from '@/utils/log'
|
||||||
|
|
||||||
let imapConnected = false;
|
let imapConnected = false;
|
||||||
let monitorStartTime = 0;
|
let monitorStartTime = 0;
|
||||||
|
let reconnectAttempts = 0;
|
||||||
|
const MAX_RECONNECT_DELAY = 300000; // 5 minutes
|
||||||
|
|
||||||
export const isImapConnected = () => imapConnected;
|
export const isImapConnected = () => imapConnected;
|
||||||
|
|
||||||
|
const getReconnectDelay = () => {
|
||||||
|
const baseDelay = 10000; // 10 seconds
|
||||||
|
const delay = Math.min(baseDelay * 2 ** reconnectAttempts, MAX_RECONNECT_DELAY);
|
||||||
|
reconnectAttempts++;
|
||||||
|
return delay;
|
||||||
|
};
|
||||||
|
|
||||||
export async function startProtonMonitor() {
|
export async function startProtonMonitor() {
|
||||||
if (!PROTON_IMAP_USERNAME || !PROTON_IMAP_PASSWORD) {
|
if (!PROTON_IMAP_USERNAME || !PROTON_IMAP_PASSWORD) {
|
||||||
logError('Missing required env vars: PROTON_IMAP_USERNAME and PROTON_IMAP_PASSWORD');
|
logError('Missing required env vars: PROTON_IMAP_USERNAME and PROTON_IMAP_PASSWORD');
|
||||||
|
|
@ -114,6 +123,7 @@ export async function startProtonMonitor() {
|
||||||
const nameMatch = rawFrom.match(/^"?([^"<]+)"?\s*<?/);
|
const nameMatch = rawFrom.match(/^"?([^"<]+)"?\s*<?/);
|
||||||
const from = nameMatch?.[1]?.trim() || rawFrom;
|
const from = nameMatch?.[1]?.trim() || rawFrom;
|
||||||
|
|
||||||
|
reconnectAttempts = 0;
|
||||||
sendNotification(from, subject);
|
sendNotification(from, subject);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -123,6 +133,7 @@ export async function startProtonMonitor() {
|
||||||
|
|
||||||
imap.on('ready', () => {
|
imap.on('ready', () => {
|
||||||
imapConnected = true;
|
imapConnected = true;
|
||||||
|
reconnectAttempts = 0;
|
||||||
logSuccess('IMAP is ready');
|
logSuccess('IMAP is ready');
|
||||||
openInbox();
|
openInbox();
|
||||||
});
|
});
|
||||||
|
|
@ -132,14 +143,26 @@ export async function startProtonMonitor() {
|
||||||
logError('IMAP error:', err.message);
|
logError('IMAP error:', err.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
imap.on('close', (hadError: boolean) => {
|
const handleReconnect = (reason: string) => {
|
||||||
imapConnected = false;
|
imapConnected = false;
|
||||||
logError(`IMAP connection closed (hadError: ${hadError})`);
|
logError(reason);
|
||||||
|
|
||||||
|
const delay = getReconnectDelay();
|
||||||
|
logInfo(`Attempting to reconnect in ${delay / 1000}s (attempt ${reconnectAttempts})...`);
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!imapConnected) {
|
||||||
|
logInfo('Reconnecting to Proton Bridge...');
|
||||||
|
imap.connect();
|
||||||
|
}
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
|
||||||
|
imap.on('close', (hadError: boolean) => {
|
||||||
|
handleReconnect(`IMAP connection closed (hadError: ${hadError})`);
|
||||||
});
|
});
|
||||||
|
|
||||||
imap.on('end', () => {
|
imap.on('end', () => {
|
||||||
imapConnected = false;
|
handleReconnect('IMAP connection ended by server');
|
||||||
logError('IMAP connection ended by server');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
imap.connect();
|
imap.connect();
|
||||||
|
|
|
||||||
|
|
@ -161,27 +161,36 @@ const handleQRSection = async () => {
|
||||||
|
|
||||||
if ((!cachedQR || now - qrCacheTime > QR_CACHE_TTL) && !generatingPromise) {
|
if ((!cachedQR || now - qrCacheTime > QR_CACHE_TTL) && !generatingPromise) {
|
||||||
generatingPromise = (async () => {
|
generatingPromise = (async () => {
|
||||||
const qr = await generateLinkQR();
|
try {
|
||||||
cachedQR = qr;
|
const qr = await generateLinkQR();
|
||||||
qrCacheTime = Date.now();
|
cachedQR = qr;
|
||||||
|
qrCacheTime = Date.now();
|
||||||
|
|
||||||
finishLink()
|
finishLink()
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
await initSignal();
|
await initSignal();
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
generatingPromise = null;
|
generatingPromise = null;
|
||||||
cachedQR = null;
|
cachedQR = null;
|
||||||
qrCacheTime = 0;
|
qrCacheTime = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
return qr;
|
return qr;
|
||||||
|
} catch (error) {
|
||||||
|
generatingPromise = null;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generatingPromise && !cachedQR) {
|
if (generatingPromise && !cachedQR) {
|
||||||
await generatingPromise;
|
try {
|
||||||
|
await generatingPromise;
|
||||||
|
} catch {
|
||||||
|
return '<p>Signal daemon is starting up, please refresh in a few seconds...</p>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue