Skip to content
This repository has been archived by the owner on Oct 12, 2020. It is now read-only.

Commit

Permalink
Add oauth2 authentication (#320)
Browse files Browse the repository at this point in the history
* Setup to use authentication again
  • Loading branch information
carlioth committed Jul 5, 2019
1 parent 3ab9953 commit e3175d9
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 128 deletions.
3 changes: 3 additions & 0 deletions .env
@@ -0,0 +1,3 @@
CALLBACK_URL=https%3A%2F%2Fap.core.qlik.com%2F%23%2Fapp
BACKEND_ADDRESS=apps.core.qlik.com/secure/doc/fc649d13-84ea-4174-8c96-67208f069587
AUTH_DOMAIN=https://apps.core.qlik.com
3 changes: 3 additions & 0 deletions .env.local
@@ -0,0 +1,3 @@
CALLBACK_URL=http%3A%2F%2Flocalhost%3A8080%2F%23%2Fapp
BACKEND_ADDRESS=apps.core.qlik.com/secure/doc/fc649d13-84ea-4174-8c96-67208f069587
AUTH_DOMAIN=https://apps.core.qlik.com
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -11,7 +11,7 @@
"url": "https://github.com/qlik-oss/core-assisted-prescription-ui"
},
"scripts": {
"build": "webpack --mode production",
"build": "NODE_ENV=production webpack --mode production",
"start": "webpack-dev-server --mode development --open --hot",
"lint": "eslint --ext .js,.jsx .",
"lint:fix": "eslint --ext .js,.jsx --fix ."
Expand Down
4 changes: 0 additions & 4 deletions src/components/acceptCookies.css

This file was deleted.

33 changes: 0 additions & 33 deletions src/components/acceptCookies.jsx

This file was deleted.

4 changes: 1 addition & 3 deletions src/components/app.jsx
Expand Up @@ -30,9 +30,7 @@ class App extends Component {

try {
const global = await session.open();
const app = process.env.NODE_ENV === 'production'
? await global.getActiveDoc()
: await global.openDoc('drugcases.qvf');
const app = await global.getActiveDoc();
this.setState({ view: 'app', app, session });
} catch (error) {
this.setState({ view: 'suspended' });
Expand Down
3 changes: 1 addition & 2 deletions src/enigma-config.js
@@ -1,11 +1,10 @@
import qixSchema from 'enigma.js/schemas/12.20.0.json';

const ERR_ABORTED = 15;
const backendAdress = process.env.NODE_ENV === 'production' ? `${process.env.BACKEND}/app/doc/fc649d13-84ea-4174-8c96-67208f069587` : 'localhost:9176';

const enigmaConfig = {
schema: qixSchema,
url: `${window.location.protocol.replace('http', 'ws')}${backendAdress}`,
url: `${window.location.protocol.replace('http', 'ws')}${process.env.BACKEND_ADDRESS}`,
suspendOnClose: true,
interceptors: [
{
Expand Down
16 changes: 15 additions & 1 deletion src/index.template.html
Expand Up @@ -3,11 +3,25 @@

<head>
<meta charset="UTF-8">
<title>Assisted Prescription</title>
<title><%= htmlWebpackPlugin.options.title %></title>
<script>(function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer', '<%= htmlWebpackPlugin.options.GA %>');
</script>

</head>

<body>
<div id="root"></div>
<noscript>
<iframe src="https://www.googletagmanager.com/ns.html?id=<%= htmlWebpackPlugin.options.GA %>"
height="0" width="0" style="display:none;visibility:hidden"></iframe>
</noscript>
</body>

</html>
118 changes: 36 additions & 82 deletions src/main.jsx
Expand Up @@ -10,11 +10,8 @@ import Button from '@material-ui/core/Button';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
// import { MuiThemeProvider } from '@material-ui/core/styles';
import AcceptCookies from './components/acceptCookies';
import LandingPage from './components/landingPage';
import App from './components/app';
import Login from './components/login';
import PrivateRoute from './components/privateRoute';

import './main.css';
Expand All @@ -23,40 +20,36 @@ picasso.use(picassoQ);

const auth = {

// isAuthenticated:
// fetch('/is-authenticated', {
// credentials: 'same-origin',
// }).then(response => response.json()),
// idp:
// fetch('/idp')
// .then(response => response.text()),
// authenticate() {
// window.location.href = `/login/github?${qliktiveRedirectParam}`;
// },
// localAuthenticate(username, password) {
// window.location.href =
// `/login/local/callback?username=${username}&password=${password}&${qliktiveRedirectParam}`;
// },
// signout(cb) {
// fetch('/logout', {
// credentials: 'same-origin',
// }).then(cb);
// },
isAuthenticated:
fetch(`${process.env.AUTH_DOMAIN}/oauth2/auth`, {
credentials: 'include',
mode: 'cors',
}).then(response => response.status === 202),
authenticate() {
window.location.href = `${process.env.AUTH_DOMAIN}/oauth2/start?rd=${process.env.CALLBACK_URL}`;
},
signout(cb) {
fetch(`${process.env.AUTH_DOMAIN}/oauth2/sign_in`, {
mode: 'cors',
credentials: 'include',
}).then(cb);
},
};

// Main component responsible for rendering the routes when
// the path matches the route.
const Main = ({ notAuthorizedCallback }) => (
const Main = ({ isAuthenticated, notAuthorizedCallback }) => (
<main>
<Switch>
<Route exact path="/" component={LandingPage} />
<PrivateRoute path="/app" component={App} isAuthenticated notAuthorizedCallback={notAuthorizedCallback} />
<PrivateRoute path="/app" component={App} isAuthenticated={isAuthenticated} notAuthorizedCallback={notAuthorizedCallback} />
</Switch>
</main>
);

Main.propTypes = {
notAuthorizedCallback: PropTypes.func,
isAuthenticated: PropTypes.bool.isRequired,
};

Main.defaultProps = {
Expand All @@ -68,55 +61,25 @@ class ThePage extends React.Component {
super(...args);

this.state = {
authMode: 'local',
isAuthenticated: true,
isAuthenticated: null,
dialogIsOpen: false,
cookieAccepted: document.cookie.indexOf('apqlikcoreaccept') !== -1,
};

// auth.idp.then((authMode) => {
// this.setState({ authMode });
// });

// auth.isAuthenticated.then((authenticated) => {
// this.setState({ isAuthenticated: authenticated });
// });
auth.isAuthenticated.then((authenticated) => {
this.setState({ isAuthenticated: authenticated });
});
}

signinClicked = () => {
const { authMode } = this.state;
if (authMode === 'local') {
this.setState({ dialogIsOpen: true });
} else if (authMode === 'github') {
auth.authenticate();
}
auth.authenticate();
}

signoutClicked = () => {
auth.signout(() => { this.setState({ isAuthenticated: false }); });
}

notAuthorizedCallback = () => {
const { authMode } = this.state;
if (authMode === 'local') {
this.setState({ dialogIsOpen: true });
} else if (authMode === 'github') {
alert('Please sign in to access this page'); // eslint-disable-line no-alert
}
}

cancelLoginClicked = () => {
this.setState({ dialogIsOpen: false });
}

loginClicked = (username, password) => {
auth.localAuthenticate(username, password);
}

acceptClicked = () => {
const cookie = `apqlikcoreaccept=true; expires=${new Date('2050-01-01').toUTCString()}; path=/`;
document.cookie = cookie;
this.setState({ cookieAccepted: true });
alert('Please sign in to get access to this page'); // eslint-disable-line no-alert
}

navigateToLandingPage = () => {
Expand All @@ -128,7 +91,7 @@ class ThePage extends React.Component {
}

render() {
const { isAuthenticated, dialogIsOpen, cookieAccepted } = this.state;
const { isAuthenticated } = this.state;
if (isAuthenticated === null) {
return null;
}
Expand All @@ -148,42 +111,33 @@ class ThePage extends React.Component {
</Typography>
<span className="app-bar-title-dash">
{' '}
/
/
</span>
<span className="app-bar-subtitle">
{' '}
Assisted Prescription
Assisted Prescription
</span>
</div>
<div style={
{
marginTop: '6px',
marginRight: '0px',
marginLeft: 'auto',
}}
{
marginTop: '6px',
marginRight: '0px',
marginLeft: 'auto',
}}
>
<Button className="app-bar-button" onClick={this.navigateToAppPage}>App</Button>
{/* {
isAuthenticated
? (<Button className="app-bar-button" onClick={this.signoutClicked}>Sign Out</Button>)
: (<Button className="app-bar-button" onClick={this.signinClicked}>Sign In</Button>)
} */}
{
isAuthenticated
? (<Button className="app-bar-button" onClick={this.signoutClicked}>Sign Out</Button>)
: (<Button className="app-bar-button" onClick={this.signinClicked}>Sign In</Button>)
}
</div>
</Toolbar>
</AppBar>
<Main
isAuthenticated={isAuthenticated}
notAuthorizedCallback={this.notAuthorizedCallback}
/>
<Login
open={dialogIsOpen}
onCancel={this.cancelLoginClicked}
onLogin={this.loginClicked}
/>
<AcceptCookies
open={!cookieAccepted}
onAccept={this.acceptClicked}
/>
</div>
);
}
Expand Down
9 changes: 7 additions & 2 deletions webpack.config.js
@@ -1,18 +1,23 @@
const path = require('path');
const webpack = require('webpack');
const HtmlPlugin = require('html-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Dotenv = require('dotenv-webpack');

const GoogleAnalytics = 'GTM-P7VJSX';

const isProd = process.env.NODE_ENV === 'production';
const hashSuffix = isProd ? '.[chunkhash]' : '';

const plugins = [
new HtmlPlugin({
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.template.html',
favicon: 'src/resources/favicon.ico',
title: 'Assisted Prescription',
GA: GoogleAnalytics,
}),
new Dotenv({
path: process.env.NODE_ENV === 'production' ? '.env' : '.env.local',
systemvars: true,
}),
];
Expand Down

0 comments on commit e3175d9

Please sign in to comment.