From 1261fae9aec40808c71bb705495d857a777025e6 Mon Sep 17 00:00:00 2001 From: Zane Claes Date: Sun, 25 Oct 2020 14:55:14 -0600 Subject: [PATCH] Guest login --- docs/about/contribution.md | 22 ++--- docs/features/advanced.md | 12 +++ src/app/containers/Header/Header.jsx | 10 ++- .../CreateWorkspace/CreateWorkspacePanel.jsx | 20 ++++- src/app/containers/Login/Login.jsx | 84 +++++++++++++++++-- src/app/i18n/cs/resource.json | 12 ++- src/app/i18n/de/resource.json | 12 ++- src/app/i18n/en/resource.json | 12 ++- src/app/i18n/es/resource.json | 12 ++- src/app/i18n/fr/resource.json | 12 ++- src/app/i18n/hu/resource.json | 12 ++- src/app/i18n/it/resource.json | 12 ++- src/app/i18n/ja/resource.json | 12 ++- src/app/i18n/nl/resource.json | 12 ++- src/app/i18n/pt-br/resource.json | 12 ++- src/app/i18n/ru/resource.json | 12 ++- src/app/i18n/tr/resource.json | 12 ++- src/app/i18n/zh-cn/resource.json | 12 ++- src/app/i18n/zh-tw/resource.json | 12 ++- src/app/lib/auth.js | 44 ++++++++-- src/app/lib/cookies.js | 35 ++++++++ src/server/access-control.js | 10 ++- src/server/api/api.users.js | 13 +++ 23 files changed, 359 insertions(+), 59 deletions(-) create mode 100644 docs/features/advanced.md create mode 100644 src/app/lib/cookies.js diff --git a/docs/about/contribution.md b/docs/about/contribution.md index c287928fd..bc6e0b604 100644 --- a/docs/about/contribution.md +++ b/docs/about/contribution.md @@ -11,22 +11,16 @@ Pull requests welcome! See [issues](/about/#issues) for reporting bugs or problems. -## Development +## Documentation -See the [build from source](/installation/build-from-source/) section to get started. +These docs are located within the same Github repository that is home to Makerverse. You'll find them in the `docs/` folder, stored as `.md` (markdown) files. Therefore, the contribution process is the same as changing the Makerverse code... -## Localization +## How to Contribute -If you'd like to help contribute translations, you can fork the repository, update resource files in the `src/app/i18n` directory, and create a pull request to submit your changes. +As with contributing to most Github projects, the process is to (1) fork the repository, (2) make and push changes, and then (3) create a pull request. The pull request can then be reviewed and accepted into Makerverse. ### Fork the repository -To fork the makerverse repository, click the Fork button in the header of the repository. - -![image](https://user-images.githubusercontent.com/447801/30472117-d757e742-9a2d-11e7-80f8-4ba9ffba97d8.png) - -When it’s finished, you’ll be taken to your copy of the makerverse repository. Now you can update the resource files on GitHub, or clone it to your computer. - If you're using GitHub for Desktop application, navigate over to the toolbar, open the Clone or download dropdown, and click Open in Desktop to clone makermadecnc/makerverse to your computer and use it in GitHub Desktop. ![image](https://user-images.githubusercontent.com/447801/30471510-956b51fe-9a2b-11e7-9e43-c5e3fa19e0cb.png) @@ -54,6 +48,14 @@ You can continue to make more changes and create new commits. When you’re read 4. That's done. +## Development + +See the [build from source](/installation/build-from-source/) section to get started. + +## Localization + +If you'd like to help contribute translations, you can fork the repository, update resource files in the `src/app/i18n` directory, and create a pull request to submit your changes. + ## Translation Validation You can validate the translation by copying translated resource files to the installed directory. Note that your path may differ based on the Node installation path you have in place. diff --git a/docs/features/advanced.md b/docs/features/advanced.md new file mode 100644 index 000000000..960f91206 --- /dev/null +++ b/docs/features/advanced.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Advanced +parent: Features +nav_order: 10 +--- + +# Advanced + +## Turn Off Login (Guest Mode) + +To enable guest mode, edit the `~/.makerverse` to include the top-level `insecureDangerousGuestAccess` boolean key. diff --git a/src/app/containers/Header/Header.jsx b/src/app/containers/Header/Header.jsx index 80d22d46c..1db214568 100644 --- a/src/app/containers/Header/Header.jsx +++ b/src/app/containers/Header/Header.jsx @@ -6,6 +6,7 @@ import { withRouter } from 'react-router-dom'; import without from 'lodash/without'; import Push from 'push.js'; import api from 'app/api'; +import { deleteCookie } from 'app/lib/cookies'; import { Tooltip } from 'app/components/Tooltip'; import Anchor from 'app/components/Anchor'; import Space from 'app/components/Space'; @@ -319,10 +320,13 @@ class Header extends PureComponent { { - if (auth.isAuthenticated()) { - log.debug('Destroy and cleanup the WebSocket connection'); - Workspaces.disconnect(); + log.debug('Destroy and cleanup the WebSocket connection'); + Workspaces.disconnect(); + deleteCookie(auth.GUEST_COOKIE_NAME); + if (auth.isGuest()) { + window.location.replace('/#/login'); + } else { auth.signout(); // Remember current location diff --git a/src/app/containers/Home/CreateWorkspace/CreateWorkspacePanel.jsx b/src/app/containers/Home/CreateWorkspace/CreateWorkspacePanel.jsx index 4c07a57e8..cec24f8ef 100644 --- a/src/app/containers/Home/CreateWorkspace/CreateWorkspacePanel.jsx +++ b/src/app/containers/Home/CreateWorkspace/CreateWorkspacePanel.jsx @@ -22,9 +22,10 @@ class CreateWorkspacePanel extends PureComponent { actions: PropTypes.object }; - state = { machineProfiles: null, isCustomMachine: false }; + state = { machineProfiles: null, isCustomMachine: false, fetchBegan: false }; - componentDidMount() { + fetchMachineProfiles() { + this.setState({ fetchBegan: true }); fetchMachineProfiles().then((res) => { this.setState({ machineProfiles: res }); }).catch((err) => { @@ -134,7 +135,7 @@ class CreateWorkspacePanel extends PureComponent { } render() { - const { isCustomMachine, machineProfiles } = this.state; + const { isCustomMachine, machineProfiles, fetchBegan } = this.state; const { connectionStatus, alertMessage } = this.props; const { firmware, customMachine, machineProfileId } = this.props.workspaceSettings; const { baudRate, controllerType } = firmware || {}; @@ -155,6 +156,19 @@ class CreateWorkspacePanel extends PureComponent { const sw2 = isCustomMachine ? 'Search for pre-configured machines' : 'Switch to manual connection mode'; + if (!fetchBegan) { + return ( +
+ +
+ ); + } + return (
diff --git a/src/app/containers/Login/Login.jsx b/src/app/containers/Login/Login.jsx index 12f9b97dd..a038447cd 100644 --- a/src/app/containers/Login/Login.jsx +++ b/src/app/containers/Login/Login.jsx @@ -2,10 +2,10 @@ import cx from 'classnames'; import qs from 'qs'; import React, { PureComponent } from 'react'; import { withRouter, Redirect } from 'react-router-dom'; -import Anchor from 'app/components/Anchor'; import Space from 'app/components/Space'; import i18n from 'app/lib/i18n'; import log from 'app/lib/log'; +import { setCookie, deleteCookie } from 'app/lib/cookies'; import auth from 'app/lib/auth'; import settings from 'app/config/settings'; import analytics from 'app/lib/analytics'; @@ -42,7 +42,36 @@ class Login extends PureComponent { authenticating: false, }); }); - } + }, + handleGuest: (event) => { + event.preventDefault(); + + if (this.state.useCookies) { + setCookie(auth.GUEST_COOKIE_NAME, '1'); + } else { + deleteCookie(auth.GUEST_COOKIE_NAME); + } + + this.setState({ + alertMessage: '', + authenticating: true, + redirectToReferrer: false, + }); + + auth.signin(null, true) + .then((r) => { + this.setState({ + redirectToReferrer: true, + authenticating: false + }); + }) + .catch((e) => { + this.setState({ + alertMessage: e.message, + authenticating: false + }); + }); + }, }; fields = { @@ -61,7 +90,10 @@ class Login extends PureComponent { authenticating: false, redirectToReferrer: false, registered: false, + guest: null, + useCookies: false, errors: this.emptyErrors, + redirect: null, }; } @@ -148,13 +180,17 @@ class Login extends PureComponent { ); } + componentDidMount() { + auth.guest().then((gm) => this.setState({ guest: !!gm })); + } + render() { const error = decodeURIComponent(window.location.hash.split('error=')[1] || ''); const { from } = this.props.location.state || { from: { pathname: '/' } }; const state = { ...this.state }; // const actions = { ...this.actions }; - const { alertMessage, authenticating, registering } = state; + const { alertMessage, authenticating, registering, guest, dangerous, useCookies } = state; const docLink = 'http://www.makerverse.com/features/security/'; const showLogout = error && error.includes('Wrong user'); let enabled = !authenticating && this.fields.username && this.fields.username.value.length > 0 && @@ -268,9 +304,45 @@ class Login extends PureComponent {
- - {i18n._('Why is it necessary to log in?')} - + {!guest && ( + + {i18n._('Why is it necessary to log in?')} + + )} + {guest && ( +
+
+ + +
+
+ +
+ )}

diff --git a/src/app/i18n/cs/resource.json b/src/app/i18n/cs/resource.json index ebf863eb6..9bf8591e5 100644 --- a/src/app/i18n/cs/resource.json +++ b/src/app/i18n/cs/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/de/resource.json b/src/app/i18n/de/resource.json index b6c01f332..7b6ff0ed5 100644 --- a/src/app/i18n/de/resource.json +++ b/src/app/i18n/de/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/en/resource.json b/src/app/i18n/en/resource.json index 7b29706ac..e84529555 100644 --- a/src/app/i18n/en/resource.json +++ b/src/app/i18n/en/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "Could not download machine profiles.", "You will need to use \"manual connection mode,\" below.": "You will need to use \"manual connection mode,\" below.", "{{ axis }}-Axis": "{{ axis }}-Axis", - "Axis has no size.": "Axis has no size.", "Accuracy is unusual": "Accuracy is unusual", "Precision is unusual.": "Precision is unusual.", "Axes have been set by your machine profile.": "Axes have been set by your machine profile.", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "Required version: v{{ requiredVersion }}", "Update available: v{{ suggestedVersion }}": "Update available: v{{ suggestedVersion }}", "You have the latest firmware.": "You have the latest firmware.", - "Firmware": "Firmware" + "Firmware": "Firmware", + "Axis is very small (min and max close together).": "Axis is very small (min and max close together).", + "Preparing Machine...": "Preparing Machine...", + "Applying Settings...": "Applying Settings...", + "Refreshing Settings...": "Refreshing Settings...", + "Other": "Other", + "Is this a new machine?": "Is this a new machine?", + "Or, have you installed new firmware?": "Or, have you installed new firmware?", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "Selecting \"yes\" will reset (erase) and apply reccomended settings.", + "Welcome": "Welcome" } diff --git a/src/app/i18n/es/resource.json b/src/app/i18n/es/resource.json index 1ff52e360..1bd0c16c2 100644 --- a/src/app/i18n/es/resource.json +++ b/src/app/i18n/es/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/fr/resource.json b/src/app/i18n/fr/resource.json index e1d89e8d6..ac5dd6f21 100644 --- a/src/app/i18n/fr/resource.json +++ b/src/app/i18n/fr/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/hu/resource.json b/src/app/i18n/hu/resource.json index 8c2246644..abc3f7a43 100644 --- a/src/app/i18n/hu/resource.json +++ b/src/app/i18n/hu/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/it/resource.json b/src/app/i18n/it/resource.json index cbac6573a..4cf756efd 100644 --- a/src/app/i18n/it/resource.json +++ b/src/app/i18n/it/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/ja/resource.json b/src/app/i18n/ja/resource.json index 242100a09..96f9950ca 100644 --- a/src/app/i18n/ja/resource.json +++ b/src/app/i18n/ja/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/nl/resource.json b/src/app/i18n/nl/resource.json index a328e7187..b4d7bcda4 100644 --- a/src/app/i18n/nl/resource.json +++ b/src/app/i18n/nl/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/pt-br/resource.json b/src/app/i18n/pt-br/resource.json index 998da8813..a5f76ece9 100644 --- a/src/app/i18n/pt-br/resource.json +++ b/src/app/i18n/pt-br/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/ru/resource.json b/src/app/i18n/ru/resource.json index 6b7a82f2e..8e39320f6 100644 --- a/src/app/i18n/ru/resource.json +++ b/src/app/i18n/ru/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/tr/resource.json b/src/app/i18n/tr/resource.json index af971d0df..61514dad3 100644 --- a/src/app/i18n/tr/resource.json +++ b/src/app/i18n/tr/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/zh-cn/resource.json b/src/app/i18n/zh-cn/resource.json index ee148dde2..e3909f663 100644 --- a/src/app/i18n/zh-cn/resource.json +++ b/src/app/i18n/zh-cn/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/i18n/zh-tw/resource.json b/src/app/i18n/zh-tw/resource.json index ba1241f25..3b9081b63 100644 --- a/src/app/i18n/zh-tw/resource.json +++ b/src/app/i18n/zh-tw/resource.json @@ -573,7 +573,6 @@ "Could not download machine profiles.": "", "You will need to use \"manual connection mode,\" below.": "", "{{ axis }}-Axis": "", - "Axis has no size.": "", "Accuracy is unusual": "", "Precision is unusual.": "", "Axes have been set by your machine profile.": "", @@ -592,5 +591,14 @@ "Required version: v{{ requiredVersion }}": "", "Update available: v{{ suggestedVersion }}": "", "You have the latest firmware.": "", - "Firmware": "" + "Firmware": "", + "Axis is very small (min and max close together).": "", + "Preparing Machine...": "", + "Applying Settings...": "", + "Refreshing Settings...": "", + "Other": "", + "Is this a new machine?": "", + "Or, have you installed new firmware?": "", + "Selecting \"yes\" will reset (erase) and apply reccomended settings.": "", + "Welcome": "" } diff --git a/src/app/lib/auth.js b/src/app/lib/auth.js index 62eb87f8d..3aba85187 100644 --- a/src/app/lib/auth.js +++ b/src/app/lib/auth.js @@ -4,6 +4,7 @@ import { createUserManager, loadUser } from 'redux-oidc'; import Workspaces from 'app/lib/workspaces'; import log from 'app/lib/log'; import analytics from 'app/lib/analytics'; +import { getCookie } from 'app/lib/cookies'; import series from 'app/lib/promise-series'; import promisify from 'app/lib/promisify'; import { prodHost } from 'app/lib/ows/api'; @@ -36,17 +37,30 @@ const resume = (reduxStore) => new Promise((resolve, reject) => { }); }); -const signin = (oidc) => new Promise((resolve, reject) => { +const guest = () => new Promise((resolve, reject) => { + authrequest + .post('/api/signin') + .then((res) => { + resolve(res.body && res.body.guest); + }) + .catch((e) => { + log.error('login error', e); + }); +}); + +const signin = (oidc, guest = false) => new Promise((resolve, reject) => { const token = oidc ? oidc.access_token : config.get('session.token'); - if (!token) { + const isGuest = guest || hasGuestCookie(); + if (!token && !isGuest) { log.debug('no token in storage'); resolve({ success: false }); return; } + const payload = isGuest ? {} : { token }; log.debug('resuming login...'); authrequest .post('/api/signin') - .send({ token }) + .send(payload) .then((res) => { const body = res ? res.body : {}; @@ -81,13 +95,12 @@ const signin = (oidc) => new Promise((resolve, reject) => { .then(({ body }) => { if (body && body.records) { body.records.forEach((record) => { - log.debug(`loading workspace: ${record.name}`); Workspaces.load(record); }); } else { log.error('workspaces load error'); } - log.debug('login connecting to', Workspaces.all.length, 'workspaces...'); + log.debug('login connecting to workspaces:', Object.keys(Workspaces.all)); const funcs = Object.keys(Workspaces.all).map((id) => { return () => promisify(next => { const workspace = Workspaces.all[id]; @@ -119,18 +132,37 @@ const signout = () => new Promise((resolve, reject) => { resolve(); }); +const GUEST_COOKIE_NAME = 'mvguest'; + +const hasGuestCookie = () => { + return getCookie(GUEST_COOKIE_NAME) === '1'; +}; + const isAuthenticated = () => { - return _authenticated; + return _authenticated || hasGuestCookie(); +}; + +const setAuthenticated = (auth) => { + _authenticated = !!auth; +}; + +const isGuest = () => { + return isAuthenticated() && auth.user && auth.user.username === 'guest'; }; const auth = { host: '', socket: { }, isAuthenticated: isAuthenticated, + setAuthenticated: setAuthenticated, + hasGuestCookie: hasGuestCookie, manager: authManager, signout: signout, signin: signin, resume: resume, + isGuest: isGuest, + guest: guest, + GUEST_COOKIE_NAME: GUEST_COOKIE_NAME, user: null, }; diff --git a/src/app/lib/cookies.js b/src/app/lib/cookies.js new file mode 100644 index 000000000..5266bc24d --- /dev/null +++ b/src/app/lib/cookies.js @@ -0,0 +1,35 @@ + +export function setCookie(name, val) { + const date = new Date(); + const value = val; + + // Set it expire in 30 days + date.setTime(date.getTime() + 30 * 24 * 60 * 60 * 1000); + + console.log('set cookie', name, value); + // Set it + document.cookie = name + '=' + value + '; expires=' + date.toUTCString() + '; path=/'; +} + +export function getCookie(name) { + const value = '; ' + document.cookie; + const parts = value.split('; ' + name + '='); + + if (parts.length === 2) { + const ppop = parts.pop(); + if (ppop) { + return ppop.split(';').shift(); + } + } + return null; +} + +export function deleteCookie(name) { + const date = new Date(); + + // Set it expire in -1 days + date.setTime(date.getTime() + -1 * 24 * 60 * 60 * 1000); + + // Set it + document.cookie = name + '=; expires=' + date.toUTCString() + '; path=/'; +} diff --git a/src/server/access-control.js b/src/server/access-control.js index 4c00e899a..b7aba6ff5 100644 --- a/src/server/access-control.js +++ b/src/server/access-control.js @@ -1,7 +1,7 @@ // import ensureArray from 'ensure-array'; // import _ from 'lodash'; // import rangeCheck from 'range_check'; -import { getUserByToken } from './api/api.users'; +import { getUserByToken, isGuestAccessEnabled, guestUser } from './api/api.users'; import settings from './config/settings'; // import config from './services/configstore'; import urljoin from './lib/urljoin'; @@ -77,8 +77,12 @@ const getTokenFromHeader = (authHeader) => { // Return the associated token for a user (or throw an error) const validateToken = (token) => { - if (!token) { - throw new Error('No token provided'); + if (!token || token.length <= 0) { + if (isGuestAccessEnabled()) { + return guestUser; + } else { + throw new Error('No token provided'); + } } const user = getUserByToken(token); if (!user) { diff --git a/src/server/api/api.users.js b/src/server/api/api.users.js index ca89943c8..591410175 100644 --- a/src/server/api/api.users.js +++ b/src/server/api/api.users.js @@ -39,6 +39,13 @@ const noCache = (request) => { } }; +const GUEST_KEY = 'insecureDangerousGuestAccess'; + +export const isGuestAccessEnabled = () => { + const gk = config.get(GUEST_KEY, false); + return gk === true; +}; + export const owsreq = superagentUse(superagent); owsreq.use(noCache); @@ -85,6 +92,8 @@ const getSanitizedRecords = () => { return records; }; +export const guestUser = { username: 'guest' }; + // Get all users which may be used for login purposes. export const getValidUsers = () => { const users = getSanitizedRecords(); @@ -100,6 +109,10 @@ export const getUserByToken = (token) => { export const signin = (req, res) => { const { token = '' } = { ...req.body }; + if (token.length <= 0 && isGuestAccessEnabled()) { + res.send({ enabled: true, guest: true, user: guestUser }); + } + owsreq.use((request) => { request.set('Authorization', 'Bearer ' + token); request.set('ClientVersion', pkg.version);