Browse Source

Merge pull request #6686 from tslaton/fix-chrome-downloads

Fix downloads in Chrome with xsrf token
Steven Silvester 5 years ago
parent
commit
91eb753f19
2 changed files with 18 additions and 21 deletions
  1. 12 18
      packages/filebrowser/src/model.ts
  2. 6 3
      packages/services/src/contents/index.ts

+ 12 - 18
packages/filebrowser/src/model.ts

@@ -312,24 +312,18 @@ export class FileBrowserModel implements IDisposable {
    * @returns A promise which resolves when the file has begun
    *   downloading.
    */
-  download(path: string): Promise<void> {
-    return this.manager.services.contents.getDownloadUrl(path).then(url => {
-      // Check the browser is Chrome https://stackoverflow.com/a/9851769
-      const chrome = (window as any).chrome;
-      const isChrome = !!chrome && (!!chrome.webstore || !!chrome.runtime);
-      if (isChrome) {
-        // Workaround https://bugs.chromium.org/p/chromium/issues/detail?id=455987
-        window.open(url);
-      } else {
-        let element = document.createElement('a');
-        document.body.appendChild(element);
-        element.setAttribute('href', url);
-        element.setAttribute('download', '');
-        element.click();
-        document.body.removeChild(element);
-        return void 0;
-      }
-    });
+  async download(path: string): Promise<void> {
+    const url = await this.manager.services.contents.getDownloadUrl(path);
+    let element = document.createElement('a');
+    document.body.appendChild(element);
+    element.setAttribute('href', url);
+    // Chrome doesn't get the right name automatically
+    const parts = path.split('/');
+    const name = parts[parts.length - 1];
+    element.setAttribute('download', name);
+    element.click();
+    document.body.removeChild(element);
+    return void 0;
   }
 
   /**

+ 6 - 3
packages/services/src/contents/index.ts

@@ -1044,9 +1044,12 @@ export class Drive implements Contents.IDrive {
    */
   getDownloadUrl(localPath: string): Promise<string> {
     let baseUrl = this.serverSettings.baseUrl;
-    return Promise.resolve(
-      URLExt.join(baseUrl, FILES_URL, URLExt.encodeParts(localPath))
-    );
+    let url = URLExt.join(baseUrl, FILES_URL, URLExt.encodeParts(localPath));
+    const xsrfTokenMatch = document.cookie.match('\\b_xsrf=([^;]*)\\b');
+    if (xsrfTokenMatch) {
+      url = URLExt.join(url, `?_xsrf=${xsrfTokenMatch[1]}`);
+    }
+    return Promise.resolve(url);
   }
 
   /**