oaeproject / 3akai-ux

Open Academic Environment (OAE) Front-End
http://www.oaeproject.org
Educational Community License v2.0
134 stars 206 forks source link

Support OS X File Packages as Content (or at least provide meaningful errors) #3788

Closed sathomas closed 10 years ago

sathomas commented 10 years ago

OS X allows certain directories (file packages) to be presented to users as single files in the the Finder. Many OS X applications (Keynote, Pages, Numbers, ...) use file packages for individual documents. If a user attempts to upload a file package to the OAE, the behavior is browser-dependent, but in no case is it good. The following behaviors are based on the pending pull request https://github.com/oaeproject/3akai-ux/pull/3781.

Safari

Safari recognizes file packages as documents, creates a .zip archive of the directory contents, and uploads that .zip archive as a single file. It does not, however, change the name of the file package to add a .zip extension. When an OAE user downloads this uploaded file, it is downloaded as a .zip archive but retains the name of the original file package. (For example, what really should be named Presentation.key.zip is downloaded as Presentation.key.) The OS X Finder attempts to treat the resulting download as a file package instead of an archive, and the corresponding app fails to open it.

Firefox

Firefox treats file packages exactly as regular directories (folders), which is to say it presents them to JavaScript as zero-length files. The OAE rejects files without content and does not upload them.

Chrome

Chrome treats file packages exactly as regular directories (folders), which is to say it allows JavaScript to traverse the file system and locate individual files within the package. The OAE thus uploads many (potentially hundreds) of useless individual files instead of the single document the user expects. Here's an example of the individual files that comprise a single Keynote presentation.

