Skip to content

Commit

Permalink
Fix to limit rerenders (reducers) and API token endpoint calling to m…
Browse files Browse the repository at this point in the history
…inimum required (once per action and page load)
  • Loading branch information
mluypaert committed Jan 9, 2024
1 parent 8f5c86d commit 84aff72
Showing 1 changed file with 88 additions and 58 deletions.
146 changes: 88 additions & 58 deletions client/src/containers/Authenticate/TokenMgmt.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,109 @@ import { CopyToClipboard } from 'react-copy-to-clipboard';

import { Button } from '../../components/elements';
import AuthorizationContext from '../../containers/Authenticate/AuthorizationContext';
import { useCallback } from 'react';

const ACTION_STORE = 'STORE';
const ACTION_REVOKE = 'REVOKE';
const UPDATE_METADATA = 'UPDATE_METADATA';

function tokenMetaDataReducer(state, action) {
let newState = { ...state };

switch (action.type) {
case UPDATE_METADATA:
console.log('Metadata update trigerred.');
newState = { ...action['payload'] };
break;
default:
console.log('Invalid action type detected:');
console.log(action.type);
throw new Error();
}

function TokenMgmt() {
const ACTION_STORE = 'STORE';
const ACTION_REVOKE = 'REVOKE';
const UPDATE_METADATA = 'UPDATE_METADATA';
return newState;
}

function tokenReducer(state, action) {
const newState = { ...state };

switch (action.type) {
case ACTION_STORE:
newState['apiToken'] = action.payload;
break;
case ACTION_REVOKE:
newState['apiToken'] = null;
break;
default:
console.log('Invalid action type detected:');
console.log(action.type);
throw new Error();
}

return newState;
}

function TokenMgmt() {
const { authorizedFetch, user } = useContext(AuthorizationContext);

const [tokenState, dispatchTokenState] = useReducer(tokenReducer, {
apiToken: null,
tokenMetadata: {
});

const [tokenMetaDataState, dispatchTokenMetaData] = useReducer(
tokenMetaDataReducer,
{
'token-stored?': false,
'last-used': null,
}
);

const updateTokenMetadata = useCallback(
() => {
authorizedFetch('/api/auth/token-metadata', { method: 'GET' })
.then((response) => {
if (response.ok) {
return response.json();
} else {
console.log(
'Error while retrieving token metadata. Returned response: ',
response
);
throw new Error('Error while retrieving token metadata');
}
})
.then((data) => {
console.log('token-metadata result received:', data);

dispatchTokenMetaData({ type: UPDATE_METADATA, payload: data });
})
.catch((error) => {
console.log(
'Error caught on authorizedFetch for token-metadata:',
error
);
});
},
});
[authorizedFetch]
);

const defaultTokenInstructions =
'No stored ID token to display.\n' +
"Click the 'Store token' button below to store the current ID token and display it here.";

function tokenReducer(state, action) {
const newState = { ...state };

switch (action.type) {
case ACTION_STORE:
newState['apiToken'] = user.id_token;
break;
case ACTION_REVOKE:
newState['apiToken'] = null;
break;
case UPDATE_METADATA:
console.log('Metadata update trigerred.');
newState['tokenMetadata'] = { ...action.payload };
break;
default:
console.log('Invalid action type detected:');
console.log(action.type);
throw new Error();
}

return newState;
}

function storeTokenHandler() {
console.log('storeTokenHandler triggered.');

authorizedFetch(`/api/auth/token`, {
method: 'POST',
}).then((response) => {
if (response.ok) {
updateTokenMetadata();
dispatchTokenState({ type: ACTION_STORE, payload: user.id_token });
} else {
console.log('Error returned by /auth/token POST endpoint.');
throw new Error('API endpoint for token storage returned error.');
}
});

dispatchTokenState({ type: ACTION_STORE });
}

function revokeTokenHandler() {
Expand All @@ -69,44 +115,28 @@ function TokenMgmt() {
method: 'DELETE',
}).then((response) => {
if (response.ok) {
updateTokenMetadata();
dispatchTokenState({ type: ACTION_REVOKE });
} else {
console.log('Error returned by /auth/token DELETE endpoint.');
throw new Error('API endpoint for token revoking returned error.');
}
});

dispatchTokenState({ type: ACTION_REVOKE });
}

function updateTokenMetadata() {
authorizedFetch('/api/auth/token-metadata', { method: 'GET' })
.then((response) => {
return Promise.all([response, response.json()]);
})
.then(([response, data]) => {
if (response.ok) {
console.log('authorizedFetch data results:', data);
dispatchTokenState({ type: UPDATE_METADATA, payload: data });
} else {
console.log('Error while retrieving token metadata.');
}
});
}

useEffect(() => {
updateTokenMetadata();
}, []);
useEffect(
() => {
updateTokenMetadata();
},
[tokenState, updateTokenMetadata]
);

return (
<div>
<span>
Token stored?:{' '}
{tokenState.tokenMetadata['token-stored?'] ? 'Yes' : 'No'}
Token stored?: {tokenMetaDataState['token-stored?'] ? 'Yes' : 'No'}
</span>
<br />
<span>
Token last used: {tokenState.tokenMetadata['last-used'] || 'Never'}
</span>
<span>Token last used: {tokenMetaDataState['last-used'] || 'Never'}</span>
<br />
<textarea
disabled={true}
Expand Down

0 comments on commit 84aff72

Please sign in to comment.