diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json index c5e64dcf4..5f2f58634 100644 --- a/public/locales/en/translations.json +++ b/public/locales/en/translations.json @@ -53,6 +53,16 @@ "invalidToken": "Invalid token, please try again", "loginSessionExpired": "Your login session has expired, please try again" }, + "ttlSelect": { + "title": "Auth Token TTL", + "1day": "1 Day", + "2days": "2 Days", + "3days": "3 Days", + "4days": "4 Days", + "5days": "5 Days", + "6days": "6 Days", + "7days": "7 Days" + }, "apiKey": "API Key", "apiSecret": "API Secret", "accWithApiKey": "Add account with API key", diff --git a/src/components/Preferences/Preferences.js b/src/components/Preferences/Preferences.js index 40d33a562..a2b40bad1 100644 --- a/src/components/Preferences/Preferences.js +++ b/src/components/Preferences/Preferences.js @@ -15,6 +15,7 @@ import ThemeSwitcher from 'ui/ThemeSwitcher' import TimezonePicker from 'ui/TimezonePicker' import TableScrollPref from 'ui/TableScrollPref' import ShowMilliseconds from 'ui/ShowMilliseconds' +import TokenTTLSelector from 'ui/TokenTTLSelector' import DateFormatSelector from 'ui/DateFormatSelector' import SyncAfterUpdatePref from 'ui/SyncAfterUpdatePref' import TimeRangePreservePref from 'ui/TimeRangePreservePref' @@ -77,6 +78,12 @@ const Preferences = ({
{t('preferences.dateformat')}
+ {showFrameworkMode && ( +
+
{t('auth.ttlSelect.title')}
+ +
+ )}
{t('preferences.milliseconds')} diff --git a/src/state/auth/actions.js b/src/state/auth/actions.js index 5b4ab5116..ffc9616ba 100644 --- a/src/state/auth/actions.js +++ b/src/state/auth/actions.js @@ -224,6 +224,13 @@ export function disableAuthBtn(payload) { } } +export function setAuthTokenTTL(payload) { + return { + type: types.SET_TOKEN_TTL, + payload, + } +} + export default { checkAuth, addUser, @@ -251,4 +258,5 @@ export default { deleteAccount, syncAfterUpdate, disableAuthBtn, + setAuthTokenTTL, } diff --git a/src/state/auth/constants.js b/src/state/auth/constants.js index b5bfb5e4a..32625b3f3 100644 --- a/src/state/auth/constants.js +++ b/src/state/auth/constants.js @@ -25,7 +25,9 @@ export default { DELETE_ACCOUNT: 'BITFINEX/AUTH/ACCOUNT/DELETE', SET_SYNC_AFTER_UPDATE: 'BITFINEX/SYNC/SYNC_AFTER_UPDATE/SET', DISABLE_AUTH_BUTTON: 'BITFINEX/AUTH/BUTTON/DISABLE', + SET_TOKEN_TTL: 'BITFINEX/AUTH/TOKEN_TTL/SET', WS_SIGN_IN: 'ws_signIn', LOGIN_2FA_OTP: 'otp', + DEFAULT_TOKEN_TTL: 86400, // 24h } diff --git a/src/state/auth/reducer.js b/src/state/auth/reducer.js index ebc3dbfdd..bc34874bf 100644 --- a/src/state/auth/reducer.js +++ b/src/state/auth/reducer.js @@ -57,6 +57,7 @@ const initialState = { userShouldReLogin: '', shouldNotSyncOnStartupAfterUpdate: false, isAuthBtnDisabled: false, + authTokenTTLSec: types.DEFAULT_TOKEN_TTL, } export function authReducer(state = initialState, action) { @@ -154,6 +155,11 @@ export function authReducer(state = initialState, action) { ...state, isAuthBtnDisabled: payload, } + case types.SET_TOKEN_TTL: + return { + ...state, + authTokenTTLSec: payload, + } case types.HIDE_AUTH: return { ...state, diff --git a/src/state/auth/saga.js b/src/state/auth/saga.js index b98c4ea05..a04aad811 100644 --- a/src/state/auth/saga.js +++ b/src/state/auth/saga.js @@ -513,6 +513,24 @@ function* handleSyncAfterUpdate({ payload }) { } } +function* handleUpdateTokenTTL({ payload }) { + try { + const auth = yield select(selectAuth) + const params = { authTokenTTLSec: payload } + const { error } = yield makeFetchCall('updateUser', params, auth) + + if (error) { + yield put(updateErrorStatus({ + id: 'status.fail', + topic: 'auth.updateUser', + detail: error?.message ?? JSON.stringify(error), + })) + } + } catch (fail) { + yield put(updateAuthErrorStatus(fail)) + } +} + export default function* authSaga() { yield takeLatest(types.CHECK_AUTH, checkAuth) yield takeLatest(types.FETCH_USERS, fetchUsers) @@ -528,5 +546,6 @@ export default function* authSaga() { yield takeLatest(types.REMOVE_USER, removeUser) yield takeLatest(types.AUTH_EXPIRED, handleExpiredAuth) yield takeLatest(types.SET_SYNC_AFTER_UPDATE, handleSyncAfterUpdate) + yield takeLatest(types.SET_TOKEN_TTL, handleUpdateTokenTTL) yield fork(tokenRefreshSaga) } diff --git a/src/state/auth/selectors.js b/src/state/auth/selectors.js index 97a5f5369..9a638978c 100644 --- a/src/state/auth/selectors.js +++ b/src/state/auth/selectors.js @@ -3,6 +3,8 @@ import _first from 'lodash/first' import _filter from 'lodash/filter' import { isEqual } from '@bitfinex/lib-js-util-base' +import types from './constants' + const getAuth = state => state.auth export const getAuthStatus = state => getAuth(state).authStatus @@ -23,6 +25,7 @@ export const getIsSubAccsAvailable = state => _first( )?.isApiKeysAuth ?? true export const getLocalUsername = state => getAuth(state)?.localUsername ?? null export const getIsAuthBtnDisabled = state => getAuth(state)?.isAuthBtnDisabled ?? false +export const getAuthTokenTTL = state => getAuth(state)?.authTokenTTLSec ?? types.DEFAULT_TOKEN_TTL export const getAuthData = state => { const { @@ -110,4 +113,5 @@ export default { getLocalUsername, getShouldNotSyncOnStartupAfterUpdate, getIsAuthBtnDisabled, + getAuthTokenTTL, } diff --git a/src/ui/Select/Select.js b/src/ui/Select/Select.js index 8803a8ce1..ea506586a 100644 --- a/src/ui/Select/Select.js +++ b/src/ui/Select/Select.js @@ -59,7 +59,7 @@ class Select extends PureComponent { } itemRenderer = (item, { modifiers, handleClick }) => { - const { active, disabled } = modifiers + const { disabled } = modifiers const { value } = this.props let options = {} @@ -82,7 +82,7 @@ class Select extends PureComponent { return ( [ + { value: 86400, label: t('auth.ttlSelect.1day') }, + { value: 172800, label: t('auth.ttlSelect.2days') }, + { value: 259200, label: t('auth.ttlSelect.3days') }, + { value: 345600, label: t('auth.ttlSelect.4days') }, + { value: 432000, label: t('auth.ttlSelect.5days') }, + { value: 518400, label: t('auth.ttlSelect.6days') }, + { value: 604800, label: t('auth.ttlSelect.7days') }, +] + +const ExportTypeSelector = () => { + const { t } = useTranslation() + const dispatch = useDispatch() + const authTokenTTL = useSelector(getAuthTokenTTL) + const items = useMemo(() => getItems(t), [t]) + + const handleChange = useCallback((value) => { + dispatch(setAuthTokenTTL(value)) + }, [dispatch]) + + return ( +