Skip to content

Commit

Permalink
feat(auth): restore user session from local storage
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristiaanScheermeijer committed Jul 23, 2021
1 parent 2f75031 commit a04b15e
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import './i18n/config';
import './styles/main.scss';
import { initializeWatchHistory } from './stores/WatchHistoryStore';
import { initializeFavorites } from './stores/FavoritesStore';
import { initializeAccount } from './stores/AccountStore';

interface State {
error: Error | null;
Expand All @@ -30,6 +31,7 @@ class App extends Component {
}

initializeFavorites();
initializeAccount();
}

configLoadingHandler = (isLoading: boolean) => {
Expand Down
14 changes: 13 additions & 1 deletion src/services/account.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import type { ChangePassword, GetCustomer, Login, Register, ResetPassword, UpdateCustomer } from '../../types/account';
import type {
ChangePassword,
GetCustomer,
Login,
RefreshToken,
Register,
ResetPassword,
UpdateCustomer,
} from '../../types/account';

import { post, put, patch, get } from './cleeng.service';

Expand All @@ -25,3 +33,7 @@ export const updateCustomer: UpdateCustomer = async (payload, sandbox, jwt) => {
export const getCustomer: GetCustomer = async (payload, sandbox, jwt) => {
return get(sandbox, `/customers/${payload.customerId}`, jwt);
};

export const refreshToken: RefreshToken = async (payload, sandbox) => {
return post(sandbox, '/auths/refresh_token', JSON.stringify(payload));
};
50 changes: 49 additions & 1 deletion src/stores/AccountStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import jwtDecode from 'jwt-decode';

import * as accountService from '../services/account.service';
import type { AuthData, Customer, JwtDetails } from '../../types/account';
import * as persist from '../utils/persist';

import { ConfigStore } from './ConfigStore';

const PERSIST_KEY_ACCOUNT = 'auth';

type AccountStore = {
auth: AuthData | null;
user: Customer | null;
Expand All @@ -16,10 +19,55 @@ export const AccountStore = new Store<AccountStore>({
user: null,
});

export const initializeAccount = async () => {
const { config } = ConfigStore.getRawState();
const storedSession: AuthData | null = persist.getItem(PERSIST_KEY_ACCOUNT) as AuthData | null;
let refreshTimeout: number;

AccountStore.subscribe(
(state) => state.auth,
(authData) => {
window.clearTimeout(refreshTimeout);

if (authData) {
refreshTimeout = window.setTimeout(() => refreshJwtToken(config.cleengSandbox, authData), 60 * 1000);
}

persist.setItem(PERSIST_KEY_ACCOUNT, authData);
},
);

// restore session from localStorage
if (storedSession) {
const refreshedAuthData = await getFreshJwtToken(config.cleengSandbox, storedSession);

if (refreshedAuthData) {
await afterLogin(config.cleengSandbox, refreshedAuthData);
}
}
};

const getFreshJwtToken = async (sandbox: boolean, auth: AuthData) => {
const result = await accountService.refreshToken({ refreshToken: auth.refreshToken }, sandbox);

if (result?.responseData) {
return result.responseData;
}
};

const refreshJwtToken = async (sandbox: boolean, auth: AuthData) => {
const authData = await getFreshJwtToken(sandbox, auth);

if (authData) {
AccountStore.update(s => {
s.auth = { ...s.auth, ...authData };
});
}
};

const afterLogin = async (sandbox: boolean, auth: AuthData) => {
const decodedToken: JwtDetails = jwtDecode(auth.jwt);
const customerId = decodedToken.customerId.toString();

const response = await accountService.getCustomer({ customerId }, sandbox, auth.jwt);

if (response.errors.length) throw new Error(response.errors[0]);
Expand Down
6 changes: 6 additions & 0 deletions types/account.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Offer } from './checkout';
export type AuthData = {
jwt: string;
customerToken: string;
refreshToken: string;
};

export type JwtDetails = {
Expand Down Expand Up @@ -69,6 +70,10 @@ export type UpdateCustomerPayload = {
lastName?: string;
};

export type RefreshTokenPayload = {
refreshToken: string;
};

export type Customer = {
id: string;
email: string;
Expand All @@ -88,3 +93,4 @@ type ResetPassword = CleengRequest<ResetPasswordPayload, Record<string, unknown>
type ChangePassword = CleengRequest<ChangePasswordPayload, Record<string, unknown>>;
type GetCustomer = CleengAuthRequest<GetCustomerPayload, Customer>;
type UpdateCustomer = CleengAuthRequest<UpdateCustomerPayload, Customer>;
type RefreshToken = CleengRequest<RefreshTokenPayload, AuthData>;

0 comments on commit a04b15e

Please sign in to comment.