SHA256
Display new notification count
This commit is contained in:
@@ -249,6 +249,11 @@ function uint8Bytes(value) {
|
||||
}
|
||||
|
||||
const DM_PREFIX_V1 = utf8Bytes('SHiNE_DM');
|
||||
const NTF_PREFIX_V1 = utf8Bytes('SHiNE_NTF');
|
||||
const NTF_FORMAT_VERSION_MAJOR = 1;
|
||||
const NTF_FORMAT_VERSION_MINOR = 0;
|
||||
const NTF_STATE_SEEN_WATERMARK = 1;
|
||||
const NTF_CATEGORY = { replies: 1, connections: 2, events: 3 };
|
||||
const DM_TYPE_INCOMING = 1;
|
||||
const DM_TYPE_OUTGOING_COPY = 2;
|
||||
const DM_TYPE_READ_INCOMING = 3;
|
||||
@@ -2891,14 +2896,40 @@ export class AuthService {
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async getNotifications(limit = 50) {
|
||||
const payload = {};
|
||||
if (Number.isFinite(Number(limit))) payload.limit = Math.max(1, Math.min(200, Number(limit)));
|
||||
const response = await this.ws.request('GetNotifications', payload);
|
||||
async getNotifications(countsOnly = false) {
|
||||
const response = await this.ws.request('GetNotifications', countsOnly ? { countsOnly: true } : {});
|
||||
if (response.status !== 200) throw opError('GetNotifications', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async setNotificationSeen({ login, category, seenAtMs, storagePwd }) {
|
||||
const cleanLogin = this.normalizeDmLogin(login);
|
||||
const cleanCategory = String(category || '').trim().toLowerCase();
|
||||
const categoryCode = NTF_CATEGORY[cleanCategory];
|
||||
if (!cleanLogin || !categoryCode) throw new Error('Некорректный login/category уведомлений');
|
||||
if (!storagePwd) throw new Error('Не передан storagePwd для подписи состояния уведомлений');
|
||||
const normalizedSeenAtMs = Math.max(0, Math.trunc(Number(seenAtMs || 0)));
|
||||
const timeMs = Date.now();
|
||||
const nonce = Math.floor(Math.random() * 0x100000000);
|
||||
const secrets = await loadEncryptedUserSecrets(cleanLogin, storagePwd);
|
||||
const clientPriv = secrets?.clientKey;
|
||||
if (!clientPriv) throw new Error('Не найден приватный clientKey');
|
||||
const privateKey = await importPkcs8Ed25519(clientPriv);
|
||||
const loginBytes = ensureAsciiBytes(cleanLogin, 'login');
|
||||
const preimage = concatBytes(
|
||||
NTF_PREFIX_V1,
|
||||
uint8Bytes(NTF_FORMAT_VERSION_MAJOR), uint8Bytes(NTF_FORMAT_VERSION_MINOR),
|
||||
uint8Bytes(loginBytes.length), loginBytes,
|
||||
uint64Bytes(timeMs), uint32Bytes(nonce),
|
||||
uint8Bytes(NTF_STATE_SEEN_WATERMARK), uint8Bytes(categoryCode),
|
||||
uint64Bytes(normalizedSeenAtMs),
|
||||
);
|
||||
const signature = await signBytes(privateKey, preimage);
|
||||
const response = await this.ws.request('SetNotificationState', { blobB64: bytesToBase64(concatBytes(preimage, signature)) });
|
||||
if (response.status !== 200) throw opError('SetNotificationState', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async getUserConnectionsGraph(login) {
|
||||
const response = await this.ws.request('GetUserConnectionsGraph', { login });
|
||||
if (response.status !== 200) throw opError('GetUserConnectionsGraph', response);
|
||||
|
||||
Reference in New Issue
Block a user