diff --git a/package.json b/package.json
index 98d31d54..26f62f49 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "netlify-cms",
- "version": "0.5.0-beta.1",
+ "version": "0.5.0-beta.7",
"description": "Netlify CMS lets content editors work on structured content stored in git",
"main": "dist/cms.js",
"scripts": {
@@ -68,6 +68,7 @@
"exports-loader": "^0.6.4",
"extract-text-webpack-plugin": "^2.1.2",
"file-loader": "^0.11.2",
+ "gotrue-js": "^0.9.3",
"identity-obj-proxy": "^3.0.0",
"imports-loader": "^0.7.1",
"jest": "^20.0.4",
@@ -101,7 +102,6 @@
"dateformat": "^1.0.12",
"deep-equal": "^1.0.1",
"fuzzy": "^0.1.1",
- "gotrue-js": "^0.9.3",
"history": "^2.1.2",
"immutability-helper": "^2.0.0",
"immutable": "^3.7.6",
@@ -115,6 +115,7 @@
"mdast-util-definitions": "^1.2.2",
"mdast-util-to-string": "^1.0.4",
"moment": "^2.11.2",
+ "node-sass": "^3.10.0",
"normalize.css": "^4.2.0",
"preliminaries": "1.1.0",
"preliminaries-parser-toml": "1.1.0",
diff --git a/src/actions/auth.js b/src/actions/auth.js
index 55d66c3f..10a586dd 100644
--- a/src/actions/auth.js
+++ b/src/actions/auth.js
@@ -77,7 +77,8 @@ export function logoutUser() {
return (dispatch, getState) => {
const state = getState();
const backend = currentBackend(state.config);
- backend.logout();
- dispatch(logout());
+ Promise.resolve(backend.logout()).then(() => {
+ dispatch(logout());
+ });
};
}
diff --git a/src/backends/backend.js b/src/backends/backend.js
index 1f027628..782422bc 100644
--- a/src/backends/backend.js
+++ b/src/backends/backend.js
@@ -1,7 +1,7 @@
import { attempt, isError } from 'lodash';
import TestRepoBackend from "./test-repo/implementation";
import GitHubBackend from "./github/implementation";
-import NetlifyAuthBackend from "./netlify-auth/implementation";
+import GitGatewayBackend from "./git-gateway/implementation";
import { resolveFormat } from "../formats/formats";
import { selectListMethod, selectEntrySlug, selectEntryPath, selectAllowNewEntries, selectFolderEntryExtension } from "../reducers/collections";
import { createEntry } from "../valueObjects/Entry";
@@ -36,12 +36,12 @@ const slugFormatter = (template = "{{slug}}", entryData) => {
const identifier = identifiers.find(ident => ident !== undefined);
if (identifier === undefined) {
- throw new Error("Collection must have a field name that is a valid entry identifier");
+ throw new Error("Collection must have a field name that is a valid entry identifier");
}
return identifier;
};
-
+
return template.replace(/\{\{([^\}]+)\}\}/g, (_, field) => {
switch (field) {
case "year":
@@ -88,11 +88,11 @@ class Backend {
}
logout() {
- if (this.authStore) {
- this.authStore.logout();
- } else {
- throw new Error("User isn't authenticated.");
- }
+ return Promise.resolve(this.implementation.logout()).then(() => {
+ if (this.authStore) {
+ this.authStore.logout();
+ }
+ });
}
getToken = () => this.implementation.getToken();
@@ -292,8 +292,8 @@ export function resolveBackend(config) {
return new Backend(new TestRepoBackend(config), authStore);
case "github":
return new Backend(new GitHubBackend(config), authStore);
- case "netlify-auth":
- return new Backend(new NetlifyAuthBackend(config), authStore);
+ case "git-gateway":
+ return new Backend(new GitGatewayBackend(config), authStore);
default:
throw new Error(`Backend not found: ${ name }`);
}
diff --git a/src/backends/netlify-auth/API.js b/src/backends/git-gateway/API.js
similarity index 100%
rename from src/backends/netlify-auth/API.js
rename to src/backends/git-gateway/API.js
diff --git a/src/backends/netlify-auth/AuthenticationPage.css b/src/backends/git-gateway/AuthenticationPage.css
similarity index 100%
rename from src/backends/netlify-auth/AuthenticationPage.css
rename to src/backends/git-gateway/AuthenticationPage.css
diff --git a/src/backends/netlify-auth/AuthenticationPage.js b/src/backends/git-gateway/AuthenticationPage.js
similarity index 67%
rename from src/backends/netlify-auth/AuthenticationPage.js
rename to src/backends/git-gateway/AuthenticationPage.js
index d23aee69..66807e56 100644
--- a/src/backends/netlify-auth/AuthenticationPage.js
+++ b/src/backends/git-gateway/AuthenticationPage.js
@@ -1,28 +1,54 @@
import React from "react";
import Input from "react-toolbox/lib/input";
import Button from "react-toolbox/lib/button";
+import { Notifs } from 'redux-notifications';
+import { Toast } from '../../components/UI/index';
import { Card, Icon } from "../../components/UI";
import logo from "./netlify_logo.svg";
import styles from "./AuthenticationPage.css";
+let component = null;
+
+if (window.netlifyIdentity) {
+ window.netlifyIdentity.on('login', (user) => {
+ component && component.handleIdentityLogin(user);
+ });
+ window.netlifyIdentity.on('logout', () => {
+ component && component.handleIdentityLogout();
+ });
+}
+
export default class AuthenticationPage extends React.Component {
constructor(props) {
super(props);
- this.identity = window.netlifyIdentity;
- this.state = {user: this.identity && this.identity.gotrue && this.identity.gotrue.currentUser()};
+ component = this;
}
componentDidMount() {
- if (this.identity && !this.state.user) {
- this.identity.on('login', (user) => {
- this.props.onLogin(user);
- this.identity.close();
- });
- this.identity.on('signup', (user) => {
- this.props.onLogin(user);
- this.identity.close();
- });
- this.identity.open();
+ if (!this.loggedIn && window.netlifyIdentity && window.netlifyIdentity.currentUser()) {
+ this.props.onLogin(window.netlifyIdentity.currentUser());
+ window.netlifyIdentity.close();
+ }
+ }
+
+ componentWillUnmount() {
+ component = null;
+ }
+
+ handleIdentityLogin = (user) => {
+ this.props.onLogin(user);
+ window.netlifyIdentity.close();
+ }
+
+ handleIdentityLogout = () => {
+ window.netlifyIdentity.open();
+ }
+
+ handleIdentity = () => {
+ if (window.netlifyIdentity.currentUser()) {
+ this.props.onLogin(user);
+ } else {
+ window.netlifyIdentity.open();
}
}
@@ -66,6 +92,15 @@ export default class AuthenticationPage extends React.Component {
const { errors } = this.state;
const { error } = this.props;
+ if (window.netlifyIdentity) {
+ return
+
+
+
+ }
+
return (
diff --git a/src/backends/netlify-auth/implementation.js b/src/backends/git-gateway/implementation.js
similarity index 65%
rename from src/backends/netlify-auth/implementation.js
rename to src/backends/git-gateway/implementation.js
index 66776c5c..2b1f58ee 100644
--- a/src/backends/netlify-auth/implementation.js
+++ b/src/backends/git-gateway/implementation.js
@@ -11,38 +11,40 @@ const localHosts = {
'127.0.0.1': true,
'0.0.0.0': true
}
+const defaults = {
+ identity: '/.netlify/identity',
+ gateway: '/.netlify/git/github'
+}
function getEndpoint(endpoint, netlifySiteURL) {
- if (localHosts[document.location.host] && netlifySiteURL && endpoint.match(/^\/\.netlify\//)) {
- const parts = [netlifySiteURL];
- if (!netlifySiteURL.match(/\/$/)) { parts.push("/"); }
- parts.push(endpoint);
+ if (localHosts[document.location.host.split(":").shift()] && netlifySiteURL && endpoint.match(/^\/\.netlify\//)) {
+ const parts = [];
+ if (netlifySiteURL) {
+ parts.push(netlifySiteURL);
+ if (!netlifySiteURL.match(/\/$/)) { parts.push("/"); }
+ }
+ parts.push(endpoint.replace(/^\//, ''));
return parts.join("");
}
return endpoint;
}
-export default class NetlifyAuth extends GitHubBackend {
+export default class GitGateway extends GitHubBackend {
constructor(config) {
super(config, true);
- if (config.getIn(["backend", "auth_url"]) == null) { throw new Error("The NetlifyAuth backend needs an \"auth_url\" in the backend configuration."); }
-
- if (config.getIn(["backend", "github_proxy_url"]) == null) {
- throw new Error("The NetlifyAuth backend needs an \"github_proxy_url\" in the backend configuration.");
- }
this.accept_roles = (config.getIn(["backend", "accept_roles"]) || List()).toArray();
const netlifySiteURL = localStorage.getItem("netlifySiteURL");
- const APIUrl = getEndpoint(config.getIn(["backend", "auth_url"]), netlifySiteURL);
- this.github_proxy_url = getEndpoint(config.getIn(["backend", "github_proxy_url"]), netlifySiteURL);
- this.authClient = new GoTrue({APIUrl});
+ const APIUrl = getEndpoint(config.getIn(["backend", "identity_url"], defaults.identity), netlifySiteURL);
+ this.github_proxy_url = getEndpoint(config.getIn(["backend", "gateway_url"], defaults.gateway), netlifySiteURL);
+ this.authClient = window.netlifyIdentity ? window.netlifyIdentity.gotrue : new GoTrue({APIUrl});
AuthenticationPage.authClient = this.authClient;
}
setUser() {
- const user = this.authClient.currentUser();
+ const user = this.authClient && this.authClient.currentUser();
if (!user) return Promise.reject();
return this.authenticate(user);
}
@@ -58,7 +60,7 @@ export default class NetlifyAuth extends GitHubBackend {
const userRoles = get(jwtDecode(token), 'app_metadata.roles', []);
if (validRole) {
const userData = {
- name: user.user_metadata.name,
+ name: user.user_metadata.name || user.email.split('@').shift(),
email: user.email,
metadata: user.user_metadata,
};
@@ -74,6 +76,14 @@ export default class NetlifyAuth extends GitHubBackend {
});
}
+ logout() {
+ if (window.netlifyIdentity) {
+ return window.netlifyIdentity.logout();
+ }
+ const user = this.authClient.currentUser();
+ return user && user.logout();
+ }
+
getToken() {
return this.tokenPromise();
}
diff --git a/src/backends/netlify-auth/netlify_logo.svg b/src/backends/git-gateway/netlify_logo.svg
similarity index 100%
rename from src/backends/netlify-auth/netlify_logo.svg
rename to src/backends/git-gateway/netlify_logo.svg
diff --git a/src/backends/github/implementation.js b/src/backends/github/implementation.js
index 8f978fa0..f071d021 100644
--- a/src/backends/github/implementation.js
+++ b/src/backends/github/implementation.js
@@ -42,6 +42,11 @@ export default class GitHub {
);
}
+ logout() {
+ this.token = null;
+ return;
+ }
+
getToken() {
return Promise.resolve(this.token);
}
diff --git a/src/backends/test-repo/AuthenticationPage.js b/src/backends/test-repo/AuthenticationPage.js
index 92ac194d..6ebe77c0 100644
--- a/src/backends/test-repo/AuthenticationPage.js
+++ b/src/backends/test-repo/AuthenticationPage.js
@@ -2,8 +2,8 @@ import React from 'react';
import Input from "react-toolbox/lib/input";
import Button from "react-toolbox/lib/button";
import { Card, Icon } from "../../components/UI";
-import logo from "../netlify-auth/netlify_logo.svg";
-import styles from "../netlify-auth/AuthenticationPage.css";
+import logo from "../git-gateway/netlify_logo.svg";
+import styles from "../git-gateway/AuthenticationPage.css";
export default class AuthenticationPage extends React.Component {
static propTypes = {
diff --git a/src/backends/test-repo/implementation.js b/src/backends/test-repo/implementation.js
index 18180aa3..c7cc22c7 100644
--- a/src/backends/test-repo/implementation.js
+++ b/src/backends/test-repo/implementation.js
@@ -36,6 +36,10 @@ export default class TestRepo {
return Promise.resolve({ email: state.email, name: nameFromEmail(state.email) });
}
+ logout() {
+ return null;
+ }
+
getToken() {
return Promise.resolve('');
}