plugins: new frontend events: loginOk, loginFailed #1126
Massimo Melina committed
Nov 26, 2025 at 10:59 UTC
b2e7d19c7c85a6b6a19282cdce986ad21e1f952e
3 files changed
+12
-4
dev-plugins.md
+8
-2
@@ -617,8 +617,12 @@ This is a list of available frontend-events, with respective object parameter an
617
- `newListEntries`
618
- new entries for the list have being fetched from the server
619
- parameter `{ entries: DirEntry[] }`
620
+- `loginOk`
621
+ - parameter `{ username }`
622
+- `loginFailed`
623
+ - parameter `{ username, error }`
624
- All of the following have no parameters and you are supposed to output `Html` that will be displayed in the described place:
621
-- `appendMenuBar` inside menu-bar, at the end
625
+ - `appendMenuBar` inside menu-bar, at the end
626
- `afterMenuBar` between menu-bar and breadcrumbs
627
- `afterBreadcrumbs` between breadcrumbs and folder-stats
628
- `afterFolderStats` between folder-stats and filter-bar
@@ -1079,4 +1083,6 @@ If you want to override a text regardless of the language, use the special langu
1083
- ctx.disconnect(logMessage)
1084
- 12.94 (v0.57.24)
1085
- HFS.onEvent now supports :after
1082
- - HFS.userBelongsTo now supports array of usernames
\ No newline at end of file
1086
+ - HFS.userBelongsTo now supports array of usernames
1087
+- 12.95 (v0.57.27)
1088
+ - frontend events: loginOk, loginFailed
\ No newline at end of file
frontend/src/login.ts
+3
-1
@@ -4,7 +4,7 @@ import { apiCall } from '@hfs/shared/api'
4
import { state, useSnapState } from './state'
5
import { alertDialog, newDialog, toast } from './dialog'
6
import {
7
- getHFS, hIcon, makeSessionRefresher, srpClientSequence, working, fallbackToBasicAuth,
7
+ getHFS, hIcon, makeSessionRefresher, srpClientSequence, working, fallbackToBasicAuth, hfsEvent,
8
HTTP_CONFLICT, HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED, ALLOW_SESSION_IP_CHANGE,
9
} from './misc'
10
import { createElement as h, Fragment, useEffect, useRef } from 'react'
@@ -22,10 +22,12 @@ async function login(username:string, password:string, extra?: object) {
22
return apiCall('login', { username, password, ...extra })
23
throw err
24
}).then(res => {
25
+ hfsEvent('loginOk', { username })
26
refreshSession(res)
27
state.loginRequired = false
28
return res
29
}, err => {
30
+ hfsEvent('loginFailed', { username, error: err }) // the name inconsistency with the backend event 'failedLogin' can make it easier to distinguish
31
throw Error(err.data === 'trust' ? t('login_untrusted', "Login aborted: server identity cannot be trusted")
32
: err.code === HTTP_UNAUTHORIZED && !err.data ? t('login_bad_credentials', "Invalid credentials") // err.data is empty on standard errors, but a plugin may want to show differently
33
: err.code === HTTP_CONFLICT ? t('login_bad_cookies', "Cookies not working - login failed")
src/const.ts
+1
-1
@@ -9,7 +9,7 @@ import { formatTimestamp } from './cross'
9
import { argv } from './argv'
10
export * from './cross-const'
11
12
-export const API_VERSION = 12.94
12
+export const API_VERSION = 12.95
13
export const COMPATIBLE_API_VERSION = 1 // while changes in the api are not breaking, this number stays the same, otherwise it is made equal to API_VERSION
14
15
// you can add arguments with this file, currently used for the update process on mac/linux