From c07ab1af26310e290d6d4e2b50eac23eff8ed51e Mon Sep 17 00:00:00 2001 From: Beau Cameron Date: Mon, 13 Nov 2023 16:14:43 -0500 Subject: [PATCH] Fix for 2825 New utility method for converting to atob with stringification checks Updated Parser for Blobs Update parsers.ts --- packages/core/util.ts | 18 +++++++++++++++++- packages/queryable/behaviors/parsers.ts | 18 ++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/packages/core/util.ts b/packages/core/util.ts index d5e5b191d..9bac79d7d 100644 --- a/packages/core/util.ts +++ b/packages/core/util.ts @@ -133,7 +133,23 @@ export function hOP(o: any, p: T): boolean { return Object.hasOwnProperty.call(o, p); } - +/** + * @returns validates and returns a valid atob conversion +*/ +export function parseToAtob(str: string): string { + const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/; + try { + // test if str has been JSON.stringified + const parsed = JSON.parse(str); + if(base64Regex.test(parsed)){ + return atob(parsed); + } + return null; + } catch (err) { + // Not a valid JSON string, check if it's a standalone Base64 string + return base64Regex.test(str) ? atob(str) : null; + } +} /** * Generates a ~unique hash code diff --git a/packages/queryable/behaviors/parsers.ts b/packages/queryable/behaviors/parsers.ts index f649e01df..5313faa38 100644 --- a/packages/queryable/behaviors/parsers.ts +++ b/packages/queryable/behaviors/parsers.ts @@ -1,5 +1,5 @@ import { Queryable } from "../queryable.js"; -import { hOP, TimelinePipe } from "@pnp/core"; +import { hOP, TimelinePipe, parseToAtob } from "@pnp/core"; import { isFunc } from "@pnp/core"; export function DefaultParse(): TimelinePipe { @@ -25,7 +25,21 @@ export function TextParse(): TimelinePipe { export function BlobParse(): TimelinePipe { - return parseBinderWithErrorCheck(r => r.blob()); + return parseBinderWithErrorCheck( async (response) => { + const binaryResponseBody = parseToAtob(await response.clone().text()); + // handle batch responses for things that are base64, like photos https://github.com/pnp/pnpjs/issues/2825 + if(binaryResponseBody){ + // Create an array buffer from the binary string + const arrayBuffer = new ArrayBuffer(binaryResponseBody.length); + const uint8Array = new Uint8Array(arrayBuffer); + for (let i = 0; i < binaryResponseBody.length; i++) { + uint8Array[i] = binaryResponseBody.charCodeAt(i); + } + // Create a Blob from the array buffer + return new Blob([arrayBuffer], {type:response.headers.get("Content-Type")}); + } + return response.blob(); + }); } export function JSONParse(): TimelinePipe {