Milin commited on
Commit
33eb1fa
·
1 Parent(s): 35d4f12

feat(webui): Display logged-in username

Browse files

- Add username display in the `SiteHeader` component.
- Update logout button text to include username.
- Add `username` field in auth state.
- Optimize token parsing logic to extract username information.
- pre-commit fix

env.example CHANGED
@@ -155,4 +155,4 @@ REDIS_URI=redis://localhost:6379
155
  # AUTH_ACCOUNTS='admin:admin123,user1:pass456' # username:password,username:password
156
  # TOKEN_SECRET=Your-Key-For-LightRAG-API-Server # JWT key
157
  # TOKEN_EXPIRE_HOURS=4 # expire duration
158
- # WHITELIST_PATHS= # white list
 
155
  # AUTH_ACCOUNTS='admin:admin123,user1:pass456' # username:password,username:password
156
  # TOKEN_SECRET=Your-Key-For-LightRAG-API-Server # JWT key
157
  # TOKEN_EXPIRE_HOURS=4 # expire duration
158
+ # WHITELIST_PATHS= # white list
lightrag/api/auth.py CHANGED
@@ -21,12 +21,12 @@ class AuthHandler:
21
  self.algorithm = "HS256"
22
  self.expire_hours = int(os.getenv("TOKEN_EXPIRE_HOURS", 4))
23
  self.guest_expire_hours = int(os.getenv("GUEST_TOKEN_EXPIRE_HOURS", 2))
24
-
25
  self.accounts = {}
26
  auth_accounts = os.getenv("AUTH_ACCOUNTS")
27
  if auth_accounts:
28
- for account in auth_accounts.split(','):
29
- username, password = account.split(':', 1)
30
  self.accounts[username] = password
31
 
