Skip to content

Commit

Permalink
Remove use of npm package moment-hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
chrieinv committed Aug 22, 2023
1 parent cda25ff commit 40d57cb
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 398 deletions.
1 change: 0 additions & 1 deletion sourcecode/proxies/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"homepage": "/admin",
"dependencies": {
"@auth0/auth0-react": "^1.12.0",
"@cerpus/edlib-components": "3.5.0",
"@material-ui/core": "^4.12.4",
"@material-ui/icons": "^4.11.3",
"@material-ui/lab": "^4.0.0-alpha.61",
Expand Down
2 changes: 1 addition & 1 deletion sourcecode/proxies/admin/src/contexts/token.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { useToken } from '@cerpus/edlib-components';
import useToken from '../hooks/useToken';
import store from 'store';
import storageKeys from '../constants/storageKeys.js';
import apiConfig from '../config/api.js';
Expand Down
33 changes: 33 additions & 0 deletions sourcecode/proxies/admin/src/hooks/useArray.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useCallback, useMemo, useState } from 'react';

const useArray = (initialArray) => {
const [value, setValue] = useState(initialArray);
const push = useCallback(
(a) => {
setValue((v) => [...v, ...(Array.isArray(a) ? a : [a])]);
},
[]
);

const removeIndex = useCallback(
(index) => setValue((v) => {
const copy = v.slice();
copy.splice(index, 1);
return copy;
}),
[]
);

const actions = useMemo(
() => ({
setValue,
push,
removeIndex,
}),
[push, removeIndex]
);

return [value, actions];
};

export default useArray;
191 changes: 191 additions & 0 deletions sourcecode/proxies/admin/src/hooks/useToken.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import debug from 'debug';
import request from '../helpers/request';
import { isTokenExpired } from '../helpers/token';

const log = debug('useToken');
const checkFrequency = 5 * 1000; //milliseconds
const tokenExpiryMargin = 2 * 60; //seconds

const useToken = ((getJwt) => {
const [jwt, setJwt] = useState(null);
const [jwtLoading, setJwtLoading] = useState(null);
const [jwtError, setJwtError] = useState(null);
const [retry, setRetry] = useState(null);
const prevCountRef = useRef(null);
const currentId = useRef(1);

useEffect(() => {
if (!prevCountRef) {
setJwt(null);
setJwtError(null);
}

prevCountRef.current = getJwt;
}, [getJwt]);

const updateToken = useCallback(() => {
if (!getJwt) {
setJwtLoading(false);
setJwtError('getJwt is not provided');
console.error('getJwt is not provided');
return null;
}

const id = currentId.current + 1;
currentId.current = id;
setJwtLoading(true);

const _update = async () => {
let newInternalToken;

if (!jwt) {
const externalToken = await getJwt();

if (!externalToken) {
setJwtError('jwt was not returned from getJwt function');
return console.error('jwt was not returned from getJwt function');
}

let getJwtTokenData = externalToken;

if (typeof externalToken === 'string') {
getJwtTokenData = {
type: 'external',
token: externalToken
};
}

if (getJwtTokenData.type === 'internal') {
newInternalToken = getJwtTokenData.token;
} else {
const {
token: internalToken
} = await request('/auth/v1/jwt/convert', 'POST', {
body: {
externalToken: getJwtTokenData.token
}
});
newInternalToken = internalToken;
}
} else {
const {
token: internalToken
} = await request('/auth/v3/jwt/refresh', 'POST', {
headers: {
Authorization: `Bearer ${jwt}`
},
body: {
token: jwt
}
});
newInternalToken = internalToken;
}

if (id !== currentId.current) {
return;
}

if (!newInternalToken) {
setJwtError('Error creating internal JWT token');
return console.error('Error creating internal JWT token');
} else if (isTokenExpired(newInternalToken)) {
setJwtError('Returned token has expired');
return console.error('Returned token has expired');
}

return setJwt(newInternalToken);
};

_update().catch(e => {
if (id !== currentId.current) {
return;
}

console.error(e);
setJwtError('Noe skjedde');
setRetry(retry => retry ? retry + 1 : 1);
}).finally(() => {
if (id !== currentId.current) {
return;
}

setJwtLoading(false);
});
}, [getJwt, setJwt, setJwtLoading, setJwtError, jwt]);

const updateTokenIfRequired = useCallback(() => {
log('Check if token must be updated');

if (jwtLoading) {
log('Not refreshing token as it is already loading a new.');
return;
}

if (jwtError && retry === null) {
log('Not refreshing token as an error has occurred and retry is null');
}

if (jwt) {
if (!isTokenExpired(jwt, tokenExpiryMargin)) {
return;
}

log('Refreshing token as it has expired');
} else {
log("Refreshing token as it doesn't exists");
}

updateToken();
}, [updateToken, jwtLoading, jwtError, jwt]);

useEffect(() => {
const interval = setInterval(() => {
updateTokenIfRequired();
}, checkFrequency);
return () => clearInterval(interval);
}, [updateTokenIfRequired]);

useEffect(() => {
if (retry) {
setTimeout(() => {
updateTokenIfRequired();
}, 5000);
}
}, [retry]);

useEffect(() => {
log('Triggering initial token loading');
updateTokenIfRequired();
}, []);

useEffect(() => {
log('Jwt updated to ', jwt);
}, [jwt]);

const getToken = useCallback(async () => {
if (jwt && !isTokenExpired(jwt)) {
return jwt;
}

throw new Error('No valid token is available');
}, [jwt]);

const reset = useCallback(async () => {
setJwt(null);
setJwtLoading(null);
setJwtError(null);
setRetry(null);
updateToken();
}, [updateToken]);

return {
token: jwt,
loading: jwtLoading,
error: jwtError,
getToken,
reset
};
});

export default useToken;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Button, Container, Grid, TextField } from '@material-ui/core';
import { useArray } from 'moment-hooks';
import useArray from '../../../../hooks/useArray';
import useRequestAction from '../../../../hooks/useRequestAction.jsx';
import { useHistory } from 'react-router-dom';
import useRequestWithToken from '../../../../hooks/useRequestWithToken.jsx';
Expand Down
Loading

0 comments on commit 40d57cb

Please sign in to comment.