From f012ab0f5fead02a8ac14da342ea186dcf115546 Mon Sep 17 00:00:00 2001 From: Benjamin Kyd Date: Thu, 7 Apr 2022 16:15:54 +0100 Subject: [PATCH] auth Former-commit-id: 0bcfacc0759ab1d808a2c4156e544834ab7173b2 --- .env | 2 +- client/public/auth.mjs | 66 + client/public/components/basket.mjs | 3 + client/public/components/css/navbar.css | 22 +- client/public/components/navbar.mjs | 54 +- client/public/components/storefront.mjs | 89 +- .../public/components/templates/navbar.html | 2 +- client/public/index.html | 10 + client/public/index.mjs | 5 +- client/public/product/index.html | 4 + client/public/res/lego-image1.jpg | Bin 0 -> 1046215 bytes package-lock.json | 1533 +++++++++++++++++ package.json | 3 + src/routes/api.js | 1 - 14 files changed, 1775 insertions(+), 19 deletions(-) create mode 100644 client/public/auth.mjs create mode 100644 client/public/res/lego-image1.jpg diff --git a/.env b/.env index 5081be5..3f6b922 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ NODE_ENV=dev -PORT=80 +PORT=8080 PORT_DEV=8080 LOG_LEVEL=0 diff --git a/client/public/auth.mjs b/client/public/auth.mjs new file mode 100644 index 0000000..0c44a80 --- /dev/null +++ b/client/public/auth.mjs @@ -0,0 +1,66 @@ +import { NotifyNavbar } from './components/navbar.mjs'; + +const AUTH0CONFIG = { + domain: 'benkyd.eu.auth0.com', + clientId: 'WAOkscCNYD4FzXrm6pEQi3oNKNfa8l1F', +}; + +let auth0 = null; + +async function CheckRedirect() { + const isAuthenticated = await auth0.isAuthenticated(); + if (isAuthenticated) { + return; + } + + const query = window.location.search; + if (query.includes('state=')) { + try { + // process the login state + await auth0.handleRedirectCallback(); + } catch (e) { + window.alert(e.message || 'authentication error, sorry'); + Signout(); + } + + // remove the query parameters + window.history.replaceState({}, document.title, '/'); + } +} + +export async function InitAuth0() { + auth0 = await window.createAuth0Client({ + domain: AUTH0CONFIG.domain, + client_id: AUTH0CONFIG.clientId, + }); + + await CheckRedirect(); + + const isAuthenticated = await auth0.isAuthenticated(); + if (isAuthenticated) { + const user = await auth0.getUser(); + console.log(user); + NotifyNavbar('login', user); + } +} + +export async function LoginSignup(context) { + const isAuthenticated = await auth0.isAuthenticated(); + if (isAuthenticated) { + return; + } + + const options = { + redirect_uri: window.location.origin, + response_type: 'code', + scope: 'openid profile email', + }; + + auth0.loginWithRedirect(options); +} + +export async function Signout() { + await auth0.logout({ + returnTo: window.location.origin, + }); +} diff --git a/client/public/components/basket.mjs b/client/public/components/basket.mjs index 06e33c8..a470011 100644 --- a/client/public/components/basket.mjs +++ b/client/public/components/basket.mjs @@ -125,6 +125,9 @@ class Basket extends Component { {this.state.items} + `, diff --git a/client/public/components/css/navbar.css b/client/public/components/css/navbar.css index d6a8ceb..905c371 100644 --- a/client/public/components/css/navbar.css +++ b/client/public/components/css/navbar.css @@ -158,6 +158,14 @@ z-index: 5; } +.nav-link:hover + .sub-nav { + display: block; +} + +.sub-nav:hover { + display: block; +} + /* Make sure the thing doesnt move */ /* .nav-menu { transform: translatey(-100%); @@ -181,7 +189,7 @@ transform: translatey(-100%); text-align: center; z-index: 100; - } + } .nav-menu .menu-item a { font-size: 1.5em; @@ -191,7 +199,7 @@ .menu-active .nav-menu { transform: translatey(0%); opacity: 1; - } + } .sub-nav { position: relative; @@ -200,15 +208,7 @@ display: none; background-color: rgba(0, 0, 0, 0.20); box-sizing: border-box; - } -} - -.nav-link:hover + .sub-nav { - display: block; -} - -.sub-nav:hover { - display: block; + } } /* search bar */ diff --git a/client/public/components/navbar.mjs b/client/public/components/navbar.mjs index 9bd9487..195a07c 100644 --- a/client/public/components/navbar.mjs +++ b/client/public/components/navbar.mjs @@ -1,10 +1,25 @@ import { RegisterComponent, Component, SideLoad } from './components.mjs'; +import { LoginSignup, Signout } from '../auth.mjs'; + +// due to peculiarities in asynchronus loading of components, +// we need to have this remember the state of the logged in user +// so that we can display the correct navbar +let navbarCallback = null; +export function NotifyNavbar(type, user) { + if (navbarCallback && type === 'login') { + navbarCallback.OnLogin(user); + } + if (navbarCallback && type === 'logout') { + navbarCallback.OnLogout(); + } +} class NavBar extends Component { static __IDENTIFY() { return 'navbar'; } constructor() { super(NavBar); + navbarCallback = this; } Render() { @@ -14,7 +29,7 @@ class NavBar extends Component { }; } - OnRender() { + SetupHamburger() { const menuToggler = document.querySelector('navbar-component').shadowRoot.querySelector('#menu-toggler'); const navMenu = document.querySelector('navbar-component').shadowRoot.querySelector('.navbar'); @@ -22,9 +37,42 @@ class NavBar extends Component { menuToggler.classList.toggle('menu-active'); navMenu.classList.toggle('menu-active'); }); + } - // set up basket - const basketToggler = document.querySelector('#basket-count'); + OnLogin(user) { + const account = this.root.querySelector('.account-item'); + + // doing this with proper dom manipulation wasn't working + account.innerHTML = ` + ${user.name}▾ + + `; + + const logoutButton = account.querySelector('.logout-button'); + logoutButton.addEventListener('click', () => { + Signout(); + }); + } + + OnLogout() { + const account = this.root.querySelector('.account-item'); + account.innerHTML = 'My Account'; + } + + OnRender() { + this.SetupHamburger(); + + // setup log in button + const loginButton = this.root.querySelector('.account-button'); + loginButton.addEventListener('click', () => { + LoginSignup(this); + // remove event listener and then change the + // text to the users name and a dropdown that gives + // them the option to log out + }); } } diff --git a/client/public/components/storefront.mjs b/client/public/components/storefront.mjs index d278b0a..eaa5eb7 100644 --- a/client/public/components/storefront.mjs +++ b/client/public/components/storefront.mjs @@ -10,6 +10,25 @@ class StoreFront extends Component { Render() { return { template: ` + + `, style: ` + @import url('https://unpkg.com/flickity@2/dist/flickity.min.css'); + + /* enable Flickity by default */ + .main-carousel:after { + content: 'flickity'; + display: none; /* hide :after */ + } + + .carousel-image { + object-fit: none; + /* center image */ + display: block; + margin: 0 auto; + width: 100%; + height: 100%; + } + + .carousel-cell { + height: 533px; + width: 800px; + margin-right : 10px; + } + + .carousel-caption { + position: absolute; + right: 0; + left: 0; + bottom: 0; + text-align: center; + padding: 10px; + } + + .carousel-caption h1 { + font-size: 2em; + color: #fff; + text-shadow: 0 0 5px #000; + font-weight: bold; + } + + .carousel-caption p { + } + + .carousel-caption button { + background-color: #E55744; + color: #fff; + text-shadow: 0 0 3px #000; + border: none; + padding: 10px; + font-size: 2em; + font-weight: bold; + border-radius: 5px; + } + + .carousel-caption button:hover { + background-color: #D7331D; + cursor: pointer; + } + product-list-component { z-index: 0; display: block; @@ -26,7 +103,17 @@ class StoreFront extends Component { } OnRender() { - + // setup flickity + const carousel = this.root.querySelector('.main-carousel'); + this.flkty = new window.Flickity(carousel, { + cellAlign: 'center', + contain: true, + wrapAround: true, + watchCSS: true, + autoPlay: true, + prevNextButtons: true, + pageDots: true, + }); } } diff --git a/client/public/components/templates/navbar.html b/client/public/components/templates/navbar.html index 3a38803..7ddf634 100644 --- a/client/public/components/templates/navbar.html +++ b/client/public/components/templates/navbar.html @@ -29,7 +29,7 @@
  • Bricks by price
  • -