Skip to content

Commit

Permalink
Update logout
Browse files Browse the repository at this point in the history
  • Loading branch information
arhtudormorar committed Jul 16, 2024
1 parent 45df82b commit 24377dd
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 69 deletions.
4 changes: 3 additions & 1 deletion src/core/methods/account/getIsLoggedIn.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { isLoggedInSelector } from 'store/selectors/accountSelectors';
import { getAddress } from './getAddress';
import { getState } from 'store/store';

export function getIsLoggedIn() {
return Boolean(getAddress());
return isLoggedInSelector(getState());
}
12 changes: 0 additions & 12 deletions src/store/actions/loginInfo/loginInfoActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,3 @@ export const setIsWalletConnectV2Initialized = (isInitialized: boolean) =>
store.setState(({ loginInfo: state }) => {
state.isWalletConnectV2Initialized = isInitialized;
});

// reset by passing null
export const updateLoginExpiresAt = (data?: null) =>
store.setState(({ loginInfo: state }) => {
if (data === null) {
state.loginExpiresAt = null;
return;
}

const loginExpiresAt = new Date().setHours(new Date().getHours() + 24);
state.loginExpiresAt = loginExpiresAt;
});
36 changes: 3 additions & 33 deletions src/store/actions/sharedActions/sharedActions.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,9 @@
import { Address } from '@multiversx/sdk-core/out';
import { initialState as initialAccountState } from 'store/slices/account/accountSlice';
import { initialState as initialLoginInfoState } from 'store/slices/loginInfo/loginInfoSlice';
import { getState, store } from '../../store';
import { store } from '../../store';
import { LoginMethodsEnum } from 'types/enums.types';
import { updateLoginExpiresAt } from '../loginInfo/loginInfoActions';

store.subscribe(
(state) => ({ account: state.account, network: state.network }), // only listen to changes in account and network
({ account }) => {
const isLoggedIn = Boolean(account.address);
const loginTimestamp = getState().loginInfo.loginExpiresAt;

if (!isLoggedIn || loginTimestamp == null) {
return;
}

const isExpired = loginTimestamp - Date.now() < 0;

if (isExpired) {
logoutAction();
return;
}

updateLoginExpiresAt();
}
);

export const logoutAction = () =>
store.setState((store) => {
store.account = initialAccountState;
store.loginInfo = initialLoginInfoState;
updateLoginExpiresAt(null);
});
import { resetStore } from 'store/middleware/logoutMiddleware';

export const logoutAction = () => store.setState(resetStore);
export interface LoginActionPayloadType {
address: string;
loginMethod: LoginMethodsEnum;
Expand All @@ -43,5 +14,4 @@ export const loginAction = ({ address, loginMethod }: LoginActionPayloadType) =>
account.address = address;
account.publicKey = new Address(address).hex();
loginInfo.loginMethod = loginMethod;
updateLoginExpiresAt();
});
7 changes: 7 additions & 0 deletions src/store/middleware/applyMiddleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { StoreType } from '../store.types';
import { StoreApi } from 'zustand/vanilla';
import { logoutMiddleware } from './logoutMiddleware';

export const applyMiddleware = (store: StoreApi<StoreType>) => {
store.subscribe(logoutMiddleware);
};
1 change: 1 addition & 0 deletions src/store/middleware/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './applyMiddleware';
46 changes: 46 additions & 0 deletions src/store/middleware/logoutMiddleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { storage } from 'storage';
import { WritableDraft } from 'immer';
import { initialState as initialAccountState } from 'store/slices/account/accountSlice';
import { initialState as initialLoginInfoState } from 'store/slices/loginInfo/loginInfoSlice';
import { localStorageKeys } from 'storage/local';
import { isLoggedInSelector } from 'store/selectors';
import { StoreType } from '../store.types';

export const resetStore = (store: WritableDraft<StoreType>) => {
store.account = initialAccountState;
store.loginInfo = initialLoginInfoState;
};

export function getNewLoginExpiresTimestamp() {
return new Date().setHours(new Date().getHours() + 24);
}

export function setLoginExpiresAt(expiresAt: number) {
storage.local.setItem({
key: localStorageKeys.loginExpiresAt,
data: expiresAt,
expires: expiresAt
});
}

export const logoutMiddleware = (newStore: StoreType) => {
const isLoggedIn = isLoggedInSelector(newStore);
const loginTimestamp = storage.local.getItem(localStorageKeys.loginExpiresAt);

if (!isLoggedIn) {
return;
}

if (loginTimestamp == null) {
setLoginExpiresAt(getNewLoginExpiresTimestamp());
return;
}

const now = Date.now();
const isExpired = loginTimestamp - now < 0;

if (isExpired) {
// logout
resetStore(newStore);
}
};
6 changes: 6 additions & 0 deletions src/store/selectors/accountSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ export const addressSelector = ({ account: { address } }: StoreType) => address;

export const accountNonceSelector = (store: StoreType) =>
accountSelector(store)?.nonce || 0;

export const isLoggedInSelector = (store: StoreType) => {
const address = addressSelector(store);
const account = accountSelector(store);
return address && account.address === address;
};
1 change: 0 additions & 1 deletion src/store/slices/loginInfo/loginInfo.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export interface LoginInfoSliceType {
walletConnectLogin: WalletConnectLoginType | null;
ledgerLogin: LedgerLoginType | null;
tokenLogin: TokenLoginType | null;
loginExpiresAt: number | null;
walletLogin: LoginInfoType | null;
extensionLogin: LoginInfoType | null;
operaLogin: LoginInfoType | null;
Expand Down
1 change: 0 additions & 1 deletion src/store/slices/loginInfo/loginInfoSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export const initialState: LoginInfoSliceType = {
walletConnectLogin: null,
ledgerLogin: null,
tokenLogin: null,
loginExpiresAt: null,
walletLogin: null,
extensionLogin: null,
operaLogin: null,
Expand Down
36 changes: 15 additions & 21 deletions src/store/store.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,43 @@
import { createStore } from 'zustand/vanilla';
import {
createJSONStorage,
devtools,
persist,
subscribeWithSelector
} from 'zustand/middleware';
import { createJSONStorage, devtools, persist } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
import { networkSlice } from './slices/network/networkSlice';
import { accountSlice } from './slices/account/accountSlice';
import { createBoundedUseStore } from './createBoundedStore';
import { loginInfoSlice } from './slices/loginInfo';
import { StoreType } from './store.types';
import { applyMiddleware } from './middleware/applyMiddleware';

export type MutatorsIn = [
['zustand/subscribeWithSelector', never],
['zustand/devtools', never],
['zustand/persist', unknown],
['zustand/immer', never]
];

export type MutatorsOut = [
['zustand/subscribeWithSelector', never],
['zustand/devtools', never],
['zustand/persist', StoreType],
['zustand/immer', never]
];

export const store = createStore<StoreType, MutatorsOut>(
subscribeWithSelector(
devtools(
persist(
immer((...args) => ({
network: networkSlice(...args),
account: accountSlice(...args),
loginInfo: loginInfoSlice(...args)
})),
{
name: 'sdk-dapp-store',
storage: createJSONStorage(() => localStorage)
}
)
devtools(
persist(
immer((...args) => ({
network: networkSlice(...args),
account: accountSlice(...args),
loginInfo: loginInfoSlice(...args)
})),
{
name: 'sdk-dapp-store',
storage: createJSONStorage(() => localStorage)
}
)
)
);

applyMiddleware(store);

export const getState = () => store.getState();

export const useStore = createBoundedUseStore(store);

0 comments on commit 24377dd

Please sign in to comment.