From 2cfee78597971b2e3e7e612eb9d7e8805e1aef85 Mon Sep 17 00:00:00 2001 From: ivarlovlie Date: Mon, 10 Aug 2020 21:35:58 +0200 Subject: add signing credentials --- src/browser/package-lock.json | 19 ++ src/browser/package.json | 5 +- src/browser/src/api/account.js | 76 +------- src/browser/src/constants.js | 8 - src/browser/src/router.js | 4 +- src/browser/src/store.js | 11 ++ src/browser/src/styles/codyframe/_base.scss | 44 ++--- src/browser/src/styles/codyframe/_btn-states.scss | 55 +++--- .../src/styles/codyframe/_custom-style.scss | 14 +- .../src/styles/codyframe/_radios-checkboxes.scss | 149 ++++++++++++++++ src/browser/src/views/Forgot.vue | 66 +++++-- src/browser/src/views/Home.vue | 10 +- src/browser/src/views/Login.vue | 192 ++------------------- src/browser/src/views/OidcCallback.vue | 11 +- 14 files changed, 329 insertions(+), 335 deletions(-) create mode 100644 src/browser/src/styles/codyframe/_radios-checkboxes.scss (limited to 'src/browser') diff --git a/src/browser/package-lock.json b/src/browser/package-lock.json index 2e5511f..ecb17cb 100644 --- a/src/browser/package-lock.json +++ b/src/browser/package-lock.json @@ -1123,6 +1123,11 @@ "to-regex-range": "^5.0.1" } }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + }, "follow-redirects": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz", @@ -1752,6 +1757,11 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, "log-symbols": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", @@ -2919,6 +2929,15 @@ "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.0-beta.4.tgz", "integrity": "sha512-/+4E1dokq5cwbl4mohOqOj8h0vOLOWmLSqlqTf++bfmN9/JKWtwYfsBrzlK0sYrNfuYcpQeX0BVxQHoHXDfYZQ==" }, + "vuex-persist": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vuex-persist/-/vuex-persist-2.2.0.tgz", + "integrity": "sha512-o/qbBeMcKZZqMvCXc7kfIew/5cjHxlP1f53rx5YYp3r2tk2kxXYK/UZumxKn7OXywlurl2r0mgkuBzH6nIWFjw==", + "requires": { + "flatted": "^2.0.0", + "lodash.merge": "^4.6.2" + } + }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", diff --git a/src/browser/package.json b/src/browser/package.json index baec9c1..16f440f 100644 --- a/src/browser/package.json +++ b/src/browser/package.json @@ -8,9 +8,10 @@ }, "dependencies": { "oidc-client": "^1.10.1", - "vue-router": "^4.0.0-0", "vue": "^3.0.0-rc.1", - "vuex": "^4.0.0-0" + "vue-router": "^4.0.0-0", + "vuex": "^4.0.0-0", + "vuex-persist": "^2.2.0" }, "devDependencies": { "@vue/compiler-sfc": "^3.0.0-rc.1", diff --git a/src/browser/src/api/account.js b/src/browser/src/api/account.js index 665eb3f..88522d6 100644 --- a/src/browser/src/api/account.js +++ b/src/browser/src/api/account.js @@ -18,8 +18,6 @@ const userManager = new Oidc.UserManager({ Oidc.Log.logger = console; Oidc.Log.level = Oidc.Log.INFO; -let currentUser; -let signedIn = false; userManager.events.addUserLoaded(function (user) { store.commit("setProfileData", user); @@ -48,9 +46,8 @@ userManager.events.addSilentRenewError(function () { }); userManager.events.addUserSignedOut(function () { - alert("Logout"); console.log("UserSignedOut:", arguments); - //userManager.removeUser(); + userManager.removeUser(); userManager .signoutRedirect() .then(function (resp) { @@ -70,39 +67,23 @@ export default { signinRedirectCallback() { userManager.signinRedirectCallback().then( - () => { - console.log("Logged in"); - }, - (error) => { - console.error(error); - } + (res) => console.log(res), + (error) => console.error(error) ); }, signOut() { - var self = this; userManager .signoutRedirect() .then(function (resp) { - self.signedIn = false; - console.log("signed out", resp); + return true; }) .catch(function (err) { - console.log(err); + console.error(err); + return false; }); }, - showTokens() { - userManager.getUser().then(function (user) { - if (user) { - console.log("Profile", user.profile); - console.log("Role", user.profile.role); - } else { - self.signIn(); - } - }); - }, - getUser() { let self = this; return new Promise((resolve, reject) => { @@ -117,50 +98,7 @@ export default { } }) .catch(function (err) { - console.log(err); - return reject(err); - }); - }); - }, - - getSignedIn() { - let self = this; - return new Promise((resolve, reject) => { - userManager - .getUser() - .then(function (user) { - if (user == null) { - self.signIn(); - return resolve(false); - } else { - currentUser = user; - signedIn = true; - return resolve(signedIn); - } - }) - .catch(function (err) { - console.log(err); - return reject(err); - }); - }); - }, - - getRole() { - let self = this; - return new Promise((resolve, reject) => { - userManager - .getUser() - .then(function (user) { - if (user == null) { - self.signIn(); - return resolve(false); - } else { - currentUser = user; - return resolve(user.profile.role); - } - }) - .catch(function (err) { - console.log(err); + console.error(err); return reject(err); }); }); diff --git a/src/browser/src/constants.js b/src/browser/src/constants.js index 471cc92..cb78214 100644 --- a/src/browser/src/constants.js +++ b/src/browser/src/constants.js @@ -1,12 +1,4 @@ export default { api_address: "http://localhost:5001", client_address: "http://localhost:3000", - storageKeys: { - cookie_last_seen: "cookie-last-seen", - }, - types: { - set_profile_data: "set-profile-data", - login_async: "login-async", - download_profile_data: "download-profile-data-async", - }, }; diff --git a/src/browser/src/router.js b/src/browser/src/router.js index 0fd5462..53df01f 100644 --- a/src/browser/src/router.js +++ b/src/browser/src/router.js @@ -66,9 +66,9 @@ const router = createRouter({ }); router.beforeEach((to, from, next) => { - console.log("store.state.profile.isAuthenticated: " + store.state.profile.isAuthenticated); + console.log("store.state.isAuthenticated: " + store.state.isAuthenticated); const publicPaths = routes.filter((r) => r.isPublic); - if (publicPaths.every((c) => c.path !== to.path) && !store.state.profile.isAuthenticated) + if (publicPaths.every((c) => c.path !== to.path) && !store.state.isAuthenticated) next("/login"); else next(); }); diff --git a/src/browser/src/store.js b/src/browser/src/store.js index c775ed8..ba69ba5 100644 --- a/src/browser/src/store.js +++ b/src/browser/src/store.js @@ -1,15 +1,26 @@ import { createStore } from "vuex"; +import VuexPersistence from "vuex-persist"; + +const vuexLocal = new VuexPersistence({ + storage: window.localStorage, +}); export default createStore({ strict: true, state: { + isAuthenticated: false, profile: {}, }, mutations: { setProfileData(state, profile) { state.profile = profile; + state.isAuthenticated = profile.profile != undefined; + }, + checkForAuthState(state) { + state.isAuthenticated = state.profile.profile != undefined; }, }, actions: {}, modules: {}, + plugins: [vuexLocal.plugin], }); diff --git a/src/browser/src/styles/codyframe/_base.scss b/src/browser/src/styles/codyframe/_base.scss index 5b4bdf6..1810765 100644 --- a/src/browser/src/styles/codyframe/_base.scss +++ b/src/browser/src/styles/codyframe/_base.scss @@ -1,23 +1,23 @@ -@import 'base/reset'; -@import 'base/breakpoints'; -@import 'base/mixins'; -@import 'base/colors'; -@import 'base/spacing'; -@import 'base/grid-layout'; -@import 'base/shared-styles'; -@import 'base/typography'; -@import 'base/icons'; -@import 'base/buttons'; -@import 'base/forms'; -@import 'base/z-index'; -@import 'base/visibility'; -@import 'base/accessibility'; +@import "base/reset"; +@import "base/breakpoints"; +@import "base/mixins"; +@import "base/colors"; +@import "base/spacing"; +@import "base/grid-layout"; +@import "base/shared-styles"; +@import "base/typography"; +@import "base/icons"; +@import "base/buttons"; +@import "base/forms"; +@import "base/z-index"; +@import "base/visibility"; +@import "base/accessibility"; +@import "base/util"; -@import 'base/util'; -@import 'custom-style/colors'; -@import 'custom-style/spacing'; -@import 'custom-style/shared-styles'; -@import 'custom-style/typography'; -@import 'custom-style/icons'; -@import 'custom-style/buttons'; -@import 'custom-style/forms'; +@import "custom-style/colors"; +@import "custom-style/spacing"; +@import "custom-style/shared-styles"; +@import "custom-style/typography"; +@import "custom-style/icons"; +@import "custom-style/buttons"; +@import "custom-style/forms"; diff --git a/src/browser/src/styles/codyframe/_btn-states.scss b/src/browser/src/styles/codyframe/_btn-states.scss index bc1498f..fcb2105 100644 --- a/src/browser/src/styles/codyframe/_btn-states.scss +++ b/src/browser/src/styles/codyframe/_btn-states.scss @@ -8,44 +8,43 @@ Usage: codyhouse.co/license -------------------------------- */ .btn .btn__content-a { - display: inline-flex; + display: inline-flex; } - .btn .btn__content-b { - display: none; + display: none; } -.btn__content-a, .btn__content-b { - align-items: center; +.btn__content-a, +.btn__content-b { + align-items: center; } .btn--state-b { - .btn__content-a { - display: none; - } - - .btn__content-b { - display: inline-block; // fallback - display: inline-flex; - } + .btn__content-a { + display: none; + } + + .btn__content-b { + display: inline-block; // fallback + display: inline-flex; + } } /* preserve button width when switching from state A to state B */ .btn--preserve-width { - .btn__content-b { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - justify-content: center; - } - - &.btn--state-b .btn__content-a { - display: inline-block; // fallback - display: inline-flex; - visibility: hidden; - } + .btn__content-b { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + justify-content: center; + } + + &.btn--state-b .btn__content-a { + display: inline-block; // fallback + display: inline-flex; + visibility: hidden; + } } - diff --git a/src/browser/src/styles/codyframe/_custom-style.scss b/src/browser/src/styles/codyframe/_custom-style.scss index 67e3481..3882275 100644 --- a/src/browser/src/styles/codyframe/_custom-style.scss +++ b/src/browser/src/styles/codyframe/_custom-style.scss @@ -1,7 +1,7 @@ -@import 'custom-style/colors'; -@import 'custom-style/spacing'; -@import 'custom-style/shared-styles'; -@import 'custom-style/typography'; -@import 'custom-style/icons'; -@import 'custom-style/buttons'; -@import 'custom-style/forms'; +@import "custom-style/colors"; +@import "custom-style/spacing"; +@import "custom-style/shared-styles"; +@import "custom-style/typography"; +@import "custom-style/icons"; +@import "custom-style/buttons"; +@import "custom-style/forms"; diff --git a/src/browser/src/styles/codyframe/_radios-checkboxes.scss b/src/browser/src/styles/codyframe/_radios-checkboxes.scss new file mode 100644 index 0000000..ec16b8e --- /dev/null +++ b/src/browser/src/styles/codyframe/_radios-checkboxes.scss @@ -0,0 +1,149 @@ + + +/* -------------------------------- + +File#: _1_radios-checkboxes +Title: Radios and Checkboxes +Descr: Custom radio and checkbox buttons +Usage: codyhouse.co/license + +-------------------------------- */ + +:root { + // radios and checkboxes + --checkbox-radio-size: 1em; + --checkbox-radio-translate-y: 0.15em; // edit to align buttons with labels + --checkbox-radio-gap: var(--space-xxxs); // gap between button and label + --checkbox-radio-border-width: 2px; + --checkbox-radio-line-height: var(--body-line-height); + + // radio buttons + --radio-marker-size: 8px; + + // checkboxes + --checkbox-marker-size: 12px; + --checkbox-radius: 0.185em; +} + +.radio, +.checkbox { + // hide native buttons + position: absolute; + margin: 0 !important; + padding: 0 !important; + opacity: 0; + height: 0; + width: 0; + pointer-events: none; +} + +.radio + label, +.checkbox + label { // label style + display: inline-block; // fallback + display: inline-flex; + align-items: baseline; + line-height: var(--checkbox-radio-line-height); + user-select: none; + cursor: pointer; +} + +.radio + label::before, +.checkbox + label::before { // custom buttons - basic style + content: ''; + display: inline-block; + vertical-align: middle; // fallback + flex-shrink: 0; + width: var(--checkbox-radio-size); + height: var(--checkbox-radio-size); + background-color: var(--color-bg); + border-width: var(--checkbox-radio-border-width); + border-color: var(--color-contrast-low); + border-style: solid; + margin-right: var(--checkbox-radio-gap); + background-repeat: no-repeat; + background-position: center; + transition: transform .2s, border .2s; +} + +.radio:not(:checked):not(:focus) + label:hover::before, +.checkbox:not(:checked):not(:focus) + label:hover::before { // :hover + border-color: var(--color-contrast-medium); +} + +@supports (grid-area: auto) { + .radio + label::before, + .checkbox + label::before { + position: relative; + top: var(--checkbox-radio-translate-y); + } +} + +.radio + label::before { + border-radius: 50%; // radio button radius +} + +.checkbox + label::before { + border-radius: var(--checkbox-radius); // checkbox button radius +} + +.radio:checked + label::before, +.checkbox:checked + label::before { + // checked state + background-color: var(--color-primary); + box-shadow: none; + border-color: var(--color-primary); + transition: transform .2s; +} + +.radio:active + label::before, +.checkbox:active + label::before { + // active state + transform: scale(0.8); + transition: transform .2s; +} + +.radio:checked:active + label::before, +.checkbox:checked:active + label::before { + transform: none; + transition: none; +} + +.radio:checked + label::before { + // radio button icon + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cg class='nc-icon-wrapper' fill='%23ffffff'%3E%3Ccircle cx='8' cy='8' r='8' fill='%23ffffff'%3E%3C/circle%3E%3C/g%3E%3C/svg%3E"); + background-size: var(--radio-marker-size); +} + +.checkbox:checked + label::before { + // checkbox button icon + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cg class='nc-icon-wrapper' stroke-width='2' fill='%23ffffff' stroke='%23ffffff'%3E%3Cpolyline fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10' points='1,9 5,13 15,3 ' data-cap='butt'%3E%3C/polyline%3E%3C/g%3E%3C/svg%3E"); + background-size: var(--checkbox-marker-size); +} + +.radio:checked:active + label::before, +.checkbox:checked:active + label::before, +.radio:focus + label::before, +.checkbox:focus + label::before { + // focus state + border-color: var(--color-primary); + box-shadow: 0 0 0 3px alpha(var(--color-primary), 0.2); +} + +// --radio--bg, --checkbox--bg +.radio--bg + label, .checkbox--bg + label { + padding: var(--space-xxxxs) var(--space-xxxs); + border-radius: var(--radius-md); + transition: background .2s; +} + +.radio--bg + label:hover, .checkbox--bg + label:hover { + background-color: var(--color-contrast-lower); +} + +.radio--bg:active + label, +.checkbox--bg:active + label, +.radio--bg:focus + label, +.checkbox--bg:focus + label { + background-color: alpha(var(--color-primary), 0.1); +} + diff --git a/src/browser/src/views/Forgot.vue b/src/browser/src/views/Forgot.vue index 0e78904..efe367c 100644 --- a/src/browser/src/views/Forgot.vue +++ b/src/browser/src/views/Forgot.vue @@ -1,18 +1,14 @@ diff --git a/src/browser/src/views/Login.vue b/src/browser/src/views/Login.vue index a94ea9e..c021fca 100644 --- a/src/browser/src/views/Login.vue +++ b/src/browser/src/views/Login.vue @@ -1,193 +1,29 @@ - - diff --git a/src/browser/src/views/OidcCallback.vue b/src/browser/src/views/OidcCallback.vue index 10ccd52..1735696 100644 --- a/src/browser/src/views/OidcCallback.vue +++ b/src/browser/src/views/OidcCallback.vue @@ -1,8 +1,15 @@ -- cgit v1.3