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 {