mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
Add component for signing S3 url
This commit is contained in:
parent
2cb8fb2dd9
commit
f2c7f02480
91
js/components/ascribe_buttons/s3_download_button.js
Normal file
91
js/components/ascribe_buttons/s3_download_button.js
Normal file
@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import S3Fetcher from '../../fetchers/s3_fetcher';
|
||||
|
||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
import { queryParamsToArgs } from '../../utils/url_utils';
|
||||
|
||||
|
||||
const { string } = React.PropTypes;
|
||||
|
||||
const S3DownloadButton = React.createClass({
|
||||
propTypes: {
|
||||
url: string,
|
||||
title: string,
|
||||
artistName: string,
|
||||
fileExtension: string
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
downloadUrl: null
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
/**
|
||||
* Initially, we request a signed url from
|
||||
* the backend
|
||||
*/
|
||||
this.signUrl();
|
||||
},
|
||||
|
||||
transformS3UrlToS3Key(url) {
|
||||
return url.replace(`https://${AppConstants.cloudfrontDomain}/`, '');
|
||||
},
|
||||
|
||||
signUrl(next) {
|
||||
const { url, title, artistName } = this.props;
|
||||
|
||||
S3Fetcher
|
||||
.signUrl(this.transformS3UrlToS3Key(url), title, artistName)
|
||||
.then(({ signed_url: downloadUrl }) => this.setState({ downloadUrl }, next))
|
||||
.catch(console.logGlobal);
|
||||
},
|
||||
|
||||
reSignUrl(event) {
|
||||
/**
|
||||
* The signed url, however can expire, which is why
|
||||
* we need to renew it when it expires.
|
||||
*/
|
||||
const { downloadUrl } = this.state;
|
||||
const { expires } = queryParamsToArgs(downloadUrl.split('?')[1]);
|
||||
const nowInSeconds = new Date().getTime() / 1000;
|
||||
|
||||
if(nowInSeconds > expires) {
|
||||
event.preventDefault();
|
||||
this.signUrl(() => this.refs.downloadButton.getDOMNode().click());
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const { fileExtension, url } = this.props;
|
||||
const { downloadUrl } = this.state;
|
||||
|
||||
return (
|
||||
<span>
|
||||
<a
|
||||
ref="downloadButton"
|
||||
download
|
||||
className="btn btn-xs btn-default ascribe-margin-1px"
|
||||
target="_blank"
|
||||
onClick={this.reSignUrl}
|
||||
href={downloadUrl || url}>
|
||||
{/*
|
||||
If it turns out that `fileExtension` is an empty string, we're just
|
||||
using the label 'file'.
|
||||
*/}
|
||||
{getLangText('Download')} .{fileExtension || 'file'} <Glyphicon glyph="cloud-download" />
|
||||
</a>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default S3DownloadButton;
|
@ -3,13 +3,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import Button from 'react-bootstrap/lib/Button';
|
||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||
|
||||
import MediaPlayer from './../ascribe_media/media_player';
|
||||
|
||||
import FacebookShareButton from '../ascribe_social_share/facebook_share_button';
|
||||
import TwitterShareButton from '../ascribe_social_share/twitter_share_button';
|
||||
|
||||
import S3DownloadButton from '../ascribe_buttons/s3_download_button';
|
||||
|
||||
import CollapsibleButton from './../ascribe_collapsible/collapsible_button';
|
||||
|
||||
import AclProxy from '../acl_proxy';
|
||||
@ -131,17 +132,11 @@ let MediaContainer = React.createClass({
|
||||
show={['video', 'audio', 'image'].indexOf(mimetype) === -1 || content.acl.acl_download}
|
||||
aclObject={content.acl}
|
||||
aclName="acl_download">
|
||||
<a
|
||||
download
|
||||
className="btn btn-xs btn-default ascribe-margin-1px"
|
||||
href={content.digital_work.url}
|
||||
target="_blank">
|
||||
{/*
|
||||
If it turns out that `fileExtension` is an empty string, we're just
|
||||
using the label 'file'.
|
||||
*/}
|
||||
{getLangText('Download')} .{fileExtension || 'file'} <Glyphicon glyph="cloud-download" />
|
||||
</a>
|
||||
<S3DownloadButton
|
||||
url={content.digital_work.url}
|
||||
title={content.title}
|
||||
artistName={content.artist_name}
|
||||
fileExtension={fileExtension} />
|
||||
</AclProxy>
|
||||
{embed}
|
||||
</p>
|
||||
|
@ -76,7 +76,8 @@ let ApiUrls = {
|
||||
'webhooks': AppConstants.apiEndpoint + 'webhooks/',
|
||||
'webhooks_events': AppConstants.apiEndpoint + 'webhooks/events/',
|
||||
'whitelabel_settings': AppConstants.apiEndpoint + 'whitelabel/settings/${subdomain}/',
|
||||
'delete_s3_file': AppConstants.serverUrl + 's3/delete/'
|
||||
'delete_s3_file': AppConstants.serverUrl + 's3/delete/',
|
||||
'sign_url_s3': AppConstants.serverUrl + 's3/sign_url/'
|
||||
};
|
||||
|
||||
|
||||
|
@ -119,7 +119,7 @@ const constants = {
|
||||
'twitter': {
|
||||
'sdkUrl': 'https://platform.twitter.com/widgets.js'
|
||||
},
|
||||
|
||||
'cloudfrontDomain': 'd1qjsxua1o9x03.cloudfront.net',
|
||||
'errorMessagesToIgnore': [
|
||||
'Authentication credentials were not provided.',
|
||||
'Informations d\'authentification non fournies.'
|
||||
|
@ -11,6 +11,13 @@ let S3Fetcher = {
|
||||
key,
|
||||
bucket
|
||||
});
|
||||
},
|
||||
signUrl(key, title, artistName) {
|
||||
return requests.get('sign_url_s3', {
|
||||
'artist_name': artistName,
|
||||
key,
|
||||
title
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -70,7 +70,7 @@ class Requests {
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getUrl(url) {
|
||||
|
Loading…
Reference in New Issue
Block a user