fix(github-graphql): use getMediaDisplayURL to load media with auth header (#2652)

This commit is contained in:
Erez Rokah 2019-09-05 01:56:06 +03:00 committed by Shawn Erquhart
parent a801636967
commit e674e43f9f
7 changed files with 42 additions and 16 deletions

View File

@ -102,14 +102,14 @@ export default class API {
return textPromise;
}
request(path, options = {}) {
request(path, options = {}, parseResponse = response => this.parseResponse(response)) {
const headers = this.requestHeaders(options.headers || {});
const url = this.urlFor(path, options);
let responseStatus;
return fetch(url, { ...options, headers })
.then(response => {
responseStatus = response.status;
return this.parseResponse(response);
return parseResponse(response);
})
.catch(error => {
throw new APIError(error.message, responseStatus, 'GitHub');

View File

@ -170,7 +170,7 @@ export default class GraphQLAPI extends API {
} else if (!is_binary) {
return text;
} else {
return super.retrieveBlob(sha);
return super.retrieveBlob(sha, repoURL);
}
}
@ -194,12 +194,13 @@ export default class GraphQLAPI extends API {
});
if (data.repository.object) {
const files = data.repository.object.entries.map(e => ({
...e,
path: `${path}/${e.name}`,
download_url: `https://raw.githubusercontent.com/${this.repo}/${this.branch}/${path}/${e.name}`,
size: e.blob && e.blob.size,
}));
const files = data.repository.object.entries
.filter(({ type }) => type === 'blob')
.map(e => ({
...e,
path: `${path}/${e.name}`,
size: e.blob && e.blob.size,
}));
return files;
} else {
throw new APIError('Not Found', 404, 'GitHub');
@ -589,15 +590,15 @@ export default class GraphQLAPI extends API {
let entries = null;
if (commitTree.data.repository.commit.tree) {
entries = commitTree.data.repository.commit.tree.entries;
({ entries, sha } = commitTree.data.repository.commit.tree);
}
if (tree.data.repository.tree.entries) {
entries = tree.data.repository.tree.entries;
({ entries, sha } = tree.data.repository.tree);
}
if (entries) {
return { tree: entries.map(e => ({ ...e, mode: TREE_ENTRY_TYPE_TO_MODE[e.type] })) };
return { sha, tree: entries.map(e => ({ ...e, mode: TREE_ENTRY_TYPE_TO_MODE[e.type] })) };
}
return Promise.reject('Could not get tree');

View File

@ -67,6 +67,7 @@ export const fileEntry = gql`
fragment FileEntryParts on TreeEntry {
name
sha: oid
type
blob: object {
... on Blob {
size: byteSize

View File

@ -259,15 +259,34 @@ export default class GitHub {
getMedia() {
return this.api.listFiles(this.config.get('media_folder')).then(files =>
files.map(({ sha, name, size, download_url, path }) => {
const url = new URL(download_url);
if (url.pathname.match(/.svg$/)) {
url.search += (url.search.slice(1) === '' ? '?' : '&') + 'sanitize=true';
if (download_url) {
const url = new URL(download_url);
if (url.pathname.match(/.svg$/)) {
url.search += (url.search.slice(1) === '' ? '?' : '&') + 'sanitize=true';
}
// if 'displayURL' is a string it will be loaded as is
return { id: sha, name, size, displayURL: url.href, path };
} else {
// if 'displayURL' is not a string it will be loaded using getMediaDisplayURL
return { id: sha, name, size, displayURL: { sha }, path };
}
return { id: sha, name, size, displayURL: url.href, path };
}),
);
}
async getMediaDisplayURL(displayURL) {
const { sha } = displayURL;
const blob = await this.api.request(
`${this.api.repoURL}/git/blobs/${sha}`,
{
headers: { Accept: 'application/vnd.github.VERSION.raw' },
},
response => response.blob(),
);
return URL.createObjectURL(blob);
}
persistEntry(entry, mediaFiles = [], options = {}) {
return this.api.persistFiles(entry, mediaFiles, options);
}

View File

@ -100,6 +100,8 @@ MediaLibraryCard.propTypes = {
margin: PropTypes.string.isRequired,
isPrivate: PropTypes.bool,
type: PropTypes.string,
isViewableImage: PropTypes.bool.isRequired,
loadDisplayURL: PropTypes.func.isRequired,
};
export default MediaLibraryCard;

View File

@ -86,6 +86,7 @@ MediaLibraryCardGrid.propTypes = {
cardMargin: PropTypes.string.isRequired,
loadDisplayURL: PropTypes.func.isRequired,
isPrivate: PropTypes.bool,
displayURLs: PropTypes.instanceOf(Map).isRequired,
};
export default MediaLibraryCardGrid;

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from '@emotion/styled';
import { Map } from 'immutable';
import { isEmpty } from 'lodash';
import { translate } from 'react-polyglot';
import { Modal } from 'UI';
@ -219,6 +220,7 @@ MediaLibraryModal.propTypes = {
handleLoadMore: PropTypes.func.isRequired,
loadDisplayURL: PropTypes.func.isRequired,
t: PropTypes.func.isRequired,
displayURLs: PropTypes.instanceOf(Map).isRequired,
};
export default translate()(MediaLibraryModal);