diff --git a/src/frontend/src/components/OAuth2ProxyApiTokenComponent.jsx b/src/frontend/src/components/OAuth2ProxyApiTokenComponent.jsx
index d3b71c6..6b22569 100644
--- a/src/frontend/src/components/OAuth2ProxyApiTokenComponent.jsx
+++ b/src/frontend/src/components/OAuth2ProxyApiTokenComponent.jsx
@@ -12,36 +12,71 @@ import {
} from '@sonatype/nexus-ui-plugin';
export default function OAuth2ProxyApiTokenComponent() {
- const [token, setToken] = React.useState('');
- const [error, setError] = React.useState(false);
-
- React.useEffect(() => {
- (async () => {
- try {
- const reponse = await Axios.post("/service/rest/oauth2-proxy/user/reset-token");
- setToken(reponse.data);
- } catch (e) {
- setError(true);
- console.error('Failed to reset token:', e);
- }
- })();
- }, []);
-
- if (error) {
- return
Error fetching user data.
;
- }
-
return
-
- A new API token has been created. It is only displayed once. Store it in a safe place!
- ⚠️ The next time you visit this page, you will automatically reset the token again.
- 💡 Make sure no one was watching when displaying this token. If in doubt, just reset it once more.
- Your API token: {token}
-
+
}
+
+function TokenSection() {
+ const [token, setToken] = React.useState('****************************************');
+ const [resetFailed, setResetFailed] = React.useState(false);
+ const [resetInProgress, setResetInProgress] = React.useState(false);
+ const [tokenFreshlyReset, setTokenFreshlyReset] = React.useState(false);
+
+ const resetToken = React.useCallback(async () => {
+ if(resetInProgress) {
+ console.log("Still resetting the token, not sending another request now");
+ } else {
+ setResetInProgress(true);
+ Axios.post("/service/rest/oauth2-proxy/user/reset-token")
+ .then(response => {
+ setToken(response.data);
+ setTokenFreshlyReset(true);
+ setResetInProgress(false);
+ })
+ .catch(error => {
+ setResetFailed(true);
+ console.error('Failed to reset token:' + JSON.stringify(error.toJSON()));
+ setResetInProgress(false);
+ });
+ }
+ }, [resetInProgress])
+
+ if(resetFailed) {
+ return
+ ⛔ Failed to generate a new access token
+
+ }
+
+ if(tokenFreshlyReset) {
+ return
+ ✔ A new API token has been created. It is only displayed once. Store it in a safe place!
+ ⚠️ The old API token has been invalidated
+ 💡 Make sure no one was watching when displaying this token. If in doubt, just reset it once more.
+ resetToken()} token={token}/>
+
+ }
+
+ return
+ ⚠️ Your current API token is hidden. Click the button to generate a new token
+ ⚠️ When a new token is generated, the old one is invalidated immediately
+ resetToken()} token={token}/>
+
+}
+
+function TokenFooter({resetInProgress, resetPressed, token}) {
+ const buttonStyle = {
+ marginRight: '1em',
+ minWidth: '10em'
+ }
+ let buttonText = resetInProgress ? "Generating..." : "Regenerate Token"
+ return
+
+ Your API token: {token}
+
+}
\ No newline at end of file
diff --git a/src/frontend/src/components/OAuth2ProxyApiTokenComponent.test.jsx b/src/frontend/src/components/OAuth2ProxyApiTokenComponent.test.jsx
index db1b318..b41c2e6 100644
--- a/src/frontend/src/components/OAuth2ProxyApiTokenComponent.test.jsx
+++ b/src/frontend/src/components/OAuth2ProxyApiTokenComponent.test.jsx
@@ -3,7 +3,7 @@ import React from 'react';
import OAuth2ProxyApiTokenComponent from './OAuth2ProxyApiTokenComponent';
import '@testing-library/jest-dom'
-import { act, render } from '@testing-library/react';
+import { act, render, fireEvent } from '@testing-library/react';
jest.mock('axios');
@@ -24,9 +24,23 @@ describe('OAuth2ProxyApiTokenComponent', () => {
Axios.post.mockImplementationOnce(() => Promise.resolve({ data: 'foobar' }));
});
- it('calls post request once when rendered', async () => {
+ it('renders page without immediately re-generating the token', async () => {
+ const { findByText } = render();
+
+ const token = await findByText(/Your current API token is hidden/i);
+ expect(token).toBeInTheDocument();
+
+ const button = await findByText(/Regenerate Token/i);
+ expect(button).toBeInTheDocument();
+
+ expect(Axios.post).toHaveBeenCalledTimes(0);
+ });
+
+ it('calls post request once when regenerate button is clicked', async () => {
await act(async () => {
- render();
+ const { findByText } = render();
+ const button = await findByText(/Regenerate Token/i);
+ fireEvent.click(button);
});
expect(Axios.post).toHaveBeenCalledTimes(1);
@@ -34,9 +48,13 @@ describe('OAuth2ProxyApiTokenComponent', () => {
});
it('renders response content as token', async () => {
- const { findByText } = render();
-
- const token = await findByText(/foobar/i);
- expect(token).toBeInTheDocument();
+ await act(async () => {
+ const { findByText } = render();
+ const button = await findByText(/Regenerate Token/i);
+ fireEvent.click(button);
+
+ const token = await findByText(/foobar/i);
+ expect(token).toBeInTheDocument();
+ });
});
});
\ No newline at end of file