From eea242f14fa3702b0a152cbdff80846984a35da0 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Mon, 8 Jun 2020 16:45:43 +0200 Subject: [PATCH] List auth providers in UserSettings --- .../core/src/layout/Sidebar/UserSettings.tsx | 148 +++++++++++++++--- 1 file changed, 125 insertions(+), 23 deletions(-) diff --git a/packages/core/src/layout/Sidebar/UserSettings.tsx b/packages/core/src/layout/Sidebar/UserSettings.tsx index 26cffa0c35..f4f22dd151 100644 --- a/packages/core/src/layout/Sidebar/UserSettings.tsx +++ b/packages/core/src/layout/Sidebar/UserSettings.tsx @@ -1,32 +1,110 @@ +/* + * 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, { useState, useContext, useEffect, useRef } from 'react'; import Collapse from '@material-ui/core/Collapse'; import ExpandLess from '@material-ui/icons/ExpandLess'; import ExpandMore from '@material-ui/icons/ExpandMore'; import StarBorder from '@material-ui/icons/StarBorder'; +import Star from '@material-ui/icons/Star'; import { SidebarContext } from './config'; -import { SidebarItem, SidebarDivider } from './Items'; +import { SidebarItem } from './Items'; import AccountCircleIcon from '@material-ui/icons/AccountCircle'; import Divider from '@material-ui/core/Divider'; -import { useApi, googleAuthApiRef, ProfileInfo } from '@backstage/core-api'; -import { Avatar, IconButton } from '@material-ui/core'; +import { + useApi, + googleAuthApiRef, + githubAuthApiRef, + ProfileInfo, +} from '@backstage/core-api'; +import { Avatar, IconButton, makeStyles, Tooltip } from '@material-ui/core'; import PowerButton from '@material-ui/icons/PowerSettingsNew'; -import { SidebarThemeToggle } from './SidebarThemeToggle'; +// import { SidebarThemeToggle } from './SidebarThemeToggle'; + +type Provider = { + title: string; + api: any; + identity?: boolean; + isSignedIn: boolean; + icon: any; +}; + +const useProviders = () => { + const googleAuth = useApi(googleAuthApiRef); + const githubAuth = useApi(githubAuthApiRef); + const [providers, setProviders] = useState([ + { + title: 'Google', + api: googleAuth, + identity: true, + isSignedIn: false, + icon: Star, + }, + { + title: 'Github', + api: githubAuth, + isSignedIn: false, + icon: StarBorder, + }, + ]); + + Promise.all( + providers.map((provider: Provider) => + provider.identity + ? provider.api.getIdToken({ optional: true }) + : provider.api.getAccessToken('', { optional: true }), + ), + ).then(results => { + results.map((result, i) => { + providers[i].isSignedIn = !!result; + }); + + setProviders(providers); + }); + + return providers; +}; + +const useStyles = makeStyles({ + avatar: { + width: 24, + height: 24, + }, +}); export function SidebarUserSettings() { const { isOpen: sidebarOpen } = useContext(SidebarContext); const [open, setOpen] = React.useState(false); const ref = useRef(); // for scrolling down when collapse item opens - - const googleAuth = useApi(googleAuthApiRef); + const providers = useProviders(); const [profile, setProfile] = useState(); + const classes = useStyles(); // TODO(soapraj): List all the providers supported by the app and let user log in from here // TODO(soapraj): How to observe if the user is logged in useEffect(() => { - googleAuth.getProfile({ optional: true }).then(googleProfile => { - setProfile(googleProfile); - }); - }, [googleAuth, open]); + const identityProvider = providers.find( + (provider: Provider) => provider.identity, + ); + identityProvider?.api + .getProfile({ optional: true }) + .then((userProfile: ProfileInfo) => { + setProfile(userProfile); + }); + }, [providers, open]); const handleClick = () => { setOpen(!open); @@ -36,13 +114,12 @@ export function SidebarUserSettings() { // Close the provider list when sidebar collapse useEffect(() => { if (!sidebarOpen && open) setOpen(false); - }, [sidebarOpen]); + }, [open, sidebarOpen]); // Handle main auth info that is shown on the collapsible SidebarItem let avatar; let displayName; if (profile) { - // const classes = useStyles(); const email = profile.email; const name = profile.name; const imageUrl = profile.picture; @@ -52,8 +129,12 @@ export function SidebarUserSettings() { emailTrimmed.charAt(0).toUpperCase() + emailTrimmed.slice(1); displayName = name ?? displayEmail; avatar = imageUrl - ? () => - : () => {avatarFallback[0]}; + ? () => + : () => ( + + {avatarFallback[0]} + + ); } return ( @@ -65,18 +146,39 @@ export function SidebarUserSettings() { icon={avatar || AccountCircleIcon} disableSelected > - {open ? : } + {open ? : } - - - profile ? googleAuth.logout() : googleAuth.getAccessToken() - } + {providers.map((provider: Provider) => ( + - - - + + provider.isSignedIn + ? provider.api.logout() + : provider.api.getAccessToken() + } + > + + + + + + ))} );