diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx
index af7759d86f..8795b50e1d 100644
--- a/packages/app/src/components/Root/Root.tsx
+++ b/packages/app/src/components/Root/Root.tsx
@@ -18,6 +18,7 @@ import React, { FC, useContext } from 'react';
import PropTypes from 'prop-types';
import { Link, makeStyles, Typography } from '@material-ui/core';
import HomeIcon from '@material-ui/icons/Home';
+import AccountCircle from '@material-ui/icons/AccountCircle';
import {
Sidebar,
SidebarPage,
@@ -77,6 +78,7 @@ const Root: FC<{}> = ({ children }) => (
+
diff --git a/packages/core/src/api/app/AppBuilder.tsx b/packages/core/src/api/app/AppBuilder.tsx
index e2f56c4cdb..393388cc38 100644
--- a/packages/core/src/api/app/AppBuilder.tsx
+++ b/packages/core/src/api/app/AppBuilder.tsx
@@ -25,6 +25,7 @@ import {
SystemIconKey,
defaultSystemIcons,
} from '../../icons';
+import LoginPage from './LoginPage';
class AppImpl implements App {
constructor(private readonly systemIcons: SystemIcons) {}
@@ -86,6 +87,10 @@ export default class AppBuilder {
}
}
+ routes.push(
+ ,
+ );
+
return () => (
diff --git a/packages/core/src/api/app/LoginPage/LoginPage.tsx b/packages/core/src/api/app/LoginPage/LoginPage.tsx
new file mode 100644
index 0000000000..4f8214b35c
--- /dev/null
+++ b/packages/core/src/api/app/LoginPage/LoginPage.tsx
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React, { FC, useState } from 'react';
+import { GitHub as GitHubIcon } from '@material-ui/icons';
+import Page from '../../../layout/Page';
+import Header from '../../../layout/Header';
+import Content from '../../../layout/Content/Content';
+import ContentHeader from '../../../layout/ContentHeader/ContentHeader';
+import {
+ Grid,
+ Typography,
+ Button,
+ TextField,
+ List,
+ ListItem,
+ Link
+} from '@material-ui/core';
+import InfoCard from '../../../layout/InfoCard/InfoCard';
+
+enum AuthType {
+ GitHub,
+}
+
+const LoginPage: FC<{}> = () => {
+ const [githubUsername, setGithubUsername] = useState(String);
+ const [githubPersonalAuthToken, setGithubPersonalAuthToken] = useState(String);
+ const [loginDetails, setLoginDetails] = useState(Object);
+
+ const saveGithubInfo = (info: {}) => {
+ localStorage.setItem('githubLoginDetails', JSON.stringify(info));
+ setLoginDetails(info);
+ };
+
+ const deleteGithubInfo = () => {
+ localStorage.removeItem('githubLoginDetails');
+ setLoginDetails(undefined);
+ };
+
+ const handleTokenRegistration = (event: any) => {
+ switch (event.target.name) {
+ case 'github-username-tf':
+ setGithubUsername(event.target.value);
+ break;
+ case 'github-auth-tf':
+ setGithubPersonalAuthToken(event.target.value);
+ break;
+ default:
+ break;
+ }
+ };
+
+ const fetchGitHubToken = (username: String, token: String) => {
+ fetch('https://api.github.com/user', {
+ headers: new Headers({
+ Authorization: `Basic ${btoa(`${username}:${token}`)}`,
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ }),
+ })
+ .then((response) => {
+ if (response.status === 200) return response.json();
+ throw Error(`${response.status} ${response.statusText}`);
+ })
+ .then((data) => {
+ const info = {
+ username: username,
+ token: token,
+ name: data.name || data.login,
+ };
+ saveGithubInfo(info);
+ })
+ .catch(() => {});
+ };
+
+ const validateUsernameAndToken = (username: String, token: String) => {
+ if (username === undefined || username === null || username === '')
+ return false;
+
+ if (token === undefined || token === null || token === '') return false;
+
+ return true;
+ };
+
+ const authenticate = (type: AuthType) => {
+ switch (type) {
+ case AuthType.GitHub:
+ {
+ const username = githubUsername;
+ const token = githubPersonalAuthToken;
+ if (validateUsernameAndToken(username, token))
+ fetchGitHubToken(username, token);
+ }
+ break;
+ default:
+ break;
+ }
+ };
+
+ const LoginIndicator = () => {
+ const ls = localStorage.getItem('githubLoginDetails');
+ if (ls !== null) {
+ const obj = ls || loginDetails ? JSON.parse(ls) : loginDetails;
+ return (
+
+ {`Welcome, ${obj.name}!`}
+
+ Logout
+
+ );
+ }
+ return (
+
+ Welcome, guest!
+
+ );
+ };
+
+ return (
+
+
+
+
+
+
+
+
+ GitHub
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default LoginPage;
\ No newline at end of file
diff --git a/packages/core/src/api/app/LoginPage/index.ts b/packages/core/src/api/app/LoginPage/index.ts
new file mode 100644
index 0000000000..094029448c
--- /dev/null
+++ b/packages/core/src/api/app/LoginPage/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { default } from './LoginPage';