Skip to content

Commit

Permalink
fix: use getAsFileSystemHandle only in secure ctx
Browse files Browse the repository at this point in the history
  • Loading branch information
rolandjitsu committed Nov 25, 2024
1 parent f159a4a commit 70f2362
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 4 deletions.
5 changes: 4 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/** @type {import('ts-jest').JestConfigWithTsJest} **/
/** @type {import('ts-jest').ProjectConfigTsJest} **/
module.exports = {
testEnvironment: 'jsdom',
"setupFilesAfterEnv": [
"<rootDir>/test-setup.js"
],
transform: {
'^.+.tsx?$': [
'ts-jest',
Expand Down
32 changes: 30 additions & 2 deletions src/file-selector.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,35 @@ it('should use getAsFileSystemHandle when available', async () => {
expect(file.path).toBe(`./${name}`);
});

it('should not use getAsFileSystemHandle when not in a secure context', async () => {
const f1Name = 'test.nosec.json';
const f1 = createFile(f1Name, {ping: false}, {
type: 'application/json'
});
const [_, h] = createFileSystemFileHandle('test.sec.json', {ping: true}, {
type: 'application/json'
});
const evt = dragEvtFromItems([
dataTransferItemWithFsHandle(f1, h)
]);

window.isSecureContext = false;

const files = await fromEvent(evt);
expect(files).toHaveLength(1);
expect(files.every(file => file instanceof File)).toBe(true);

const [file] = files as FileWithPath[];

expect(file.name).toBe(f1.name);
expect(file.type).toBe(f1.type);
expect(file.size).toBe(f1.size);
expect(file.lastModified).toBe(f1.lastModified);
expect(file.path).toBe(`./${f1Name}`);

window.isSecureContext = true;
});

function dragEvtFromItems(items: DataTransferItem | DataTransferItem[], type: string = 'drop'): DragEvent {
return {
type,
Expand Down Expand Up @@ -466,8 +495,7 @@ function createFile<T>(name: string, data: T, options?: FilePropertyBag) {
}

function createFileSystemFileHandle<T>(name: string, data: T, options?: FilePropertyBag): [File, FileSystemFileHandle] {
const json = JSON.stringify(data);
const file = new File([json], name, options);
const file = createFile(name, data, options);
return [file, {
getFile() {
return Promise.resolve(file);
Expand Down
8 changes: 7 additions & 1 deletion src/file-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,13 @@ function flatten<T>(items: any[]): T[] {
}

function fromDataTransferItem(item: DataTransferItem, entry?: FileSystemEntry | null) {
if (typeof (item as any).getAsFileSystemHandle === 'function') {
// Check if we're in a secure context; due to a bug in Chrome (as far as we know)
// the browser crashes when calling this API (yet to be confirmed as a consistent behaviour).
//
// See:
// - https://issues.chromium.org/issues/40186242
// - https://github.com/react-dropzone/react-dropzone/issues/1397
if (globalThis.isSecureContext && typeof (item as any).getAsFileSystemHandle === 'function') {
return (item as any).getAsFileSystemHandle()
.then(async (h: any) => {
const file = await h.getFile();
Expand Down
6 changes: 6 additions & 0 deletions test-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// NOTE: Let us test {isSecureContext}!
Object.defineProperty(globalThis, "isSecureContext", {
value: true,
writable: true,
enumerable: true,
});

0 comments on commit 70f2362

Please sign in to comment.