mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-15 03:25:46 -04:00
We don't want to clone a struct that contains a secret. However, on the Node.js side, we can only receive arguments by references. The problem we have is that we cannot transfer the ownership of `MediaEncryptionInfo` to `AttachmentDecryptor` because we don't own it. To simulate this behavior, we use `Option.take`. A new method then appears: `EncryptedAttachment.hasMediaEncryptionInfoBeenConsumed` to know if the media encryption info has been consumed by `Attachment.decrypt` already or not. That way, we can decrypt only once. It is possible to do a JSON-encoded backup of the media encryption info by calling `EncryptedAttachment.mediaEncryptionInfo` though.
78 lines
2.8 KiB
JavaScript
78 lines
2.8 KiB
JavaScript
const { Attachment, EncryptedAttachment } = require('../');
|
|
|
|
describe(Attachment.name, () => {
|
|
const originalData = 'hello';
|
|
const textEncoder = new TextEncoder();
|
|
const textDecoder = new TextDecoder();
|
|
|
|
let encryptedAttachment;
|
|
|
|
test('can encrypt data', () => {
|
|
encryptedAttachment = Attachment.encrypt(textEncoder.encode(originalData));
|
|
|
|
const mediaEncryptionInfo = JSON.parse(encryptedAttachment.mediaEncryptionInfo);
|
|
|
|
expect(mediaEncryptionInfo).toMatchObject({
|
|
v: 'v2',
|
|
key: {
|
|
kty: expect.any(String),
|
|
key_ops: expect.arrayContaining(['encrypt', 'decrypt']),
|
|
alg: expect.any(String),
|
|
k: expect.any(String),
|
|
ext: expect.any(Boolean),
|
|
},
|
|
iv: expect.stringMatching(/^[A-Za-z0-9\+/]+$/),
|
|
hashes: {
|
|
sha256: expect.stringMatching(/^[A-Za-z0-9\+/]+$/)
|
|
}
|
|
});
|
|
|
|
const encryptedData = encryptedAttachment.encryptedData;
|
|
expect(encryptedData.every((i) => { i != 0 })).toStrictEqual(false);
|
|
});
|
|
|
|
test('can decrypt data', () => {
|
|
expect(encryptedAttachment.hasMediaEncryptionInfoBeenConsumed).toStrictEqual(false);
|
|
|
|
const decryptedAttachment = Attachment.decrypt(encryptedAttachment);
|
|
|
|
expect(textDecoder.decode(decryptedAttachment)).toStrictEqual(originalData);
|
|
expect(encryptedAttachment.hasMediaEncryptionInfoBeenConsumed).toStrictEqual(true);
|
|
});
|
|
|
|
test('can only decrypt once', () => {
|
|
expect(encryptedAttachment.hasMediaEncryptionInfoBeenConsumed).toStrictEqual(true);
|
|
|
|
expect(() => { textDecoder.decode(decryptedAttachment) }).toThrow()
|
|
});
|
|
});
|
|
|
|
describe(EncryptedAttachment.name, () => {
|
|
const originalData = 'hello';
|
|
const textDecoder = new TextDecoder();
|
|
|
|
test('can be created manually', () => {
|
|
const encryptedAttachment = new EncryptedAttachment(
|
|
new Uint8Array([24, 150, 67, 37, 144]),
|
|
JSON.stringify({
|
|
v: 'v2',
|
|
key: {
|
|
kty: 'oct',
|
|
key_ops: [ 'encrypt', 'decrypt' ],
|
|
alg: 'A256CTR',
|
|
k: 'QbNXUjuukFyEJ8cQZjJuzN6mMokg0HJIjx0wVMLf5BM',
|
|
ext: true
|
|
},
|
|
iv: 'xk2AcWkomiYAAAAAAAAAAA',
|
|
hashes: {
|
|
sha256: 'JsRbDXgOja4xvDiF3DwBuLHdxUzIrVYIuj7W/t3aEok'
|
|
}
|
|
})
|
|
);
|
|
|
|
expect(encryptedAttachment.hasMediaEncryptionInfoBeenConsumed).toStrictEqual(false);
|
|
expect(textDecoder.decode(Attachment.decrypt(encryptedAttachment))).toStrictEqual(originalData);
|
|
expect(encryptedAttachment.hasMediaEncryptionInfoBeenConsumed).toStrictEqual(true);
|
|
});
|
|
});
|