Skip to content

Commit

Permalink
Merge pull request #22016 from code-dot-org/dashboard-restrict-share-…
Browse files Browse the repository at this point in the history
…buttons

Dashboard: restrict social sharing links
  • Loading branch information
breville committed Apr 26, 2018
2 parents 6321451 + 2e434b9 commit ef41305
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 18 deletions.
4 changes: 2 additions & 2 deletions apps/src/code-studio/components/ShareAllowedDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ class ShareAllowedDialog extends React.Component {
// check if twitter and facebook are actually available
// and not blocked by network firewall
checkImageReachability(
'https://graph.facebook.com/Code.org/picture',
'https://facebook.com/favicon.ico',
isFacebookAvailable => this.setState({isFacebookAvailable})
);
checkImageReachability(
'https://twitter.com/codeorg/profile_image?size=mini',
'https://twitter.com/favicon.ico',
isTwitterAvailable => this.setState({isTwitterAvailable})
);
}
Expand Down
4 changes: 2 additions & 2 deletions apps/src/code-studio/headerShare.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export function shareProject(shareUrl) {
const appType = dashboard.project.getStandaloneApp();

// Allow publishing for any project type that older students can publish.
// Younger students should never be able to get to the share dialog in the
// first place, so there's no need to check age against project types here.
// Younger students can now get to the share dialog if their teacher allows
// it, and should be able to publish in that case.
const canPublish = !!appOptions.isSignedIn &&
PublishableProjectTypesOver13.includes(appType);

Expand Down
8 changes: 7 additions & 1 deletion apps/src/code-studio/url_test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// Tests whether the browser can access an image URL.
// Useful as a workaround for CORS security to test access to an origin.
function testImageAccess(url, successCallback, failureCallback, timeoutMs = 5000, videoElement = false) {
function testImageAccess(
url,
successCallback = () => {},
failureCallback = () => {},
timeoutMs = 5000,
videoElement = false
) {
var element;
if (videoElement) {
element = document.createElement('video');
Expand Down
17 changes: 17 additions & 0 deletions apps/src/feedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
PUBLISH_FAILURE,
} from './templates/publishDialog/publishDialogRedux';
import {createHiddenPrintWindow} from './utils';
import testImageAccess from './code-studio/url_test';

// Types of blocks that do not count toward displayed block count. Used
// by FeedbackUtils.blockShouldBeCounted_
Expand Down Expand Up @@ -891,6 +892,22 @@ FeedbackUtils.prototype.createSharingDiv = function (options) {
});
}

var sharingFacebook = sharingDiv.querySelector('#sharing-facebook');
if (sharingFacebook) {
testImageAccess(
'https://facebook.com/favicon.ico' + "?" + Math.random(),
() => $(sharingFacebook).show()
);
}

var sharingTwitter = sharingDiv.querySelector('#sharing-twitter');
if (sharingTwitter) {
testImageAccess(
'https://twitter.com/favicon.ico' + "?" + Math.random(),
() => $(sharingTwitter).show()
);
}

// SMS-to-phone feature
var sharingPhone = sharingDiv.querySelector('#sharing-phone');
if (sharingPhone && options.sendToPhone) {
Expand Down
4 changes: 3 additions & 1 deletion apps/src/templates/Certificate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Certificate extends Component {
certificateId: PropTypes.string,
randomDonorTwitter: PropTypes.string,
responsiveSize: PropTypes.oneOf(['lg', 'md', 'sm', 'xs']).isRequired,
userAge: PropTypes.number,
};

personalizeCertificate(session) {
Expand All @@ -79,7 +80,7 @@ class Certificate extends Component {
}

render() {
const {responsiveSize, tutorial, certificateId, randomDonorTwitter} = this.props;
const {responsiveSize, tutorial, certificateId, randomDonorTwitter, userAge} = this.props;
const certificate = certificateId || 'blank';
const personalizedCertificate = `${dashboard.CODE_ORG_URL}/api/hour/certificate/${certificate}.jpg`;
const blankCertificate = blankCertificates[tutorial] || blankCertificates.hourOfCode;
Expand Down Expand Up @@ -155,6 +156,7 @@ class Certificate extends Component {
facebook={facebook}
twitter={twitter}
print={print}
userAge={userAge}
/>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions apps/src/templates/Congrats.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export default class Congrats extends Component {
tutorial={tutorial}
certificateId={certificateId}
randomDonorTwitter={randomDonorTwitter}
userAge={userAge}
/>
{userType === "teacher" && isEnglish && (
<TeachersBeyondHoc/>
Expand Down
43 changes: 33 additions & 10 deletions apps/src/templates/SocialShare.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import React, { PropTypes, Component } from 'react';
import i18n from '@cdo/locale';
import color from '../util/color';
import testImageAccess from '../code-studio/url_test';

const styles = {
shareButton: {
Expand All @@ -16,24 +17,46 @@ export default class SocialShare extends Component {
facebook: PropTypes.string.isRequired,
twitter: PropTypes.string.isRequired,
print: PropTypes.string.isRequired,
userAge: PropTypes.number,
};

state = {
isTwitterAvailable: false,
isFacebookAvailable: false
};

componentDidMount() {
testImageAccess(
'https://facebook.com/favicon.ico' + "?" + Math.random(),
() => this.setState({isFacebookAvailable: true})
);
testImageAccess(
'https://twitter.com/favicon.ico' + "?" + Math.random(),
() => this.setState({isTwitterAvailable: true})
);
}

render() {
const facebookShareUrl = `https://www.facebook.com/sharer/sharer.php?${this.props.facebook}`;
const twitterShareUrl = `https://twitter.com/share?${this.props.twitter}`;
const under13 = this.props.userAge < 13;

return (
<div>
<a href={facebookShareUrl} target="_blank" onClick={dashboard.popupWindow}>
<button style={{background: color.facebook_blue, ...styles.shareButton}}>
<i className="fa fa-facebook" />
</button>
</a>
<a href={twitterShareUrl} target="_blank" onClick={dashboard.popupWindow}>
<button style={{background: color.twitter_blue, ...styles.shareButton}}>
<i className="fa fa-twitter" />
</button>
</a>
{!under13 && this.state.isFacebookAvailable && (
<a href={facebookShareUrl} target="_blank" onClick={dashboard.popupWindow}>
<button style={{background: color.facebook_blue, ...styles.shareButton}}>
<i className="fa fa-facebook" />
</button>
</a>
)}
{!under13 && this.state.isTwitterAvailable && (
<a href={twitterShareUrl} target="_blank" onClick={dashboard.popupWindow}>
<button style={{background: color.twitter_blue, ...styles.shareButton}}>
<i className="fa fa-twitter" />
</button>
</a>
)}
<a href={this.props.print}>
<button style={{background: color.charcoal, ...styles.shareButton}}>
<i className="fa fa-print" />
Expand Down
4 changes: 2 additions & 2 deletions apps/src/templates/sharing.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
</div>
<div class='social-buttons'>
<% if (options.facebookUrl) { -%>
<a href='<%= options.facebookUrl %>' target="_blank" class="popup-window">
<a id='sharing-facebook' href='<%= options.facebookUrl %>' target="_blank" class="popup-window" style="display: none">
<button>
<i class="fa fa-facebook fa-lg"></i>
</button>
</a>
<% } -%>
<% if (options.twitterUrl) { -%>
<a href='<%= options.twitterUrl %>' target="_blank" class="popup-window">
<a id='sharing-twitter' href='<%= options.twitterUrl %>' target="_blank" class="popup-window" style="display: none">
<button>
<i class="fa fa-twitter fa-lg"></i>
</button>
Expand Down

0 comments on commit ef41305

Please sign in to comment.