Apply strictNullChecks to src/utils/exportUtils (#10379)

* Apply `strictNullChecks` to `src/utils/exportUtils`

* strict fix

* test coverage

* lint

* test coverage

* one more test
This commit is contained in:
Kerry 2023-03-30 10:47:07 +13:00 committed by GitHub
parent 1447829543
commit 9a733a6444
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 178 additions and 9 deletions

View file

@ -47,7 +47,8 @@ export class DecryptError extends Error {
* @param {IMediaEventInfo} info The info parameter taken from the matrix event.
* @returns {Promise<Blob>} Resolves to a Blob of the file.
*/
export async function decryptFile(file: IEncryptedFile, info?: IMediaEventInfo): Promise<Blob> {
export async function decryptFile(file?: IEncryptedFile, info?: IMediaEventInfo): Promise<Blob> {
// throws if file is falsy
const media = mediaFromContent({ file });
let responseData: ArrayBuffer;
@ -64,7 +65,7 @@ export async function decryptFile(file: IEncryptedFile, info?: IMediaEventInfo):
try {
// Decrypt the array buffer using the information taken from the event content.
const dataArray = await encrypt.decryptAttachment(responseData, file);
const dataArray = await encrypt.decryptAttachment(responseData, file!);
// Turn the array into a Blob and give it the correct MIME-type.
// IMPORTANT: we must not allow scriptable mime-types into Blobs otherwise

View file

@ -51,7 +51,8 @@ export default abstract class Exporter {
if (
exportOptions.maxSize < 1 * 1024 * 1024 || // Less than 1 MB
exportOptions.maxSize > 8000 * 1024 * 1024 || // More than 8 GB
exportOptions.numberOfMessages > 10 ** 8
(!!exportOptions.numberOfMessages && exportOptions.numberOfMessages > 10 ** 8) ||
(exportType === ExportType.LastNMessages && !exportOptions.numberOfMessages)
) {
throw new Error("Invalid export options");
}
@ -123,10 +124,11 @@ export default abstract class Exporter {
}
protected setEventMetadata(event: MatrixEvent): MatrixEvent {
const roomState = this.client.getRoom(this.room.roomId).currentState;
event.sender = roomState.getSentinelMember(event.getSender());
const roomState = this.client.getRoom(this.room.roomId)?.currentState;
const sender = event.getSender();
event.sender = (!!sender && roomState?.getSentinelMember(sender)) || null;
if (event.getType() === "m.room.member") {
event.target = roomState.getSentinelMember(event.getStateKey());
event.target = roomState?.getSentinelMember(event.getStateKey()!) ?? null;
}
return event;
}
@ -135,6 +137,8 @@ export default abstract class Exporter {
let limit: number;
switch (this.exportType) {
case ExportType.LastNMessages:
// validated in constructor that numberOfMessages is defined
// when export type is LastNMessages
limit = this.exportOptions.numberOfMessages!;
break;
case ExportType.Timeline:
@ -221,8 +225,14 @@ export default abstract class Exporter {
return events;
}
protected async getMediaBlob(event: MatrixEvent): Promise<Blob | undefined> {
let blob: Blob | undefined;
/**
* Decrypts if necessary, and fetches media from a matrix event
* @param event - matrix event with media event content
* @resolves when media has been fetched
* @throws if media was unable to be fetched
*/
protected async getMediaBlob(event: MatrixEvent): Promise<Blob> {
let blob: Blob | undefined = undefined;
try {
const isEncrypted = event.isEncrypted();
const content = event.getContent<IMediaEventContent>();
@ -231,12 +241,18 @@ export default abstract class Exporter {
blob = await decryptFile(content.file);
} else {
const media = mediaFromContent(content);
if (!media.srcHttp) {
throw new Error("Cannot fetch without srcHttp");
}
const image = await fetch(media.srcHttp);
blob = await image.blob();
}
} catch (err) {
logger.log("Error decrypting media");
}
if (!blob) {
throw new Error("Unable to fetch file");
}
return blob;
}