Skip to content

Commit

Permalink
File-system backend fixes and support JWT
Browse files Browse the repository at this point in the history
  • Loading branch information
Igor Kuznetsov committed Jan 20, 2018
1 parent 70640c8 commit 5929454
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 66 deletions.
4 changes: 4 additions & 0 deletions src/backends/file-system/API.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { APIError } from "../../valueObjects/errors";
export default class API {
constructor(config) {
this.api_root = config.api_root || "/api";
this.token = config.token;
}

user() {
Expand All @@ -17,6 +18,9 @@ export default class API {
"Content-Type": "application/json",
...headers,
};
if (this.token) {
baseHeader.Authorization = `Bearer ${ this.token }`;
}

return baseHeader;
}
Expand Down
49 changes: 32 additions & 17 deletions src/backends/file-system/AuthenticationPage.css
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
.fs-auth-page-root {
.nc-filesystemAuthenticationPage-root {
display: flex;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
height: 100vh;
}

.fs-auth-page-card {
.nc-filesystemAuthenticationPage-form {
width: 350px;
padding: 10px;
}
margin-top: -80px;
z-index: 1;
& input {
background-color: #fff;
border-radius: var(--borderRadius);

.fs-auth-page-card img {
display: block;
margin: auto;
padding: 20px;
}
font-size: 14px;
padding: 10px 10px;
margin-bottom: 15px;
margin-top: 6px;
width: 100%;
position: relative;
z-index: 1;

.fs-auth-page-errorMsg {
color: #dd0000;
&:focus {
outline: none;
box-shadow: inset 0 0 0 2px var(--colorBlue);
}
}
}

.fs-auth-page-message {
font-size: 1.1em;
margin: 20px 10px;
.nc-filesystemAuthenticationPage-button {
@apply(--button);
@apply(--dropShadowDeep);
@apply(--buttonDefault);
@apply(--buttonGray);

padding: 0 30px;
display: block;
margin-top: 20px;
margin: auto;
}

.fs-auth-page-button {
padding: .25em 1em;
height: auto;
.nc-filesystemAuthenticationPage-errorMsg {
color: var(--colorErrorText);
}
108 changes: 88 additions & 20 deletions src/backends/file-system/AuthenticationPage.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,108 @@
import PropTypes from 'prop-types';
import React from 'react';
import { partial } from 'lodash';
import { Icon } from "UI";
import logo from "./netlify_logo.svg";
import styles from "./AuthenticationPage.css";

let component = null;

const localHosts = {
localhost: true,
"127.0.0.1": true,
"0.0.0.0": true
};

export default class AuthenticationPage extends React.Component {
constructor(props) {
super(props);
component = this;
}

componentDidMount() {
}

componentWillUnmount() {
component = null;
}

static propTypes = {
onLogin: PropTypes.func.isRequired,
inProgress: PropTypes.bool,
};

state = { email: '' };
state = { email: "", password: "", errors: {} };

handleChange = (name, e) => {
this.setState({ ...this.state, [name]: e.target.value });
};

handleLogin = (e) => {
e.preventDefault();
this.props.onLogin(this.state);
};

handleEmailChange = (value) => {
this.setState({ email: value });
const { email, password } = this.state;
const errors = {};

if (localHosts[document.location.host.split(":").shift()]) {
this.props.onLogin(this.state);
} else {
if (!email) {
errors.email = 'Make sure to enter your email.';
}
if (!password) {
errors.password = 'Please enter your password.';
}
if (Object.keys(errors).length > 0) {
this.setState({ errors });
return;
}
AuthenticationPage.authClient.login(this.state.email, this.state.password, true)
.then((user) => {
this.props.onLogin(user);
})
.catch((error) => {
this.setState({ errors: { server: error.description || error.msg || error }, loggingIn: false });
});
}
};

render() {
const { inProgress } = this.props;

return (<section className="fs-auth-page-root">
<section className="fs-auth-page-card">
<Icon className="nc-githubAuthenticationPage-logo" size="500px" type="netlify-cms"/>
<button
className="nc-githubAuthenticationPage-button"
disabled={inProgress}
onClick={this.handleLogin}
>
{inProgress ? "Logging in..." : "Login Local"}
</button>
const { errors } = this.state;
const { error, inProgress } = this.props;

return (
<section className="nc-filesystemAuthenticationPage-root">
<Icon className="nc-filesystemAuthenticationPage-logo" size="500px" type="netlify-cms"/>
<form className="nc-filesystemAuthenticationPage-form" onSubmit={this.handleLogin}>
{!error && <p>
<span className="nc-filesystemAuthenticationPage-errorMsg">{error}</span>
</p>}
{!errors.server && <p>
<span className="nc-filesystemAuthenticationPage-errorMsg">{errors.server}</span>
</p>}
<div className="nc-filesystemAuthenticationPage-errorMsg">{ errors.email || null }</div>
<input
type="text"
name="email"
placeholder="Email"
value={this.state.email}
onChange={partial(this.handleChange, 'email')}
/>
<div className="nc-filesystemAuthenticationPage-errorMsg">{ errors.password || null }</div>
<input
type="password"
name="password"
placeholder="Password"
value={this.state.password}
onChange={partial(this.handleChange, 'password')}
/>
<button
className="nc-filesystemAuthenticationPage-button"
disabled={inProgress}
onClick={this.handleLogin}
>
{inProgress ? "Logging in..." : "Login"}
</button>
</form>
</section>
</section>);
);
}
}
65 changes: 59 additions & 6 deletions src/backends/file-system/implementation.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import GoTrue from "gotrue-js";
import jwtDecode from 'jwt-decode';
import {List} from 'immutable';
import trimStart from 'lodash/trimStart';
import AuthenticationPage from './AuthenticationPage';
import API from "./API";
Expand All @@ -23,32 +26,82 @@ function nameFromEmail(email) {
.join(' ');
}

const localHosts = {
localhost: true,
"127.0.0.1": true,
"0.0.0.0": true
};

export default class fs {
constructor(config) {
this.config = config;

this.api_root = config.getIn(["backend", "api_root"], "http://localhost:8080/api");
this.api_root = config.getIn(["backend", "api_root"], "/api");

const APIUrl = config.getIn(["backend", "identity_url"], "/.netlify/identity");
this.authClient = window.netlifyIdentity ? window.netlifyIdentity.gotrue : new GoTrue({APIUrl});

AuthenticationPage.authClient = this.authClient;
}

authComponent() {
return AuthenticationPage;
}

restoreUser(user) {
if (!localHosts[document.location.host.split(":").shift()]) {
user = this.authClient && this.authClient.currentUser();
if (!user) return Promise.reject();
}
return this.authenticate(user);
}

authenticate(state) {
this.api = new API({ api_root: this.api_root });
return Promise.resolve({ email: state.email, name: nameFromEmail(state.email) });
authenticate(user) {
if (localHosts[document.location.host.split(":").shift()]) {
const userData = { name: '', email: '' };
if (user.email) {
userData.name = nameFromEmail(user.email);
userData.email = user.email;
}
this.api = new API({
api_root: this.api_root,
token: null,
});
return Promise.resolve(userData);
} else {
this.tokenPromise = user.jwt.bind(user);
return this.tokenPromise()
.then((token) => {
const userData = {
name: user.user_metadata.name || nameFromEmail(user.email),
email: user.email,
avatar_url: user.user_metadata.avatar_url,
metadata: user.user_metadata,
};
this.api = new API({
api_root: this.api_root,
token: token,
});
return userData;
});
}
}

logout() {
return null;
if (localHosts[document.location.host.split(":").shift()]) {
return null;
} else {
const user = this.authClient.currentUser();
return user && user.logout();
}
}

getToken() {
return Promise.resolve('');
if (localHosts[document.location.host.split(":").shift()]) {
return Promise.resolve('');
} else {
return this.tokenPromise();
}
}

entriesByFolder(collection, extension) {
Expand Down
23 changes: 0 additions & 23 deletions src/backends/file-system/netlify_logo.svg

This file was deleted.

1 change: 1 addition & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@
*/
@import "./backends/git-gateway/AuthenticationPage.css";
@import "./backends/github/AuthenticationPage.css";
@import "./backends/file-system/AuthenticationPage.css";

0 comments on commit 5929454

Please sign in to comment.