SHA256
WIP: новая схема сообщений и push (не проверено)
This commit is contained in:
+85
-36
@@ -7,13 +7,15 @@ import {
|
||||
authService,
|
||||
addAppLogEntry,
|
||||
authorizeSession,
|
||||
hydrateMessagesFromStore,
|
||||
isSessionInvalidError,
|
||||
refreshSessions,
|
||||
setSessionAuthorizedHandler,
|
||||
setSessionResetHandler,
|
||||
state,
|
||||
terminateCurrentSession,
|
||||
addIncomingMessage,
|
||||
addSignedMessageToChat,
|
||||
markOutgoingReadByBaseKey,
|
||||
setContacts,
|
||||
} from './state.js';
|
||||
|
||||
@@ -338,48 +340,94 @@ async function init() {
|
||||
await terminateCurrentSession({ infoMessage: 'Сессия закрыта с другого устройства.' });
|
||||
});
|
||||
|
||||
authService.onEvent('IncomingDirectMessage', async (evt) => {
|
||||
authService.onEvent('SignedMessageArrived', async (evt) => {
|
||||
const payload = evt?.payload || {};
|
||||
const fromLogin = payload.fromLogin || 'unknown';
|
||||
const messageId = payload.messageId || '';
|
||||
const eventId = payload.eventId || evt?.requestId || '';
|
||||
let text = payload.text || '';
|
||||
if (!text && payload.blobB64) {
|
||||
try {
|
||||
const bytes = Uint8Array.from(atob(payload.blobB64), (ch) => ch.charCodeAt(0));
|
||||
const msgLen = (bytes[bytes.length - 66] << 8) | bytes[bytes.length - 65];
|
||||
const msgStart = bytes.length - 64 - msgLen;
|
||||
const msgBytes = bytes.slice(msgStart, msgStart + msgLen);
|
||||
text = new TextDecoder().decode(msgBytes);
|
||||
} catch {
|
||||
text = '[binary message]';
|
||||
}
|
||||
}
|
||||
const added = addIncomingMessage(fromLogin, text, messageId);
|
||||
if (added) {
|
||||
const messageKey = String(payload.messageKey || '').trim();
|
||||
const blobB64 = String(payload.blobB64 || '').trim();
|
||||
if (!messageKey || !blobB64) return;
|
||||
|
||||
let parsed;
|
||||
try {
|
||||
parsed = authService.parseSignedMessageBlob(blobB64);
|
||||
} catch (error) {
|
||||
addAppLogEntry({
|
||||
level: 'info',
|
||||
source: 'incoming-dm',
|
||||
message: `Входящее сообщение от ${fromLogin}`,
|
||||
details: { messageId, text },
|
||||
level: 'warn',
|
||||
source: 'signed-dm',
|
||||
message: 'Не удалось распарсить входящий signed message',
|
||||
details: { messageKey, error: error?.message || 'unknown' },
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (added && Notification.permission === 'granted') {
|
||||
try {
|
||||
new Notification(`Сообщение от ${fromLogin}`, { body: text || '' });
|
||||
} catch {}
|
||||
}
|
||||
if (eventId) {
|
||||
try {
|
||||
await authService.ackIncomingMessage(eventId, messageId);
|
||||
} catch (error) {
|
||||
|
||||
const myLogin = String(state.session.login || '').trim().toLowerCase();
|
||||
const fromLogin = parsed.fromLogin || '';
|
||||
const toLogin = parsed.toLogin || '';
|
||||
const chatId = String(fromLogin || '').toLowerCase() === myLogin ? toLogin : fromLogin;
|
||||
const messageType = Number(parsed.messageType || 0);
|
||||
const text = (messageType === 1 || messageType === 2)
|
||||
? new TextDecoder().decode(parsed.payloadBytes || new Uint8Array(0))
|
||||
: '';
|
||||
|
||||
if (messageType === 1 || messageType === 2) {
|
||||
const isIncomingForCurrent = messageType === 1;
|
||||
const added = addSignedMessageToChat({
|
||||
chatId,
|
||||
messageKey,
|
||||
baseKey: parsed.baseKey,
|
||||
from: isIncomingForCurrent ? 'in' : 'out',
|
||||
text,
|
||||
messageType,
|
||||
unread: isIncomingForCurrent,
|
||||
rawBlobB64: blobB64,
|
||||
});
|
||||
if (added) {
|
||||
addAppLogEntry({
|
||||
level: 'warn',
|
||||
source: 'incoming-dm',
|
||||
message: 'Не удалось отправить ACK на входящее сообщение',
|
||||
details: { eventId, messageId, error: error?.message || 'unknown' },
|
||||
level: 'info',
|
||||
source: 'signed-dm',
|
||||
message: isIncomingForCurrent
|
||||
? `Новое входящее сообщение от ${fromLogin}`
|
||||
: `Синхронизирована исходящая копия в чате ${chatId}`,
|
||||
details: { messageKey, baseKey: parsed.baseKey, messageType },
|
||||
});
|
||||
}
|
||||
if (added && isIncomingForCurrent && Notification.permission === 'granted' && !payload.backlog) {
|
||||
try {
|
||||
new Notification(`Сообщение от ${fromLogin}`, { body: text || '' });
|
||||
} catch {}
|
||||
}
|
||||
} else if (messageType === 3 || messageType === 4) {
|
||||
const refBaseKey = String(payload.receiptRefBaseKey || '').trim();
|
||||
if (refBaseKey) {
|
||||
markOutgoingReadByBaseKey(refBaseKey);
|
||||
} else {
|
||||
try {
|
||||
const ref = authService.parseReadReceiptPayload(parsed.payloadBytes);
|
||||
const fallbackRefBase = `${ref.refFromLogin}|${ref.refToLogin}|${ref.refTimeMs}|${ref.refNonce}`;
|
||||
markOutgoingReadByBaseKey(fallbackRefBase);
|
||||
} catch {}
|
||||
}
|
||||
addAppLogEntry({
|
||||
level: 'info',
|
||||
source: 'signed-dm',
|
||||
message: 'Получено подтверждение прочтения',
|
||||
details: { messageKey, baseKey: parsed.baseKey, messageType },
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await authService.ackSessionDelivery(messageKey);
|
||||
} catch (error) {
|
||||
addAppLogEntry({
|
||||
level: 'warn',
|
||||
source: 'signed-dm',
|
||||
message: 'Не удалось отправить ACK доставки по сессии',
|
||||
details: { messageKey, error: error?.message || 'unknown' },
|
||||
});
|
||||
}
|
||||
|
||||
const pageId = getRoute().pageId || '';
|
||||
if (pageId === 'chat-view' || pageId === 'messages-list') {
|
||||
renderApp();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -392,6 +440,7 @@ async function init() {
|
||||
});
|
||||
|
||||
await tryAutoLogin();
|
||||
await hydrateMessagesFromStore();
|
||||
await ensureSessionRuntimeStarted();
|
||||
|
||||
if (!window.location.hash) {
|
||||
|
||||
Reference in New Issue
Block a user