Skip to content

Commit

Permalink
Improve robustness of refresh token handling
Browse files Browse the repository at this point in the history
  • Loading branch information
domdomegg committed Apr 5, 2024
1 parent b9f8a37 commit 04404a6
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
4 changes: 2 additions & 2 deletions apps/server/src/helpers/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ export const login = async (email: string): Promise<LoginResponse> => {
subject: email,
groups,
iat: now,
exp: now + 3600, // 1 hour
exp: now + 20, // 1 hour
};

const refreshTokenPayload: RefreshTokenPayload = {
subject: email,
iat: now,
exp: now + 3600 * 24, // 1 day
exp: now + 3600 * 8, // 8 hours
};

return {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/helpers/networking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const getAuthFromLocalStorage = (): AuthState | undefined => {
if (typeof parsed.refreshToken !== 'object') return undefined;
if (typeof parsed.refreshToken.value !== 'string') return undefined;
if (typeof parsed.refreshToken.expiresAt !== 'number') return undefined;
if (parsed.refreshToken.expiresAt < (new Date().getTime() / 1000)) return undefined;
if (parsed.refreshToken.expiresAt < (Date.now() / 1000)) return undefined;
if (!Array.isArray(parsed.groups)) return undefined;
if (!parsed.groups.every((g: unknown) => typeof g === 'string')) return undefined;
return {
Expand Down
24 changes: 20 additions & 4 deletions apps/web/src/pages/admin/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Helmet from 'react-helmet';
import { Router } from '@gatsbyjs/reach-router';
import { RouteComponentProps, Router } from '@gatsbyjs/reach-router';
import { useEffect, useState } from 'react';
import Page from '../../components/Page';
import FundraisersPage from './fundraisers';
Expand All @@ -19,6 +19,7 @@ import UsersPage from './users';
import UserPage from './user';
import GroupPage from './group';
import { helpLink } from './_helpLink';
import Spinner from '../../components/Spinner';

const IndexPage = () => (
<Page className="pb-8">
Expand All @@ -40,6 +41,10 @@ const IndexLayout = () => {

const msUntilExpiration = (auth.refreshToken.expiresAt * 1000) - Date.now();

if (msUntilExpiration > 60_000) {
setLogoutWarning(undefined);
}

const warningTimeout = setTimeout(() => {
setLogoutWarning('You will be logged out in the next minute');
}, msUntilExpiration - 60_000);
Expand All @@ -54,9 +59,10 @@ const IndexLayout = () => {
useEffect(() => setHasMounted(true), []);
if (!hasMounted) return null;

const hasActiveLoginToken = auth && auth.accessToken.expiresAt > (Date.now() / 1000 + 10);
return (
<>
{auth && (
{hasActiveLoginToken && (
<Navigation
left={[
{ text: 'Fundraisers', href: '/admin/' },
Expand All @@ -71,15 +77,15 @@ const IndexLayout = () => {
]}
/>
)}
{logoutWarning && auth && (
{logoutWarning && hasActiveLoginToken && (
<Section>
<Alert variant="warning">{logoutWarning}</Alert>
</Section>
)}
<Router basepath="/admin" className="text-left">
<OauthCallbackPage path="/oauth-callback" />

{auth && (
{hasActiveLoginToken && (
<>
<FundraisersPage path="/" />
<FundraiserPage fundraiserId="" path="/:fundraiserId" />
Expand All @@ -95,10 +101,20 @@ const IndexLayout = () => {
</>
)}

{auth && !hasActiveLoginToken && <LoadingPage default />}
{!auth && <Login default />}
</Router>
</>
);
};

const LoadingPage: React.FC<RouteComponentProps> = () => {
return (
<div className="flex justify-center gap-4 py-24">
<span>Logging in...</span>
<Spinner />
</div>
);
};

export default IndexPage;

0 comments on commit 04404a6

Please sign in to comment.