diff --git a/package.json b/package.json index 7943d7eea..ec0a73b61 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "react-responsive": "3.0.0", "react-slick": "0.16.0", "react-string-replace": "0.4.1", - "scratch-gui": "0.1.0-prerelease.20190207214203", + "scratch-gui": "0.1.0-prerelease.20190213213304", "react-telephone-input": "4.3.4", "redux": "3.5.2", "redux-thunk": "2.0.1", diff --git a/src/redux/navigation.js b/src/redux/navigation.js index 40782c490..71459af75 100644 --- a/src/redux/navigation.js +++ b/src/redux/navigation.js @@ -2,6 +2,7 @@ const keyMirror = require('keymirror'); const defaults = require('lodash.defaults'); const api = require('../lib/api'); +const jar = require('../lib/jar'); const log = require('../lib/log.js'); const sessionActions = require('./session.js'); @@ -138,16 +139,20 @@ module.exports.handleLogIn = (formData, callback) => (dispatch => { }); }); -module.exports.handleLogOut = () => (dispatch => { - api({ - host: '', - method: 'post', - uri: '/accounts/logout/', - useCsrf: true - }, err => { - if (err) log.error(err); - dispatch(module.exports.setLoginOpen(false)); - dispatch(module.exports.setAccountNavOpen(false)); - window.location = '/'; +module.exports.handleLogOut = () => (() => { + // POST to /accounts/logout using a dummy form instead of XHR. This ensures + // logout only happens AFTER onbeforeunload has the chance to prevent nagivation. + jar.use('scratchcsrftoken', '/csrf_token/', (err, csrftoken) => { + if (err) return log.error('Error while retrieving CSRF token', err); + const form = document.createElement('form'); + form.setAttribute('method', 'POST'); + form.setAttribute('action', '/accounts/logout/'); + const csrfField = document.createElement('input'); + csrfField.setAttribute('type', 'hidden'); + csrfField.setAttribute('name', 'csrfmiddlewaretoken'); + csrfField.setAttribute('value', csrftoken); + form.appendChild(csrfField); + document.body.appendChild(form); + form.submit(); }); }); diff --git a/src/views/preview/censored-message.jsx b/src/views/preview/censored-message.jsx index b8eb01f0e..c6d35b585 100644 --- a/src/views/preview/censored-message.jsx +++ b/src/views/preview/censored-message.jsx @@ -15,29 +15,42 @@ const communityGuidelinesLink = ( ); -const CensoredMessage = ({messageHTML, reshareable}) => ( +const CensoredMessage = ({censoredByCommunity, messageHTML, reshareable}) => ( {/* if message HTML is provided, set innerHTML with it */} - {messageHTML ? embedCensorMessage(messageHTML) : ( - // if message is blank or missing, use default - - -
-
- {reshareable ? ( + {messageHTML ? embedCensorMessage(messageHTML) : + (censoredByCommunity ? ( + + +
+
- ) : ( - - )} -
- )} +
+ ) : ( + // if message is blank or missing, use default + + +
+
+ {reshareable ? ( + + ) : ( + + )} +
+ )) + }
); CensoredMessage.propTypes = { + censoredByCommunity: PropTypes.bool, messageHTML: PropTypes.string, reshareable: PropTypes.bool }; diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index 92f20cc42..d6cae775a 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -144,6 +144,7 @@ const PreviewPresentation = ({ } else if (visibilityInfo.censored) { const censoredMessage = ( @@ -730,6 +731,8 @@ PreviewPresentation.propTypes = { userOwnsProject: PropTypes.bool, visibilityInfo: PropTypes.shape({ censored: PropTypes.bool, + censoredByAdmin: PropTypes.bool, + censoredByCommunity: PropTypes.bool, message: PropTypes.string, deleted: PropTypes.bool, reshareable: PropTypes.bool diff --git a/src/views/preview/project-view.jsx b/src/views/preview/project-view.jsx index d09e735cd..75a3b1f89 100644 --- a/src/views/preview/project-view.jsx +++ b/src/views/preview/project-view.jsx @@ -410,6 +410,9 @@ class Preview extends React.Component { this.setState({isProjectLoaded: true}); } pushHistory (push) { + // Do not push history for projects without a real ID + if (this.state.projectId === '0') return; + // update URI to match mode const idPath = this.state.projectId ? `${this.state.projectId}/` : ''; let modePath = ''; @@ -829,6 +832,8 @@ Preview.propTypes = { userPresent: PropTypes.bool, visibilityInfo: PropTypes.shape({ censored: PropTypes.bool, + censoredByAdmin: PropTypes.bool, + censoredByCommunity: PropTypes.bool, message: PropTypes.string, deleted: PropTypes.bool, reshareable: PropTypes.bool