show account expiration in user panel
Massimo Melina committed
Jan 31, 2024 at 15:34 UTC
04cf2147d506fa7e698e9fe96e70c9238e151ff2
5 files changed
+8
-10
frontend/src/UserPanel.ts
+2
-1
@@ -7,7 +7,7 @@ import { createVerifierAndSalt, SRPParameters, SRPRoutines } from 'tssrp6a'
7
import { apiCall } from '@hfs/shared/api'
8
import { logout } from './login'
9
import { Btn, CustomCode } from './components'
10
-import { hIcon, HTTP_NOT_ACCEPTABLE, working } from './misc'
10
+import { formatTimestamp, hIcon, working } from './misc'
11
import { t } from './i18n'
12
13
export default function showUserPanel() {
@@ -19,6 +19,7 @@ export default function showUserPanel() {
19
const snap = useSnapState()
20
return h('div', { id: 'user-panel' },
21
h('div', {}, t`Username`, ': ', snap.username),
22
+ snap.accountExp && h('div', {}, t`Account expiration`, ': ', formatTimestamp(snap.accountExp)),
23
h(CustomCode, { name: 'userPanelAfterInfo' }),
24
snap.canChangePassword && h(Btn, {
25
icon: 'password',
frontend/src/state.ts
+1
@@ -10,6 +10,7 @@ export const state = proxy<typeof FRONTEND_OPTIONS & {
10
stoppedSearch?: boolean,
11
iconsReady: boolean,
12
username: string,
13
+ accountExp?: string,
14
list: DirList,
15
filteredList?: DirList,
16
clip: DirList
shared/index.ts
+1
-1
@@ -79,7 +79,7 @@ export function makeSessionRefresher(state: any) {
79
return function sessionRefresher(response: any) {
80
if (!response) return
81
const { exp } = response
82
- Object.assign(state, _.pick(response, ['username', 'adminUrl', 'canChangePassword']))
82
+ Object.assign(state, _.pick(response, ['username', 'adminUrl', 'canChangePassword', 'accountExp']))
83
if (!response.username || !exp) return
84
const delta = new Date(exp).getTime() - Date.now()
85
const t = _.clamp(delta - 30_000, 4_000, 600_000)
src/api.auth.ts
+2
-6
@@ -12,11 +12,6 @@ import { defineConfig } from './config'
12
const ongoingLogins:Record<string,SRPServerSessionStep1> = {} // store data that doesn't fit session object
13
const keepSessionAlive = defineConfig('keep_session_alive', true)
14
15
-function makeExp() {
16
- return !keepSessionAlive.get() ? undefined
17
- : { exp: new Date(Date.now() + sessionDuration.compiled()) }
18
-}
19
-
15
export const loginSrp1: ApiHandler = async ({ username }, ctx) => {
16
if (!username)
17
return new ApiError(HTTP_BAD_REQUEST)
@@ -83,7 +78,8 @@ export const refresh_session: ApiHandler = async ({}, ctx) => {
78
username: getCurrentUsername(ctx),
79
adminUrl: ctxAdminAccess(ctx) ? ctx.state.revProxyPath + ADMIN_URI : undefined,
80
canChangePassword: canChangePassword(ctx.state.account),
86
- ...makeExp(),
81
+ exp: keepSessionAlive.get() ? new Date(Date.now() + sessionDuration.compiled()) : undefined,
82
+ accountExp: ctx.state.account?.expire,
83
}
84
}
85
src/cross.ts
+2
-2
@@ -339,8 +339,8 @@ export function repeat(everyMs: number, cb: Callback): Callback {
339
return () => stop = true
340
}
341
342
-export function formatTimestamp(x: string) {
343
- return x ? new Date(x).toLocaleString() : '-'
342
+export function formatTimestamp(x: string | Date) {
343
+ return !x ? '-' : (x instanceof Date ? x : new Date(x)).toLocaleString()
344
}
345
346
export function isPrimitive(x: unknown): x is boolean | string | number | undefined | null {