Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
PLT-5702 Added special error page for private browsing error message (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
hmhealey authored and jwilander committed Apr 4, 2017
1 parent 5dcb159 commit 812f1d5
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 28 deletions.
112 changes: 93 additions & 19 deletions components/error_page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,27 @@
// See License.txt for license information.

import $ from 'jquery';

import React from 'react';
import {FormattedMessage} from 'react-intl';
import {Link} from 'react-router/es6';

import * as Utils from 'utils/utils.jsx';
import {ErrorPageTypes} from 'utils/constants.jsx';
import * as TextFormatting from 'utils/text_formatting.jsx';
import * as Utils from 'utils/utils.jsx';

export default class ErrorPage extends React.Component {
static propTypes = {
location: React.PropTypes.object.isRequired
};

constructor(props) {
super(props);

this.renderTitle = this.renderTitle.bind(this);
this.renderMessage = this.renderMessage.bind(this);
this.renderLink = this.renderLink.bind(this);
}

componentDidMount() {
$('body').attr('class', 'sticky error');
}
Expand All @@ -18,47 +31,108 @@ export default class ErrorPage extends React.Component {
$('body').attr('class', '');
}

render() {
let title = this.props.location.query.title;
if (!title || title === '') {
title = Utils.localizeMessage('error.generic.title', 'Error');
linkFilter(link) {
return link.startsWith('https://docs.mattermost.com') || link.startsWith('https://forum.mattermost.org');
}

renderTitle() {
if (this.props.location.query.type === ErrorPageTypes.LOCAL_STORAGE) {
return (
<FormattedMessage
id='error.local_storage.title'
defaultMessage='Cannot Load Mattermost'
/>
);
}

if (this.props.location.query.title) {
return this.props.location.query.title;
}

return Utils.localizeMessage('error.generic.title', 'Error');
}

renderMessage() {
if (this.props.location.query.type === ErrorPageTypes.LOCAL_STORAGE) {
return (
<div>
<FormattedMessage
id='error.local_storage.message'
defaultMessage='Mattermost was unable to load because a setting in your browser prevents the use of its local storage features. To allow Mattermost to load, try the following actions:'
/>
<ul>
<li>
<FormattedMessage
id='error.local_storage.help1'
defaultMessage='Enable cookies'
/>
</li>
<li>
<FormattedMessage
id='error.local_storage.help2'
defaultMessage='Turn off private browsing'
/>
</li>
<li>
<FormattedMessage
id='error.local_storage.help3'
defaultMessage='Use a supported browser (IE 11, Chrome 43+, Firefox 38+, Safari 9, Edge)'
/>
</li>
</ul>
</div>
);
}

let message = this.props.location.query.message;
if (!message || message === '') {
if (!message) {
message = Utils.localizeMessage('error.generic.message', 'An error has occoured.');
}

return <div dangerouslySetInnerHTML={{__html: TextFormatting.formatText(message, {linkFilter: this.linkFilter})}}/>;
}

renderLink() {
let link = this.props.location.query.link;
if (!link || link === '') {
if (link) {
link = link.trim();
} else {
link = '/';
} else if (link.startsWith('javascript:') || link.startsWith('vbscript:') || link.startsWith('data:')) { // eslint-disable-line no-script-url
// Sanitize out any script links
}

if (!link.startsWith('/')) {
// Only allow relative links
link = '/';
}

let linkMessage = this.props.location.query.linkmessage;
if (!linkMessage || linkMessage === '') {
if (!linkMessage) {
linkMessage = Utils.localizeMessage('error.generic.link_message', 'Back to Mattermost');
}

return (
<Link to={link}>
{linkMessage}
</Link>
);
}

render() {
const title = this.renderTitle();
const message = this.renderMessage();
const link = this.renderLink();

return (
<div className='container-fluid'>
<div className='error__container'>
<div className='error__icon'>
<i className='fa fa-exclamation-triangle'/>
</div>
<h2>{title}</h2>
<div dangerouslySetInnerHTML={{__html: TextFormatting.formatText(message)}}/>
<Link to={link}>{linkMessage}</Link>
{message}
{link}
</div>
</div>
);
}
}

ErrorPage.defaultProps = {
};
ErrorPage.propTypes = {
location: React.PropTypes.object
};
2 changes: 0 additions & 2 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1307,8 +1307,6 @@
"error.not_found.link_message": "Back to Mattermost",
"error.not_found.message": "The page you were trying to reach does not exist",
"error.not_found.title": "Page not found",
"error.not_supported.message": "Private browsing is not supported",
"error.not_supported.title": "Browser not supported",
"error_bar.expired": "Enterprise license is expired and some features may be disabled. <a href='{link}' target='_blank'>Please renew.</a>",
"error_bar.expiring": "Enterprise license expires on {date}. <a href='{link}' target='_blank'>Please renew.</a>",
"error_bar.past_grace": "Enterprise license is expired and some features may be disabled. Please contact your System Administrator for details.",
Expand Down
9 changes: 2 additions & 7 deletions stores/browser_store.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@

import {browserHistory} from 'react-router/es6';
import * as Utils from 'utils/utils.jsx';
import Constants from 'utils/constants.jsx';

const notSupportedParams = {
title: Utils.localizeMessage('error.not_supported.title', 'Browser not supported'),
message: Utils.localizeMessage('error.not_supported.message', 'Private browsing is not supported')
};
import {Constants, ErrorPageTypes} from 'utils/constants.jsx';

function getPrefix() {
if (global.window.mm_current_user_id) {
Expand Down Expand Up @@ -200,7 +195,7 @@ class BrowserStoreClass {
sessionStorage.removeItem('__testSession__');
} catch (e) {
// Session storage not usable, website is unusable
browserHistory.push(window.location.origin + '/error?title=' + notSupportedParams.title + '&message=' + notSupportedParams.message);
browserHistory.push('/error?type=' + ErrorPageTypes.LOCAL_STORAGE);
}

this.hasCheckedLocalStorage = true;
Expand Down
6 changes: 6 additions & 0 deletions utils/constants.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ export const StatTypes = keyMirror({
MONTHLY_ACTIVE_USERS: null
});

export const ErrorPageTypes = {
LOCAL_STORAGE: 'local_storage'
};

export const Constants = {
Preferences,
SocketEvents,
Expand All @@ -290,6 +294,8 @@ export const Constants = {
UserSearchOptions,
TutorialSteps,
PostTypes,
ErrorPageTypes,

IGNORE_POST_TYPES: [PostTypes.JOIN_LEAVE, PostTypes.JOIN_CHANNEL, PostTypes.LEAVE_CHANNEL, PostTypes.REMOVE_FROM_CHANNEL, PostTypes.ADD_TO_CHANNEL, PostTypes.ADD_REMOVE],

PayloadSources: keyMirror({
Expand Down
4 changes: 4 additions & 0 deletions utils/markdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ class MattermostMarkdownRenderer extends marked.Renderer {
link(href, title, text) {
let outHref = href;

if (this.formattingOptions.linkFilter && !this.formattingOptions.linkFilter(outHref)) {
return text;
}

try {
let unescaped = unescape(href);
try {
Expand Down

0 comments on commit 812f1d5

Please sign in to comment.