Skip to content

Commit

Permalink
feat: check isUserLoggedIn without a network round-trip
Browse files Browse the repository at this point in the history
This improves the first page load time (one less network round-trip in most cases).
  • Loading branch information
Viktor Lukashov committed Nov 30, 2020
1 parent f36686c commit 4611870
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 43 deletions.
38 changes: 38 additions & 0 deletions frontend/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { login as loginImpl, logout as logoutImpl } from '@vaadin/flow-frontend';
import type { LoginResult } from '@vaadin/flow-frontend';

const LAST_LOGIN_TIMESTAMP = 'lastLoginTimestamp';
const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;
const lastLoginTimestamp = localStorage.getItem(LAST_LOGIN_TIMESTAMP);
const hasRecentLoginTimestamp = (lastLoginTimestamp &&
(new Date().getTime() - new Date(+lastLoginTimestamp).getTime()) < THIRTY_DAYS_MS) || false;

let _isLoggedIn = hasRecentLoginTimestamp;

export async function login(username: string, password: string): Promise<LoginResult> {
if (_isLoggedIn) {
return { error: false } as LoginResult;
} else {
const result = await loginImpl(username, password);
if (!result.error) {
_isLoggedIn = true;
localStorage.setItem(LAST_LOGIN_TIMESTAMP, new Date().getTime() + '')
}
return result;
}
}

export async function logout() {
_isLoggedIn = false;
localStorage.removeItem(LAST_LOGIN_TIMESTAMP);
return await logoutImpl();
}

export function isLoggedIn() {
return _isLoggedIn;
}

export function setSessionExpired() {
_isLoggedIn = false;
localStorage.removeItem(LAST_LOGIN_TIMESTAMP);
}
32 changes: 15 additions & 17 deletions frontend/components/login-view/login-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { customElement, html, LitElement, property } from 'lit-element';
import '@vaadin/vaadin-login/vaadin-login-overlay';
import { LoginI18n } from '@vaadin/vaadin-login/@types/interfaces';
import { Router, AfterEnterObserver, RouterLocation } from '@vaadin/router';
import { LoginResult, login } from '@vaadin/flow-frontend';
import type { LoginResult } from '@vaadin/flow-frontend';
import { login } from '../../auth';
import { Lumo } from '../../utils/lumo';
import styles from './login-view.css';

Expand All @@ -13,9 +14,6 @@ export class LoginView extends LitElement implements AfterEnterObserver {
@property({type: Boolean})
private error = false;

@property({type: Boolean})
private open = true;

@property()
private errorTitle = '';

Expand All @@ -24,31 +22,31 @@ export class LoginView extends LitElement implements AfterEnterObserver {

private returnUrl = '/';

private onSuccess: (result:LoginResult) => void;
private onSuccess = (_: LoginResult) => { Router.go(this.returnUrl) };

static styles = [Lumo, styles];

constructor(){
super();
this.onSuccess = () => {
Router.go(this.returnUrl);
};
}
private static overlayResult?: Promise<LoginResult>;
static async showOverlay(): Promise<LoginResult> {
if (this.overlayResult) {
return this.overlayResult;
}

async showOverlay(): Promise<LoginResult>{
return new Promise(resolve => {
this.onSuccess = (result: LoginResult) => {
this.remove();
const overlay = new this();
return this.overlayResult = new Promise(resolve => {
overlay.onSuccess = result => {
this.overlayResult = undefined;
overlay.remove();
resolve(result);
}
document.body.append(this);
document.body.append(overlay);
});
}

render() {
return html`
<vaadin-login-overlay
?opened="${this.open}"
opened
.error=${this.error}
.i18n="${this.i18n}"
@login="${this.login}">
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/main-layout/main-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class MainLayout extends LitElement {
<vaadin-drawer-toggle slot="navbar"></vaadin-drawer-toggle>
<div slot="navbar" class="header">
<h1 class="logo">Vaadin CRM</h1>
<a href="/logout" router-ignore>Log out</a>
<a href="/logout">Log out</a>
</div>
<div slot="drawer" class="drawer">
<ul>
Expand Down
6 changes: 4 additions & 2 deletions frontend/connect-client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {ConnectClient, InvalidSessionMiddleware} from '@vaadin/flow-frontend';
import {setSessionExpired} from './auth';
const client = new ConnectClient({prefix: 'connect', middlewares: [new InvalidSessionMiddleware(
async () => {
const {LoginView} = await import ('./components/login-view/login-view');
return new LoginView().showOverlay();
setSessionExpired();
const {LoginView} = await import ('./components/login-view/login-view');
return LoginView.showOverlay();
}
)]});
export default client;
5 changes: 2 additions & 3 deletions frontend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { Commands, Context, Router } from '@vaadin/router';

import './components/main-layout/main-layout';
import './components/list-view/list-view';
import { isUserLoggedIn } from './generated/SecurityEndpoint';
import { logout } from '@vaadin/flow-frontend';
import { isLoggedIn, logout } from './auth';

import './utils/lumo';

Expand Down Expand Up @@ -34,7 +33,7 @@ const routes = [
{
path: '/',
action: async (_: Router.Context, commands: Router.Commands) => {
if (!await isUserLoggedIn()) {
if (!isLoggedIn()) {
return commands.redirect('/login');
}
return undefined;
Expand Down

This file was deleted.

0 comments on commit 4611870

Please sign in to comment.