From 81a952c0d8208eaf67fc2b43f27f13afd637240b Mon Sep 17 00:00:00 2001 From: Juan Carlos Farah Date: Thu, 16 May 2019 11:03:36 +0200 Subject: [PATCH] fix: provide better error handling for invalid space ids closes #81 --- package.json | 1 + src/Styles.js | 3 + src/components/VisitSpace.js | 19 ++-- src/components/space/SpaceNotFound.js | 132 +++++++++++++++++++++++--- src/config/constants.js | 1 + src/config/messages.js | 2 + src/utils/validators.js | 12 +++ yarn.lock | 5 + 8 files changed, 155 insertions(+), 20 deletions(-) create mode 100644 src/utils/validators.js diff --git a/package.json b/package.json index d8e9f282..a52164b7 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "@sentry/browser": "5.1.1", "@sentry/electron": "0.17.1", "archiver": "3.0.0", + "bson-objectid": "1.2.5", "cheerio": "1.0.0-rc.3", "classnames": "2.2.6", "connected-react-router": "6.4.0", diff --git a/src/Styles.js b/src/Styles.js index 483f2acd..e39b2e0d 100644 --- a/src/Styles.js +++ b/src/Styles.js @@ -58,6 +58,9 @@ const Styles = theme => ({ input: { margin: theme.spacing.unit, }, + button: { + margin: theme.spacing.unit, + }, }); export default Styles; diff --git a/src/components/VisitSpace.js b/src/components/VisitSpace.js index 11f10773..7d7ca824 100644 --- a/src/components/VisitSpace.js +++ b/src/components/VisitSpace.js @@ -22,9 +22,11 @@ import Styles from '../Styles'; import Loader from './LoadSpace'; import { ERROR_MESSAGE_HEADER, + INVALID_SPACE_ID, OFFLINE_ERROR_MESSAGE, } from '../config/messages'; import MainMenu from './common/MainMenu'; +import { isValidSpaceId } from '../utils/validators'; class VisitSpace extends Component { state = { @@ -64,6 +66,9 @@ class VisitSpace extends Component { if (!window.navigator.onLine) { return toastr.error(ERROR_MESSAGE_HEADER, OFFLINE_ERROR_MESSAGE); } + if (!isValidSpaceId(id)) { + return toastr.error(ERROR_MESSAGE_HEADER, INVALID_SPACE_ID); + } if (id && id !== '') { const { replace } = history; return replace(`/space/${id}`); @@ -71,6 +76,12 @@ class VisitSpace extends Component { return false; }; + handleKeyPress = event => { + if (event.key === 'Enter') { + this.handleClick(); + } + }; + render() { const { classes, theme, activity } = this.props; const { open, spaceId } = this.state; @@ -137,12 +148,7 @@ class VisitSpace extends Component { >
- + Visit a Space { - return ( -
- Space not found. - -
- ); -}; +class SpaceNotFound extends Component { + state = { + open: false, + }; -SpaceNotFound.propTypes = { - history: PropTypes.shape({ length: PropTypes.number.isRequired }).isRequired, -}; + static propTypes = { + classes: PropTypes.shape({}).isRequired, + theme: PropTypes.shape({}).isRequired, + history: PropTypes.shape({ length: PropTypes.number.isRequired }) + .isRequired, + }; -export default withRouter(SpaceNotFound); + handleDrawerOpen = () => { + this.setState({ open: true }); + }; + + handleDrawerClose = () => { + this.setState({ open: false }); + }; + + render() { + const { open } = this.state; + const { + history: { replace }, + classes, + theme, + } = this.props; + return ( +
+ + + + + + + + + +
+ + {theme.direction === 'ltr' ? ( + + ) : ( + + )} + +
+ + +
+
+
+
+ + Space Not Found + + + +
+
+
+ ); + } +} + +const StyledComponent = withStyles(Styles, { withTheme: true })(SpaceNotFound); + +export default withRouter(StyledComponent); diff --git a/src/config/constants.js b/src/config/constants.js index b2120c01..245ccd8a 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -7,3 +7,4 @@ export const APPLICATION = 'Application'; export const IFRAME = 'application/octet-stream'; export const DEFAULT_RADIUS = 50; export const DEFAULT_LANGUAGE = 'en_all'; +export const SHORT_ID_LENGTH = 6; diff --git a/src/config/messages.js b/src/config/messages.js index 2f82f63e..78cb00ee 100644 --- a/src/config/messages.js +++ b/src/config/messages.js @@ -28,6 +28,7 @@ const ERROR_GETTING_USER_FOLDER = 'There was an error getting your user folder.'; const ERROR_GETTING_LANGUAGE = 'There was an error getting the language.'; const ERROR_SETTING_LANGUAGE = 'There was an error setting the language.'; +const INVALID_SPACE_ID = 'Invalid space ID.'; module.exports = { ERROR_GETTING_LANGUAGE, @@ -52,4 +53,5 @@ module.exports = { ERROR_GETTING_GEOLOCATION, ERROR_GETTING_SPACES_NEARBY, ERROR_GETTING_USER_FOLDER, + INVALID_SPACE_ID, }; diff --git a/src/utils/validators.js b/src/utils/validators.js new file mode 100644 index 00000000..31ca4d82 --- /dev/null +++ b/src/utils/validators.js @@ -0,0 +1,12 @@ +import ObjectId from 'bson-objectid'; +import { SHORT_ID_LENGTH } from '../config/constants'; + +const isValidSpaceShortId = id => { + return id.length === SHORT_ID_LENGTH && /^[a-z0-9]+$/i.test(id); +}; + +const isValidLongSpaceId = id => ObjectId.isValid(id); + +const isValidSpaceId = id => isValidLongSpaceId(id) || isValidSpaceShortId(id); + +export { isValidSpaceId, isValidLongSpaceId, isValidSpaceShortId }; diff --git a/yarn.lock b/yarn.lock index 849a8c61..ae7c2f4d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2841,6 +2841,11 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" +bson-objectid@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/bson-objectid/-/bson-objectid-1.2.5.tgz#622c0c9d40c02aece5ac5b61a70248ec303047f0" + integrity sha512-tKLZNr1eyK/Dd48k/5FHXmpN69dUHMioQCvNv1kxy8qJINkoyQkjf7+u933EZ77bMXC3lmN1HmyFm2WS6mRYxg== + buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"