mirror of https://github.com/vector-im/riot-web
use the mimetype from the info property rather than the EncryptedFile
the mimetype in EncryptedFile is undocumented and redundant. see https://github.com/matrix-org/matrix-doc/pull/2582pull/21833/head
parent
d7cb855419
commit
3b9810719f
|
@ -31,18 +31,26 @@ export interface IEncryptedFile {
|
||||||
v: string;
|
v: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMediaEventContent {
|
export interface IMediaEventInfo {
|
||||||
body?: string;
|
thumbnail_url?: string; // eslint-disable-line camelcase
|
||||||
url?: string; // required on unencrypted media
|
thumbnail_file?: IEncryptedFile; // eslint-disable-line camelcase
|
||||||
file?: IEncryptedFile; // required for *encrypted* media
|
thumbnail_info?: { // eslint-disable-line camelcase
|
||||||
info?: {
|
|
||||||
thumbnail_url?: string; // eslint-disable-line camelcase
|
|
||||||
thumbnail_file?: IEncryptedFile; // eslint-disable-line camelcase
|
|
||||||
mimetype: string;
|
mimetype: string;
|
||||||
w?: number;
|
w?: number;
|
||||||
h?: number;
|
h?: number;
|
||||||
size?: number;
|
size?: number;
|
||||||
};
|
};
|
||||||
|
mimetype: string;
|
||||||
|
w?: number;
|
||||||
|
h?: number;
|
||||||
|
size?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IMediaEventContent {
|
||||||
|
body?: string;
|
||||||
|
url?: string; // required on unencrypted media
|
||||||
|
file?: IEncryptedFile; // required for *encrypted* media
|
||||||
|
info?: IMediaEventInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPreparedMedia extends IMediaObject {
|
export interface IPreparedMedia extends IMediaObject {
|
||||||
|
|
|
@ -17,18 +17,22 @@ limitations under the License.
|
||||||
// Pull in the encryption lib so that we can decrypt attachments.
|
// Pull in the encryption lib so that we can decrypt attachments.
|
||||||
import encrypt from 'browser-encrypt-attachment';
|
import encrypt from 'browser-encrypt-attachment';
|
||||||
import { mediaFromContent } from "../customisations/Media";
|
import { mediaFromContent } from "../customisations/Media";
|
||||||
import { IEncryptedFile } from "../customisations/models/IMediaEventContent";
|
import { IEncryptedFile, IMediaEventInfo } from "../customisations/models/IMediaEventContent";
|
||||||
import { getBlobSafeMimeType } from "./blobs";
|
import { getBlobSafeMimeType } from "./blobs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypt a file attached to a matrix event.
|
* Decrypt a file attached to a matrix event.
|
||||||
* @param {IEncryptedFile} file The json taken from the matrix event.
|
* @param {IEncryptedFile} file The encrypted file information taken from the matrix event.
|
||||||
* This passed to [link]{@link https://github.com/matrix-org/browser-encrypt-attachments}
|
* This passed to [link]{@link https://github.com/matrix-org/browser-encrypt-attachments}
|
||||||
* as the encryption info object, so will also have the those keys in addition to
|
* as the encryption info object, so will also have the those keys in addition to
|
||||||
* the keys below.
|
* the keys below.
|
||||||
|
* @param {IMediaEventInfo} info The info parameter taken from the matrix event.
|
||||||
* @returns {Promise<Blob>} Resolves to a Blob of the file.
|
* @returns {Promise<Blob>} Resolves to a Blob of the file.
|
||||||
*/
|
*/
|
||||||
export function decryptFile(file: IEncryptedFile): Promise<Blob> {
|
export function decryptFile(
|
||||||
|
file: IEncryptedFile,
|
||||||
|
info: IMediaEventInfo | undefined,
|
||||||
|
): Promise<Blob> {
|
||||||
const media = mediaFromContent({ file });
|
const media = mediaFromContent({ file });
|
||||||
// Download the encrypted file as an array buffer.
|
// Download the encrypted file as an array buffer.
|
||||||
return media.downloadSource().then((response) => {
|
return media.downloadSource().then((response) => {
|
||||||
|
@ -44,7 +48,7 @@ export function decryptFile(file: IEncryptedFile): Promise<Blob> {
|
||||||
// they introduce XSS attacks if the Blob URI is viewed directly in the
|
// they introduce XSS attacks if the Blob URI is viewed directly in the
|
||||||
// browser (e.g. by copying the URI into a new tab or window.)
|
// browser (e.g. by copying the URI into a new tab or window.)
|
||||||
// See warning at top of file.
|
// See warning at top of file.
|
||||||
let mimetype = file.mimetype ? file.mimetype.split(";")[0].trim() : '';
|
let mimetype = info?.mimetype ? info.mimetype.split(";")[0].trim() : '';
|
||||||
mimetype = getBlobSafeMimeType(mimetype);
|
mimetype = getBlobSafeMimeType(mimetype);
|
||||||
|
|
||||||
return new Blob([dataArray], { type: mimetype });
|
return new Blob([dataArray], { type: mimetype });
|
||||||
|
|
|
@ -76,7 +76,8 @@ export class MediaEventHelper implements IDestroyable {
|
||||||
|
|
||||||
private fetchSource = () => {
|
private fetchSource = () => {
|
||||||
if (this.media.isEncrypted) {
|
if (this.media.isEncrypted) {
|
||||||
return decryptFile(this.event.getContent<IMediaEventContent>().file);
|
const content = this.event.getContent<IMediaEventContent>();
|
||||||
|
return decryptFile(content.file, content.info);
|
||||||
}
|
}
|
||||||
return this.media.downloadSource().then(r => r.blob());
|
return this.media.downloadSource().then(r => r.blob());
|
||||||
};
|
};
|
||||||
|
@ -87,7 +88,7 @@ export class MediaEventHelper implements IDestroyable {
|
||||||
if (this.media.isEncrypted) {
|
if (this.media.isEncrypted) {
|
||||||
const content = this.event.getContent<IMediaEventContent>();
|
const content = this.event.getContent<IMediaEventContent>();
|
||||||
if (content.info?.thumbnail_file) {
|
if (content.info?.thumbnail_file) {
|
||||||
return decryptFile(content.info.thumbnail_file);
|
return decryptFile(content.info.thumbnail_file, content.info.thumbnail_info);
|
||||||
} else {
|
} else {
|
||||||
// "Should never happen"
|
// "Should never happen"
|
||||||
console.warn("Media claims to have thumbnail and is encrypted, but no thumbnail_file found");
|
console.warn("Media claims to have thumbnail and is encrypted, but no thumbnail_file found");
|
||||||
|
|
Loading…
Reference in New Issue