32
  def create_token(
 
21
  self.algorithm = "HS256"
22
  self.expire_hours = int(os.getenv("TOKEN_EXPIRE_HOURS", 4))
23
  self.guest_expire_hours = int(os.getenv("GUEST_TOKEN_EXPIRE_HOURS", 2))
24
+
25
  self.accounts = {}
26
  auth_accounts = os.getenv("AUTH_ACCOUNTS")
27
  if auth_accounts:
28
+ for account in auth_accounts.split(","):
29
+ username, password = account.split(":", 1)
30
  self.accounts[username] = password
31
 
32
  def create_token(
lightrag/api/webui/assets/index-BcBS1RaQ.css ADDED
Binary file (53 kB). View file
 
lightrag/api/webui/assets/index-Cq65VeVX.css DELETED
Binary file (53.1 kB)
 
lightrag/api/webui/assets/{index-DlScqWrq.js → index-qXLILB5u.js} RENAMED
Binary files a/lightrag/api/webui/assets/index-DlScqWrq.js and b/lightrag/api/webui/assets/index-qXLILB5u.js differ
 
lightrag/api/webui/index.html CHANGED
Binary files a/lightrag/api/webui/index.html and b/lightrag/api/webui/index.html differ
 
lightrag_webui/src/features/SiteHeader.tsx CHANGED
@@ -55,7 +55,7 @@ function TabsNavigation() {
55
 
56
  export default function SiteHeader() {
57
  const { t } = useTranslation()
58
- const { isGuestMode, coreVersion, apiVersion } = useAuthStore()
59
 
60
  const versionDisplay = (coreVersion && apiVersion)
61
  ? `${coreVersion}/${apiVersion}`
@@ -96,7 +96,13 @@ export default function SiteHeader() {
96
  </Button>
97
  <AppSettings />
98
  {!isGuestMode && (
99
- <Button variant="ghost" size="icon" side="bottom" tooltip={t('header.logout')} onClick={handleLogout}>
 
 
 
 
 
 
100
  <LogOutIcon className="size-4" aria-hidden="true" />
101
  </Button>
102
  )}
 
55
 
56
  export default function SiteHeader() {
57
  const { t } = useTranslation()
58
+ const { isGuestMode, coreVersion, apiVersion, username } = useAuthStore()
59
 
60
  const versionDisplay = (coreVersion && apiVersion)
61
  ? `${coreVersion}/${apiVersion}`
 
96
  </Button>
97
  <AppSettings />
98
  {!isGuestMode && (
99
+ <Button
100
+ variant="ghost"
101
+ size="icon"
102
+ side="bottom"
103
+ tooltip={`${t('header.logout')} (${username})`}
104
+ onClick={handleLogout}
105
+ >
106
  <LogOutIcon className="size-4" aria-hidden="true" />
107
  </Button>
108
  )}
lightrag_webui/src/stores/state.ts CHANGED
@@ -21,6 +21,8 @@ interface AuthState {
21
  isGuestMode: boolean; // Add guest mode flag
22
  coreVersion: string | null;
23
  apiVersion: string | null;
 
 
24
  login: (token: string, isGuest?: boolean, coreVersion?: string | null, apiVersion?: string | null) => void;
25
  logout: () => void;
26
  setVersion: (coreVersion: string | null, apiVersion: string | null) => void;
@@ -76,36 +78,42 @@ const useBackendState = createSelectors(useBackendStateStoreBase)
76
 
77
  export { useBackendState }
78
 
79
- // Helper function to check if token is a guest token
80
- const isGuestToken = (token: string): boolean => {
81
  try {
82
  // JWT tokens are in the format: header.payload.signature
83
  const parts = token.split('.');
84
- if (parts.length !== 3) return false;
85
-
86
- // Decode the payload (second part)
87
  const payload = JSON.parse(atob(parts[1]));
88
-
89
- // Check if the token has a role field with value "guest"
90
- return payload.role === 'guest';
91
  } catch (e) {
92
- console.error('Error parsing token:', e);
93
- return false;
94
  }
95
  };
96
 
97
- // Initialize auth state from localStorage
98
- const initAuthState = (): { isAuthenticated: boolean; isGuestMode: boolean; coreVersion: string | null; apiVersion: string | null } => {
 
 
 
 
 
 
 
 
 
99
  const token = localStorage.getItem('LIGHTRAG-API-TOKEN');
100
  const coreVersion = localStorage.getItem('LIGHTRAG-CORE-VERSION');
101
  const apiVersion = localStorage.getItem('LIGHTRAG-API-VERSION');
 
102
 
103
  if (!token) {
104
  return {
105
  isAuthenticated: false,
106
  isGuestMode: false,
107
  coreVersion: coreVersion,
108
- apiVersion: apiVersion
 
109
  };
110
  }
111
 
@@ -113,7 +121,8 @@ const initAuthState = (): { isAuthenticated: boolean; isGuestMode: boolean; core
113
  isAuthenticated: true,
114
  isGuestMode: isGuestToken(token),
115
  coreVersion: coreVersion,
116
- apiVersion: apiVersion
 
117
  };
118
  };
119
 
@@ -126,6 +135,7 @@ export const useAuthStore = create<AuthState>(set => {
126
  isGuestMode: initialState.isGuestMode,
127
  coreVersion: initialState.coreVersion,
128
  apiVersion: initialState.apiVersion,
 
129
 
130
  login: (token, isGuest = false, coreVersion = null, apiVersion = null) => {
131
  localStorage.setItem('LIGHTRAG-API-TOKEN', token);
@@ -137,11 +147,13 @@ export const useAuthStore = create<AuthState>(set => {
137
  localStorage.setItem('LIGHTRAG-API-VERSION', apiVersion);
138
  }
139
 
 
140
  set({
141
  isAuthenticated: true,
142
  isGuestMode: isGuest,
 
143
  coreVersion: coreVersion,
144
- apiVersion: apiVersion
145
  });
146
  },
147
 
@@ -154,8 +166,9 @@ export const useAuthStore = create<AuthState>(set => {
154
  set({
155
  isAuthenticated: false,
156
  isGuestMode: false,
 
157
  coreVersion: coreVersion,
158
- apiVersion: apiVersion
159
  });
160
  },
161
 
 
21
  isGuestMode: boolean; // Add guest mode flag
22
  coreVersion: string | null;
23
  apiVersion: string | null;
24
+ username: string | null; // login username
25
+
26
  login: (token: string, isGuest?: boolean, coreVersion?: string | null, apiVersion?: string | null) => void;
27
  logout: () => void;
28
  setVersion: (coreVersion: string | null, apiVersion: string | null) => void;
 
78
 
79
  export { useBackendState }
80
 
81
+ const parseTokenPayload = (token: string): { sub?: string; role?: string } => {
 
82
  try {
83
  // JWT tokens are in the format: header.payload.signature
84
  const parts = token.split('.');
85
+ if (parts.length !== 3) return {};
 
 
86
  const payload = JSON.parse(atob(parts[1]));
87
+ return payload;
 
 
88
  } catch (e) {
89
+ console.error('Error parsing token payload:', e);
90
+ return {};
91
  }
92
  };
93
 
94
+ const getUsernameFromToken = (token: string): string | null => {
95
+ const payload = parseTokenPayload(token);
96
+ return payload.sub || null;
97
+ };
98
+
99
+ const isGuestToken = (token: string): boolean => {
100
+ const payload = parseTokenPayload(token);
101
+ return payload.role === 'guest';
102
+ };
103
+
104
+ const initAuthState = (): { isAuthenticated: boolean; isGuestMode: boolean; coreVersion: string | null; apiVersion: string | null; username: string | null } => {
105
  const token = localStorage.getItem('LIGHTRAG-API-TOKEN');
106
  const coreVersion = localStorage.getItem('LIGHTRAG-CORE-VERSION');
107
  const apiVersion = localStorage.getItem('LIGHTRAG-API-VERSION');
108
+ const username = token ? getUsernameFromToken(token) : null;
109
 
110
  if (!token) {
111
  return {
112
  isAuthenticated: false,
113
  isGuestMode: false,
114
  coreVersion: coreVersion,
115
+ apiVersion: apiVersion,
116
+ username: null,
117
  };
118
  }
119
 
 
121
  isAuthenticated: true,
122
  isGuestMode: isGuestToken(token),
123
  coreVersion: coreVersion,
124
+ apiVersion: apiVersion,
125
+ username: username,
126
  };
127
  };
128
 
 
135
  isGuestMode: initialState.isGuestMode,
136
  coreVersion: initialState.coreVersion,
137
  apiVersion: initialState.apiVersion,
138
+ username: initialState.username,
139
 
140
  login: (token, isGuest = false, coreVersion = null, apiVersion = null) => {
141
  localStorage.setItem('LIGHTRAG-API-TOKEN', token);
 
147
  localStorage.setItem('LIGHTRAG-API-VERSION', apiVersion);
148
  }
149
 
150
+ const username = getUsernameFromToken(token);
151
  set({
152
  isAuthenticated: true,
153
  isGuestMode: isGuest,
154
+ username: username,
155
  coreVersion: coreVersion,
156
+ apiVersion: apiVersion,
157
  });
158
  },
159
 
 
166
  set({
167
  isAuthenticated: false,
168
  isGuestMode: false,
169
+ username: null,
170
  coreVersion: coreVersion,
171
+ apiVersion: apiVersion,
172
  });
173
  },
174