Skip to content

Commit

Permalink
Api key Expiration Label fix (#2495)
Browse files Browse the repository at this point in the history
* Fix api key expiration toast when the key is expired

* refactored api key expiration label in settings page
  • Loading branch information
CDimonaco authored Apr 8, 2024
1 parent d4e759f commit 1deea20
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 25 deletions.
37 changes: 24 additions & 13 deletions assets/js/pages/SettingsPage/SettingsPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Transition } from '@headlessui/react';
import { values, isUndefined } from 'lodash';
import { format, parseISO } from 'date-fns';
import { format, isBefore, parseISO } from 'date-fns';
import { EOS_INFO_OUTLINED } from 'eos-icons-react';
import { logError } from '@lib/log';
import { get, patch } from '@lib/network';
Expand Down Expand Up @@ -35,6 +35,28 @@ import {
import { dismissNotification } from '@state/notifications';
import { API_KEY_EXPIRATION_NOTIFICATION_ID } from '@state/sagas/settings';

function ApiKeyExpireInfo({ apiKeyExpiration }) {
const expirationLabel = () => {
if (!apiKeyExpiration) {
return 'Key will never expire';
}

const expireDate = parseISO(apiKeyExpiration);
if (apiKeyExpiration && isBefore(new Date(), expireDate)) {
return `Key will expire ${format(expireDate, 'd LLL yyyy')}`;
}

return 'Key expired';
};

return (
<div className="flex space-x-2 my-4">
<EOS_INFO_OUTLINED size="20" className="mt-2" />
<div className="mt-1 text-gray-600 text-sm">{expirationLabel()}</div>
</div>
);
}

function SettingsPage() {
const dispatch = useDispatch();

Expand Down Expand Up @@ -140,18 +162,7 @@ function SettingsPage() {
)}

{apiKey && (
<div className="flex space-x-2 my-4">
<EOS_INFO_OUTLINED size="20" className="mt-2" />

<div className="mt-1 text-gray-600 text-sm">
{apiKeyExpiration
? `Key will expire ${format(
parseISO(apiKeyExpiration),
'd LLL yyyy'
)}`
: 'Key will never expire'}
</div>
</div>
<ApiKeyExpireInfo apiKeyExpiration={apiKeyExpiration} />
)}
</Transition>
</div>
Expand Down
28 changes: 17 additions & 11 deletions assets/js/state/sagas/settings.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { get } from '@lib/network';
import { differenceInDays, parseISO } from 'date-fns';
import { differenceInDays, parseISO, isAfter } from 'date-fns';
import { call, put } from 'redux-saga/effects';
import HealthIcon from '@common/HealthIcon';
import { notify, dismissableNotify } from '@state/notifications';
Expand All @@ -21,7 +21,7 @@ export function* checkApiKeyExpiration() {
return;
}

if (expirationDays < 0) {
if (isAfter(new Date(), expireTS)) {
yield put(
notify({
text: 'API Key has expired. Go to Settings to issue a new key',
Expand All @@ -30,14 +30,20 @@ export function* checkApiKeyExpiration() {
id: API_KEY_EXPIRATION_NOTIFICATION_ID,
})
);
} else {
yield put(
dismissableNotify({
text: `API Key expires in ${expirationDays} days`,
icon: <HealthIcon health="warning" />,
duration: Infinity,
id: API_KEY_EXPIRATION_NOTIFICATION_ID,
})
);
return;
}

const notificationText =
expirationDays === 0
? 'API Key expires today'
: `API Key expires in ${expirationDays} days`;

yield put(
dismissableNotify({
text: notificationText,
icon: <HealthIcon health="warning" />,
duration: Infinity,
id: API_KEY_EXPIRATION_NOTIFICATION_ID,
})
);
}
19 changes: 18 additions & 1 deletion assets/js/state/sagas/settings.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { networkClient } from '@lib/network';
import MockAdapter from 'axios-mock-adapter';

import { apiKeySettingsFactory } from '@lib/test-utils/factories/settings';
import { addDays, formatISO, subDays } from 'date-fns';
import { addDays, addHours, formatISO, subDays } from 'date-fns';
import HealthIcon from '@common/HealthIcon';
import { notify, dismissableNotify } from '@state/notifications';
import { checkApiKeyExpiration } from './settings';
Expand Down Expand Up @@ -75,5 +75,22 @@ describe('Settings sagas', () => {
const dispatched = await recordSaga(checkApiKeyExpiration, {});
expect(dispatched).toEqual([]);
});

it('should dispatch a dismissable notification if the api key is going to expire the same day', async () => {
axiosMock.onGet('/api/v1/settings/api_key').reply(
200,
apiKeySettingsFactory.build({
expire_at: formatISO(addHours(new Date(), 2)),
})
);
const dispatched = await recordSaga(checkApiKeyExpiration, {});
const expectedAction = dismissableNotify({
text: `API Key expires today`,
icon: <HealthIcon health="warning" />,
duration: Infinity,
id: 'api-key-expiration-toast',
});
expect(dispatched).toEqual([expectedAction]);
});
});
});

0 comments on commit 1deea20

Please sign in to comment.