$ tree -fF JavaScript\ Security.key/
JavaScript Security.key
├── JavaScript Security.key/Data/
│   ├── JavaScript Security.key/Data/Girl and Snowcone-120.jpg
│   ├── JavaScript Security.key/Data/Girl and Snowcone-small-121.jpg
│   ├── JavaScript Security.key/Data/Happy Girls-117.jpg
│   ├── JavaScript Security.key/Data/Happy Girls-small-118.jpg
│   ├── JavaScript Security.key/Data/droppedImage-112.pdf
│   ├── JavaScript Security.key/Data/droppedImage-114.pdf
│   ├── JavaScript Security.key/Data/droppedImage-124.pdf
│   ├── JavaScript Security.key/Data/droppedImage-127.pdf
│   ├── JavaScript Security.key/Data/droppedImage-130.pdf
│   ├── JavaScript Security.key/Data/droppedImage-135.pdf
│   ├── JavaScript Security.key/Data/droppedImage-139.pdf
│   ├── JavaScript Security.key/Data/droppedImage-152.pdf
│   ├── JavaScript Security.key/Data/droppedImage-155.pdf
│   ├── JavaScript Security.key/Data/droppedImage-small-113.png
│   ├── JavaScript Security.key/Data/droppedImage-small-115.png
│   ├── JavaScript Security.key/Data/droppedImage-small-125.png
│   ├── JavaScript Security.key/Data/droppedImage-small-128.png
│   ├── JavaScript Security.key/Data/droppedImage-small-131.png
│   ├── JavaScript Security.key/Data/droppedImage-small-136.png
│   ├── JavaScript Security.key/Data/droppedImage-small-140.png
│   ├── JavaScript Security.key/Data/droppedImage-small-153.png
│   ├── JavaScript Security.key/Data/droppedImage-small-156.png
│   ├── JavaScript Security.key/Data/mt0@2x-166.jpg
│   ├── JavaScript Security.key/Data/mt10@2x-176.jpg
│   ├── JavaScript Security.key/Data/mt11@2x-177.jpg
│   ├── JavaScript Security.key/Data/mt12@2x-178.jpg
│   ├── JavaScript Security.key/Data/mt13@2x-179.jpg
│   ├── JavaScript Security.key/Data/mt1@2x-167.jpg
│   ├── JavaScript Security.key/Data/mt2@2x-168.jpg
│   ├── JavaScript Security.key/Data/mt3@2x-169.jpg
│   ├── JavaScript Security.key/Data/mt4@2x-170.jpg
│   ├── JavaScript Security.key/Data/mt5@2x-171.jpg
│   ├── JavaScript Security.key/Data/mt6@2x-172.jpg
│   ├── JavaScript Security.key/Data/mt7@2x-173.jpg
│   ├── JavaScript Security.key/Data/mt8@2x-174.jpg
│   ├── JavaScript Security.key/Data/mt9@2x-175.jpg
│   ├── JavaScript Security.key/Data/st0-122.jpg
│   ├── JavaScript Security.key/Data/st1-123.jpg
│   ├── JavaScript Security.key/Data/st2-126.jpg
│   ├── JavaScript Security.key/Data/st2-129.jpg
│   ├── JavaScript Security.key/Data/st2-141.jpg
│   ├── JavaScript Security.key/Data/st2-143.jpg
│   ├── JavaScript Security.key/Data/st24-158.jpg
│   ├── JavaScript Security.key/Data/st30-164.jpg
│   ├── JavaScript Security.key/Data/st31-165.jpg
│   ├── JavaScript Security.key/Data/st4-132.jpg
│   ├── JavaScript Security.key/Data/st4-133.jpg
│   ├── JavaScript Security.key/Data/st4-134.jpg
│   ├── JavaScript Security.key/Data/st4-137.jpg
│   ├── JavaScript Security.key/Data/st4-138.jpg
│   ├── JavaScript Security.key/Data/st4-142.jpg
│   ├── JavaScript Security.key/Data/st4-146.jpg
│   ├── JavaScript Security.key/Data/st4-147.jpg
│   ├── JavaScript Security.key/Data/st4-148.jpg
│   ├── JavaScript Security.key/Data/st4-149.jpg
│   ├── JavaScript Security.key/Data/st4-150.jpg
│   ├── JavaScript Security.key/Data/st4-151.jpg
│   ├── JavaScript Security.key/Data/st4-154.jpg
│   ├── JavaScript Security.key/Data/st4-157.jpg
│   ├── JavaScript Security.key/Data/st4-159.jpg
│   ├── JavaScript Security.key/Data/st4-160.jpg
│   ├── JavaScript Security.key/Data/st4-161.jpg
│   ├── JavaScript Security.key/Data/st4-162.jpg
│   ├── JavaScript Security.key/Data/st4-163.jpg
│   ├── JavaScript Security.key/Data/st8-144.jpg
│   ├── JavaScript Security.key/Data/st8-145.jpg
│   ├── JavaScript Security.key/Data/tile_paper_blue-89.jpg
│   ├── JavaScript Security.key/Data/tile_paper_gray-105.jpg
│   ├── JavaScript Security.key/Data/tile_paper_green-101.jpg
│   ├── JavaScript Security.key/Data/tile_paper_purple-109.jpg
│   ├── JavaScript Security.key/Data/tile_paper_red-93.jpg
│   └── JavaScript Security.key/Data/tile_paper_yellow-97.jpg
├── JavaScript Security.key/Index.zip
├── JavaScript Security.key/Metadata/
│   ├── JavaScript Security.key/Metadata/BuildVersionHistory.plist
│   ├── JavaScript Security.key/Metadata/DocumentIdentifier
│   └── JavaScript Security.key/Metadata/Properties.plist
├── JavaScript Security.key/preview-micro.jpg
├── JavaScript Security.key/preview-web.jpg
└── JavaScript Security.key/preview.jpg

2 directories, 79 files
sathomas commented 10 years ago

After a bit of research and console debugging, I've got a few ideas on how to handle file packages.

File Packages and Firefox

Since Firefox is (at the moment) philosophically opposed to the HTML5 FileSystem API, the options are somewhat limited. The following steps, though, are possible.

File Packages and Safari

For Safari we can accept file packages for upload. We just need to append a .zip extension. The approach could go something like.

File Packages and Chrome

The approach for Chrome is similar to Firefox but with different details

Because Chrome does support the FileSystem API, there is an alternative. (Normally I'd hesitate to recommend it in case I ended up having to implement it, but I'm pretty confident that no one will seriously consider it.) For completeness:

There are obvious edge cases that could fool the approaches described above, but I expect they'd be pretty rare.

nicolaasmatthijs commented 10 years ago

Moved this to the technical priorities list as this is not an immediate priority.