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

disable nodeintegration #453

Merged
merged 13 commits into from
Jun 6, 2018
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ RUN yarn run heroku-postbuild

ENV PLOTLY_CONNECTOR_PORT 9494
EXPOSE 9494
ENTRYPOINT yarn run build-web && yarn run start-headless
ENTRYPOINT yarn run start-headless
54 changes: 25 additions & 29 deletions app/components/Configuration.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@ import cookie from 'react-cookies';
import React, { Component, PropTypes } from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import Settings from './Settings/Settings.react';
import {isElectron} from '../utils/utils';
import * as SessionsActions from '../actions/sessions';
import Login from './Login.react';

import Login from './Login.react.js';
import * as SessionsActions from '../actions/sessions.js';
import Settings from './Settings/Settings.react.js';
import {isElectron, setUsernameListener} from '../utils/utils.js';


class Configuration extends Component {
constructor(props) {
super(props);
this.state = {
authEnabled: (cookie.load('db-connector-auth-enabled') === 'true'),
clientId: cookie.load('db-connector-client-id'),
isMenuOpen: false,
username: cookie.load('db-connector-user'),
/* global PLOTLY_ENV */
authDisabled: !PLOTLY_ENV.AUTH_ENABLED
username: cookie.load('db-connector-user')
};
this.toggle = this.toggle.bind(this);
this.close = this.close.bind(this);
Expand All @@ -27,12 +28,9 @@ class Configuration extends Component {
* In the browser, the username is set with a cookie but in electron
* this is set using electron's ipcRenderer.
*/
if (isElectron()) {
window.require('electron').ipcRenderer.once('username',
(event, message) => {
this.setState({username: message});
});
}
setUsernameListener((event, message) => {
this.setState({username: message});}
);
}

toggle() {
Expand All @@ -44,26 +42,24 @@ class Configuration extends Component {
}

logOut() {
/*
* Delete all the cookies and reset user state. This does not kill
* any running connections, but user will not be able to access them
* without logging in again.
*/
cookie.remove('db-connector-user');
cookie.remove('plotly-auth-token');
cookie.remove('db-connector-auth-token');
this.setState({ username: ''});

/*
* Delete all the cookies and reset user state. This does not kill
* any running connections, but user will not be able to access them
* without logging in again.
*/
cookie.remove('db-connector-user');
cookie.remove('plotly-auth-token');
cookie.remove('db-connector-auth-token');
cookie.remove('db-connector-auth-disabled');
this.setState({ username: ''});

// reload page when running in browser:
if (!isElectron()) {
window.location.reload();
}
// reload page when running in browser:
if (!isElectron()) {
window.location.reload();
}
}

render() {
return (isElectron() || this.state.authDisabled || this.state.username) ? (
return (isElectron() || !this.state.authEnabled || this.state.username) ? (
<div className="fullApp">
<Settings username={this.state.username} logout={this.logOut}/>
</div>
Expand Down
28 changes: 1 addition & 27 deletions app/components/Link.react.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,5 @@
import R from 'ramda';
import React from 'react';
import PropTypes from 'prop-types';
import {dynamicRequireElectron} from '../utils/utils';


let shell;
try {
shell = dynamicRequireElectron().shell;
} catch (e) {
shell = null;
}

export function Link(props) {
const {href} = props;
if (shell) {
return (
<span
className={`${props.className}`}
onClick={() => {shell.openExternal(href);}}
{...R.omit(['className'], props)}
/>
);
}
return <a href={href} target="_blank" {...props}/>;
return <a target="_blank" rel="noopener" {...props}/>;
}

Link.propTypes = {
href: PropTypes.string,
className: PropTypes.string
};
83 changes: 34 additions & 49 deletions app/components/Login.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import React, {Component} from 'react';
import {connect} from 'react-redux';
import {
baseUrl,
dynamicRequireElectron,
homeUrl,
isOnPrem,
plotlyUrl
Expand All @@ -21,35 +20,12 @@ const CLOUD = 'cloud';
const ONPREM = 'onprem';

window.document.title = `${build.productName} v${version}`;
let usernameLogged = '';

// http://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen
const PopupCenter = (url, title, w, h) => {
// Fixes dual-screen position
const dualScreenLeft = 'screenLeft' in window ? window.screenLeft : screen.left;
const dualScreenTop = 'screenTop' in window ? window.screenTop : screen.top;

const width = window.innerWidth
? window.innerWidth
: document.documentElement.clientWidth
? document.documentElement.clientWidth
: screen.width;
const height = window.innerHeight
? window.innerHeight
: document.documentElement.clientHeight
? document.documentElement.clientHeight
: screen.height;

const left = ((width / 2) - (w / 2)) + dualScreenLeft;
const top = ((height / 2) - (h / 2)) + dualScreenTop;
const popupWindow = window.open(url, title, `scrollbars=yes, width=${w}, height=${h}, top=${top}, left=${left}`);
return popupWindow;
};

class Login extends Component {
constructor(props) {
super(props);
this.state = {
clientId: cookie.load('db-connector-client-id'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its oauth2 client id, so we can probably name it like that. DB connector in itself doesn't have a notion of client-id.

domain: (isOnPrem() ? plotlyUrl() : 'https://plot.ly'),
statusMessage: '',
serverType: CLOUD,
Expand All @@ -58,6 +34,11 @@ class Login extends Component {
this.buildOauthUrl = this.buildOauthUrl.bind(this);
this.oauthPopUp = this.oauthPopUp.bind(this);
this.logIn = this.logIn.bind(this);

// the web app:
// - sets this property to the popup window opened for authorization
// - and triggers a reload when `this.popup.closed` becomes true
this.popup = null;
}

componentDidMount() {
Expand All @@ -69,8 +50,7 @@ class Login extends Component {
* to check for authentication.
*/
setInterval(() => {
usernameLogged = cookie.load('db-connector-user');
if (usernameLogged) {
if (this.popup && this.popup.closed) {
if (serverType === ONPREM) {
this.setState({
status: 'authorized',
Expand Down Expand Up @@ -101,7 +81,6 @@ class Login extends Component {
}

saveDomainToSettings() {

const {domain} = this.state;
let PLOTLY_API_SSL_ENABLED = true;
let PLOTLY_API_DOMAIN = '';
Expand All @@ -125,35 +104,41 @@ class Login extends Component {

}
buildOauthUrl() {
const {domain} = this.state;
/* global PLOTLY_ENV */
const oauthClientId = PLOTLY_ENV.OAUTH2_CLIENT_ID;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to get rid of this.. #Cleanup.. :)


const {clientId, domain} = this.state;
const redirect_uri = baseUrlWrapped;
return (
`${domain}/o/authorize/?response_type=token&` +
`client_id=${oauthClientId}&` +
`client_id=${clientId}&` +
`redirect_uri=${redirect_uri}/oauth2/callback`
);
}

oauthPopUp() {
try {
const electron = dynamicRequireElectron();
const oauthUrl = this.buildOauthUrl();
electron.shell.openExternal(oauthUrl);
} catch (e) {
// eslint-disable-next-line no-console
console.log('Unable to openExternal, opening a popupWindow instead:');
// eslint-disable-next-line no-console
console.log(e);
const popupWindow = PopupCenter(
this.buildOauthUrl(), 'Authorization', '500', '500'
);
if (window.focus) {
popupWindow.focus();
}
}
// http://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen
const url = this.buildOauthUrl();
const title = 'Authorization';
const w = '600';
const h = '600';

// Fixes dual-screen position
const dualScreenLeft = 'screenLeft' in window ? window.screenLeft : screen.left;
const dualScreenTop = 'screenTop' in window ? window.screenTop : screen.top;

const width = window.innerWidth
? window.innerWidth
: document.documentElement.clientWidth
? document.documentElement.clientWidth
: screen.width;
const height = window.innerHeight
? window.innerHeight
: document.documentElement.clientHeight
? document.documentElement.clientHeight
: screen.height;

const left = ((width / 2) - (w / 2)) + dualScreenLeft;
const top = ((height / 2) - (h / 2)) + dualScreenTop;

this.popup = window.open(url, title, `scrollbars=yes, width=${w}, height=${h}, top=${top}, left=${left}`);
}

logIn () {
Expand Down
32 changes: 14 additions & 18 deletions app/components/Settings/Preview/Preview.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ class Preview extends Component {
}

fetchDatacache(payload, type) {

const {username} = this.props;
const payloadJSON = JSON.stringify({
payload: payload, type: type, requestor: username});
Expand All @@ -187,7 +186,8 @@ class Preview extends Component {
}).then(resp => {
return resp.json();
}).then(data => {
const plotlyLinks = this.state.plotlyLinks;
const {plotlyLinks} = this.state;

let link;

if (!('error' in data)) {
Expand Down Expand Up @@ -456,6 +456,15 @@ class Preview extends Component {
<TabPanel>
<div className="export-options-container">
<div style={{margin: '20px 0'}}>
<button
className="btn btn-outline"
onClick={() => this.fetchDatacache(
JSON.stringify(this.state.plotlyJSON),
'plot'
)}
>
Send chart to Chart Studio
</button>
<button
className="btn btn-outline"
onClick={() => this.fetchDatacache(this.getCSVString(), 'grid')}
Expand All @@ -465,19 +474,12 @@ class Preview extends Component {
{!isOnPrem() &&
<button
className="btn btn-outline"
onClick={() => this.fetchDatacache(this.getCSVString(), 'csv')}
onClick={() => window.open(
`data:text/csv;base64,${Buffer.from(this.getCSVString()).toString('base64')}`
)}
>
Download CSV
</button>}
<button
className="btn btn-outline"
onClick={() => this.fetchDatacache(
JSON.stringify(this.state.plotlyJSON),
'plot'
)}
>
Send chart to Chart Studio
</button>
</div>
<div style={{width: 650, height: 200, border: '1px solid #dfe8f3',
fontFamily: '\'Ubuntu Mono\', courier, monospace', paddingTop: 10,
Expand All @@ -491,12 +493,6 @@ class Preview extends Component {
<Link href={link.url} target="_blank" className="externalLink">{link.url}</Link>
</div>
}
{link.type === 'csv' &&
<div>
<div style={{color: '#00cc96'}}>💾 Your CSV has been saved ⬇️</div>
<Link href={link.url} target="_blank" className="externalLink">{link.url}</Link>
</div>
}
{link.type === 'plot' &&
<div>
<div style={{color: '#00cc96'}}>📈 Link to your chart on Chart Studio ⬇️</div>
Expand Down
6 changes: 5 additions & 1 deletion app/components/Settings/Settings.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,14 @@ class Settings extends Component {

this.intervals.checkHTTPSEndpointInterval = setInterval(() => {
if (this.state.urls.https) {
fetch(this.state.urls.https).then(() => {
fetch(this.state.urls.https)
.then(() => {
this.setState({httpsServerIsOK: true});
clearInterval(this.intervals.checkHTTPSEndpointInterval);
clearInterval(this.intervals.timeElapsedInterval);
})
.catch(() => {
// silence fetch errors
});
}
}, 5 * 1000);
Expand Down
13 changes: 2 additions & 11 deletions app/components/Settings/UserConnections/UserConnections.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,12 @@ import Filedrop from './filedrop.jsx';
import {contains} from 'ramda';

import {CONNECTION_CONFIG, SAMPLE_DBS} from '../../../constants/constants';
import {dynamicRequireElectron} from '../../../utils/utils';

let dialog;
try {
dialog = dynamicRequireElectron().remote.dialog;
} catch (e) {
dialog = null;
}
import {showOpenDialog} from '../../../utils/utils';

/*
* Displays and alters user inputs for `configuration`
* username, password, and local port number.
*/


export default class UserConnections extends Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -47,7 +38,7 @@ export default class UserConnections extends Component {
getStorageOnClick(setting) {
// sqlite requires a path
return () => {
dialog.showOpenDialog({
showOpenDialog({
properties: ['openFile'],
filters: [{
name: 'databases',
Expand Down
Loading