Skip to content

Commit

Permalink
handle HTTP 429 during login nicely for better UX
Browse files Browse the repository at this point in the history
  • Loading branch information
sebadob committed Oct 25, 2023
1 parent 98e5f1a commit 3e0a389
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 44 deletions.
51 changes: 41 additions & 10 deletions frontend/src/routes/oidc/authorize/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import {onMount, tick} from "svelte";
import {authorize, authorizeRefresh, getClientLogo, postPasswordResetRequest} from "../../../utils/dataFetching.js";
import * as yup from 'yup';
import {extractFormErrors, getQueryParams, saveCsrfToken} from "../../../utils/helpers.js";
import {extractFormErrors, formatDateFromTs, getQueryParams, saveCsrfToken} from "../../../utils/helpers.js";
import Button from "$lib/Button.svelte";
import WebauthnRequest from "../../../components/webauthn/WebauthnRequest.svelte";
import {scale} from 'svelte/transition';
Expand Down Expand Up @@ -44,6 +44,7 @@
let showReset = false;
let showResetRequest = false;
let emailSuccess = false;
let tooManyRequests = false;
let emailAfterSubmit = '';
let formValues = {email: '', password: ''};
Expand Down Expand Up @@ -134,6 +135,8 @@
}
async function onSubmit() {
err = '';
try {
await schema.validate(formValues, {abortEarly: false});
formErrors = {};
Expand Down Expand Up @@ -172,6 +175,23 @@
} else if (res.status === 200) {
err = '';
webauthnData = await res.json();
} else if (res.status === 429) {
let notBefore = Number.parseInt(res.headers.get('x-retry-not-before'));
let nbfDate = formatDateFromTs(notBefore);
let diff = notBefore * 1000 - new Date().getTime();
console.log(diff);
tooManyRequests = true;
err = `${t.http429} ${nbfDate}`;
formValues.email = '';
formValues.password = '';
needsPassword = false;
setTimeout(() => {
tooManyRequests = false;
err = '';
}, diff);
} else if (!needsPassword) {
// this will happen always if the user does the first try with a password-only account
// the good thing about this is, that it is a prevention against autofill passwords from the browser
Expand All @@ -189,6 +209,8 @@
// a password and afterward changes his email again
if (needsPassword && emailAfterSubmit !== formValues.email) {
needsPassword = false;
formValues.password = '';
err = '';
}
}
Expand Down Expand Up @@ -270,6 +292,7 @@
bind:error={formErrors.email}
autocomplete="email"
placeholder={t.email}
disabled={tooManyRequests}
on:enter={onSubmit}
on:input={onEmailInput}
>
Expand All @@ -284,12 +307,13 @@
bind:error={formErrors.password}
autocomplete="current-password"
placeholder={t.password}
disabled={tooManyRequests}
on:enter={onSubmit}
>
{t.password?.toUpperCase()}
</PasswordInput>
{#if showResetRequest}
{#if showResetRequest && !tooManyRequests}
<div
role="button"
tabindex="0"
Expand All @@ -303,14 +327,20 @@
{/if}
{/if}
{#if showReset}
<div class="btn">
<Button on:click={requestReset}>{t.passwordRequest?.toUpperCase()}</Button>
</div>
{:else}
<div class="btn">
<Button on:click={onSubmit} bind:isLoading>{t.login?.toUpperCase()}</Button>
</div>
{#if !tooManyRequests}
{#if showReset}
<div class="btn">
<Button on:click={requestReset}>
{t.passwordRequest?.toUpperCase()}
</Button>
</div>
{:else}
<div class="btn">
<Button on:click={onSubmit} bind:isLoading>
{t.login?.toUpperCase()}
</Button>
</div>
{/if}
{/if}
{#if err}
Expand Down Expand Up @@ -346,6 +376,7 @@
}
.errMsg {
max-width: 15rem;
margin: -5px 10px 0 10px;
color: var(--col-err)
}
Expand Down
34 changes: 0 additions & 34 deletions frontend/src/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,6 @@ import {
import sjcl from "sjcl";
import { decode, encode } from "base64-arraybuffer";

// export function getCookie(cname) {
// let name = cname + "=";
// let decodedCookie = decodeURIComponent(document.cookie);
// let ca = decodedCookie.split(';');
// for (let i = 0; i < ca.length; i++) {
// let c = ca[i];
// while (c.charAt(0) === ' ') {
// c = c.substring(1);
// }
// if (c.indexOf(name) === 0) {
// return c.substring(name.length, c.length);
// }
// }
// return "";
// }
//
// function deleteCookie(name) {
// document.cookie = name + '=; Max-Age=-1;';
// }

export function extractFormErrors(err) {
return err.inner.reduce((acc, err) => {
return {...acc, [err.path]: err.message};
Expand Down Expand Up @@ -72,18 +52,9 @@ export const saveIdToken = (token) => {
localStorage.setItem(ID_TOKEN, token);
}

export const getIdToken = () => {
return localStorage.getItem(ID_TOKEN) || '';
}

export const saveAccessToken = (token) => {
localStorage.setItem(ACCESS_TOKEN, token);
}

export const getAccessToken = () => {
return localStorage.getItem(ACCESS_TOKEN) || '';
}

export const getVerifierFromStorage = () => {
return localStorage.getItem(PKCE_VERIFIER) || '';
};
Expand Down Expand Up @@ -134,11 +105,6 @@ export const computePow = (powChallenge) => {
}


// export const dateFromUtcTs = (ts) => {
// const utcOffsetMinutes = -new Date().getTimezoneOffset();
// return new Date((ts + utcOffsetMinutes * 60) * 1000);
// }

export const formatDateToDateInput = date => {
return date.toISOString().split('.')[0];
}
Expand Down

0 comments on commit 3e0a389

Please sign in to comment.