import GoTrue from "gotrue-js"; import jwtDecode from 'jwt-decode'; import {List} from 'immutable'; import { get, pick, intersection } from "lodash"; import GitHubBackend from "../github/implementation"; import API from "./API"; import AuthenticationPage from "./AuthenticationPage"; const localHosts = { localhost: true, '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.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 GitGateway extends GitHubBackend { constructor(config) { super(config, true); this.accept_roles = (config.getIn(["backend", "accept_roles"]) || List()).toArray(); const netlifySiteURL = localStorage.getItem("netlifySiteURL"); 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 && this.authClient.currentUser(); if (!user) return Promise.reject(); return this.authenticate(user); } authenticate(user) { this.tokenPromise = user.jwt.bind(user); return this.tokenPromise() .then((token) => { let validRole = true; if (this.accept_roles && this.accept_roles.length > 0) { validRole = intersection(userRoles, this.accept_roles).length > 0; } const userRoles = get(jwtDecode(token), 'app_metadata.roles', []); if (validRole) { const userData = { name: user.user_metadata.name || user.email.split('@').shift(), email: user.email, metadata: user.user_metadata, }; this.api = new API({ api_root: this.github_proxy_url, tokenPromise: this.tokenPromise, commitAuthor: pick(userData, ["name", "email"]), }); return userData; } else { throw new Error("You don't have sufficient permissions to access Netlify CMS"); } }); } logout() { if (window.netlifyIdentity) { return window.netlifyIdentity.logout(); } const user = this.authClient.currentUser(); return user && user.logout(); } getToken() { return this.tokenPromise(); } authComponent() { return AuthenticationPage; } }