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 (