SHA256
Довести DM v1 до соответствия коду и документации
This commit is contained in:
@@ -330,6 +330,42 @@ function parseEncryptedDmBodyBytes(payloadBytes) {
|
||||
};
|
||||
}
|
||||
|
||||
function parseReadReceiptBodyBytes(payloadBytes) {
|
||||
if (!(payloadBytes instanceof Uint8Array)) throw new Error('BAD_RECEIPT_PAYLOAD_LEN');
|
||||
let o = 0;
|
||||
const read = (n) => {
|
||||
if (o + n > payloadBytes.length) throw new Error('BAD_RECEIPT_PAYLOAD_LEN');
|
||||
const out = payloadBytes.slice(o, o + n);
|
||||
o += n;
|
||||
return out;
|
||||
};
|
||||
const readU8 = () => read(1)[0];
|
||||
const readU32 = () => {
|
||||
const part = read(4);
|
||||
return new DataView(part.buffer, part.byteOffset, 4).getUint32(0, false);
|
||||
};
|
||||
const readU64 = () => {
|
||||
const part = read(8);
|
||||
return Number(new DataView(part.buffer, part.byteOffset, 8).getBigUint64(0, false));
|
||||
};
|
||||
const readAscii = (code) => {
|
||||
const len = readU8();
|
||||
const part = read(len);
|
||||
for (let i = 0; i < part.length; i += 1) {
|
||||
const c = part[i];
|
||||
if (c < 0x20 || c > 0x7e) throw new Error(code);
|
||||
}
|
||||
return new TextDecoder().decode(part);
|
||||
};
|
||||
|
||||
const refToLogin = readAscii('BAD_RECEIPT_TO_LOGIN');
|
||||
const refFromLogin = readAscii('BAD_RECEIPT_FROM_LOGIN');
|
||||
const refTimeMs = readU64();
|
||||
const refNonce = readU32();
|
||||
if (o !== payloadBytes.length) throw new Error('BAD_RECEIPT_PAYLOAD_LEN');
|
||||
return { refToLogin, refFromLogin, refTimeMs, refNonce };
|
||||
}
|
||||
|
||||
function parseSignedMessageBlockBytes(bytes) {
|
||||
if (!(bytes instanceof Uint8Array)) throw new Error('Expected Uint8Array');
|
||||
let o = 0;
|
||||
@@ -374,11 +410,17 @@ function parseSignedMessageBlockBytes(bytes) {
|
||||
read(DM_PREFIX_V1.length);
|
||||
const formatVersionMajor = readU8();
|
||||
const formatVersionMinor = readU8();
|
||||
if (formatVersionMajor !== DM_FORMAT_VERSION_MAJOR || formatVersionMinor !== DM_FORMAT_VERSION_MINOR) {
|
||||
throw new Error('BAD_FORMAT_VERSION');
|
||||
}
|
||||
const toLogin = readAscii();
|
||||
const fromLogin = readAscii();
|
||||
const timeMs = readU64();
|
||||
const nonce = readU32();
|
||||
const messageType = readU8();
|
||||
if (messageType < DM_TYPE_INCOMING || messageType > DM_TYPE_CONVERSATION_DELETED_BY_RECIPIENT) {
|
||||
throw new Error('BAD_MESSAGE_TYPE');
|
||||
}
|
||||
const revisionTimeMs = readU64();
|
||||
const reencryptedAtMs = readU64();
|
||||
const bodyLen = readU32();
|
||||
@@ -392,9 +434,20 @@ function parseSignedMessageBlockBytes(bytes) {
|
||||
let encryptedBodyPayload = null;
|
||||
let readReceiptPayload = null;
|
||||
if (messageType === DM_TYPE_INCOMING || messageType === DM_TYPE_OUTGOING_COPY) {
|
||||
if (bodyBytes.length === 0) throw new Error('BAD_MESSAGE_LEN');
|
||||
encryptedBodyPayload = parseEncryptedDmBodyBytes(bodyBytes);
|
||||
} else if (messageType === DM_TYPE_READ_INCOMING || messageType === DM_TYPE_READ_OUTGOING_COPY) {
|
||||
readReceiptPayload = null;
|
||||
if (bodyBytes.length === 0) throw new Error('BAD_RECEIPT_PAYLOAD_LEN');
|
||||
if (revisionTimeMs !== 0 || reencryptedAtMs !== 0) throw new Error('BAD_RECEIPT_REVISION');
|
||||
readReceiptPayload = parseReadReceiptBodyBytes(bodyBytes);
|
||||
} else if (messageType === DM_TYPE_MESSAGE_DELETED_BY_SENDER || messageType === DM_TYPE_MESSAGE_DELETED_BY_RECIPIENT) {
|
||||
if (bodyBytes.length !== 0) throw new Error('BAD_DELETE_BODY');
|
||||
if (revisionTimeMs <= 0) throw new Error('BAD_REVISION_TIME');
|
||||
if (reencryptedAtMs !== 0) throw new Error('BAD_REENCRYPTED_TIME');
|
||||
} else if (messageType === DM_TYPE_CONVERSATION_DELETED_BY_SENDER || messageType === DM_TYPE_CONVERSATION_DELETED_BY_RECIPIENT) {
|
||||
if (bodyBytes.length !== 0) throw new Error('BAD_DELETE_BODY');
|
||||
if (revisionTimeMs !== 0) throw new Error('BAD_REVISION_TIME');
|
||||
if (reencryptedAtMs !== 0) throw new Error('BAD_REENCRYPTED_TIME');
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -2278,34 +2331,7 @@ export class AuthService {
|
||||
}
|
||||
|
||||
parseReadReceiptPayload(payloadBytes) {
|
||||
if (!(payloadBytes instanceof Uint8Array)) throw new Error('Expected Uint8Array');
|
||||
let o = 0;
|
||||
const read = (n) => {
|
||||
if (o + n > payloadBytes.length) throw new Error('BAD_RECEIPT_LEN');
|
||||
const out = payloadBytes.slice(o, o + n);
|
||||
o += n;
|
||||
return out;
|
||||
};
|
||||
const readU8 = () => read(1)[0];
|
||||
const readU32 = () => {
|
||||
const part = read(4);
|
||||
return new DataView(part.buffer, part.byteOffset, 4).getUint32(0, false);
|
||||
};
|
||||
const readU64 = () => {
|
||||
const part = read(8);
|
||||
return Number(new DataView(part.buffer, part.byteOffset, 8).getBigUint64(0, false));
|
||||
};
|
||||
const readAscii = () => {
|
||||
const len = readU8();
|
||||
const part = read(len);
|
||||
return new TextDecoder().decode(part);
|
||||
};
|
||||
const refToLogin = readAscii();
|
||||
const refFromLogin = readAscii();
|
||||
const refTimeMs = readU64();
|
||||
const refNonce = readU32();
|
||||
if (o !== payloadBytes.length) throw new Error('BAD_RECEIPT_LEN');
|
||||
return { refToLogin, refFromLogin, refTimeMs, refNonce };
|
||||
return parseReadReceiptBodyBytes(payloadBytes);
|
||||
}
|
||||
|
||||
async decryptSignedMessageContent({ parsed, blobB64 = '', login, storagePwd }) {
|
||||
|
||||
Reference in New Issue
Block a user