Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved API key handling #3094

Merged
merged 29 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1ac583f
Allow users to reset their API key
tillprochaska May 25, 2023
a2a94ae
Only return API key once after it has been generated
tillprochaska Apr 11, 2024
399e85f
Add new UI to reset and display API key
tillprochaska Apr 15, 2024
5d96021
Refactor existing settings screen
tillprochaska Apr 15, 2024
b13425c
Ensure that toasts are always visible, even when scrolling
tillprochaska Apr 16, 2024
8065afa
Do not display password setting when password auth is disabled
tillprochaska Apr 16, 2024
688bb96
Use session tokens for authentication in API tests
tillprochaska Apr 30, 2024
b3eac7f
Do not generate API tokens for new roles
tillprochaska May 2, 2024
d7420be
Handle users without an API key properly in the settings UI
tillprochaska May 1, 2024
0622c84
Update wording to clarify that API keys are secrets
tillprochaska May 1, 2024
6f03791
Rename "reset_api_key" to "generate_api_key"
tillprochaska May 1, 2024
be5f029
Send email notification when API key is (re-)generated
tillprochaska May 2, 2024
f30757f
Extract logic to regenerate API keys into separate module
tillprochaska May 2, 2024
e1ed9b6
Let API keys expire after 90 days
tillprochaska May 6, 2024
a506ebe
Extract `generate_api_key` method from role model
tillprochaska May 6, 2024
6cc615b
Send notification when API keys are about to expire/have expired
tillprochaska May 6, 2024
6d2d89b
Display API key expiration date in UI
tillprochaska May 6, 2024
87ce636
Add CLI command to reset API key expiration of non-expiring API keys
tillprochaska May 6, 2024
5e52e2d
Replace use of deprecated `utcnow` method
tillprochaska May 8, 2024
c091223
Remove unnecessary keys from API JSON response
tillprochaska May 8, 2024
9a42b22
Add note to remind us to remove/update logic handling legacy API keys
tillprochaska May 8, 2024
b9ad42e
Send API key expiration notifications on a daily basis
tillprochaska May 8, 2024
c0ad86d
Fix Alembic migration order
tillprochaska Oct 22, 2024
1e74da4
Reauthenticate user in test to update session cache
tillprochaska Oct 23, 2024
f95572a
Update wording of API key notification emails based on feedback
tillprochaska Oct 23, 2024
de6eeff
Use strict equality check
tillprochaska Oct 23, 2024
9b9efa9
Clarify that API keys expire when generating a new key
tillprochaska Oct 23, 2024
50b689e
Display different UI messages in case the API key has expired
tillprochaska Nov 4, 2024
987b907
Fix Alembic migration order
tillprochaska Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add new UI to reset and display API key
How API keys are reset and displayed has changed since the initial version of API keys: Users will be able to view an API key exactly once after it has been created/reset. This requires a slightly different user interface. We’re also planning a few more changes to API keys in the future, and these UI changes prepare for that.
  • Loading branch information
tillprochaska committed Nov 4, 2024
commit 399e85f8d513070964c6e6a15b26063adb2bfead
100 changes: 100 additions & 0 deletions ui/src/components/Settings/ApiKeySettings.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Button, Intent, Dialog, DialogBody, Card } from '@blueprintjs/core';
import { ClipboardInput } from 'components/common';
import { selectCurrentRole } from 'selectors';
import { resetApiKey } from 'actions';
import { FormattedMessage } from 'react-intl';

export default function ApiKeySettings() {
const dispatch = useDispatch();
const role = useSelector(selectCurrentRole);

const [isLoading, setIsLoading] = useState(false);
const [showConfirmation, setShowConfirmation] = useState(false);
const [apiKey, setApiKey] = useState(null);

const onReset = async () => {
setIsLoading(true);
const { data } = await dispatch(resetApiKey(role));
setApiKey(data.api_key);
setIsLoading(false);
};

const onClose = async () => {
setShowConfirmation(false);
setApiKey(null);
};

const resetMessage = (
<FormattedMessage
id="settings.api_key.reset"
defaultMessage="Reset API key"
/>
);

return (
<>
<Card elevation={1}>
<h4 className="bp4-heading">
<FormattedMessage
id="settings.api_key.title"
defaultMessage="API key"
/>
</h4>

<p>
<FormattedMessage
id="settings.api_key.text"
defaultMessage="Your API key is required to access the Aleph API. When you reset your API key, your old key will stop working."
/>
</p>

<Button onClick={() => setShowConfirmation(true)}>
{resetMessage}
</Button>
</Card>

<Dialog
title={resetMessage}
isOpen={showConfirmation}
onClose={onClose}
canOutsideClickClose={apiKey ? false : true}
>
{apiKey === null ? (
<DialogBody>
<p>
<FormattedMessage
id="settings.api_key.confirm"
defaultMessage="You are about to reset your API key. When you reset your API key, your old key will stop working. If you are currently using your API key in applications or scripts, you will need to update them to keep them working."
/>
</p>
<Button
intent={Intent.DANGER}
onClick={onReset}
fill
loading={isLoading}
>
{resetMessage}
</Button>
</DialogBody>
) : (
<DialogBody>
<p>
<FormattedMessage
id="settings.api_key.success"
defaultMessage="Your API key has been reset. Be sure to copy your new key below. You won’t be able to view it again later."
/>
</p>
<p>
<label>
<span className="visually-hidden">API key</span>
<ClipboardInput disabled icon="key" value={apiKey} large />
</label>
</p>
</DialogBody>
)}
</Dialog>
</>
);
}
2 changes: 1 addition & 1 deletion ui/src/reducers/roles.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default createReducer(
[updateRole.COMPLETE]: (state, { id, data }) =>
objectLoadComplete(state, id, data),
[resetApiKey.COMPLETE]: (state, { id, data }) =>
objectLoadComplete(state, id, data),
objectLoadComplete(state, id, { ...data, api_key: null }),
},
initialState
);