@@ -144,6 +144,86 @@ def _normalize_limit(v: Any) -> int:
144144 return - 1
145145
146146
147+ def _pool_to_token_type (pool_name : str ) -> str :
148+ return "ssoSuper" if str (pool_name or "" ).strip () == "ssoSuper" else "sso"
149+
150+
151+ def _parse_quota_value (v : Any ) -> tuple [int , bool ]:
152+ if v is None or v == "" :
153+ return - 1 , False
154+ try :
155+ n = int (v )
156+ except Exception :
157+ return - 1 , False
158+ if n < 0 :
159+ return - 1 , False
160+ return n , True
161+
162+
163+ def _safe_int (v : Any , default : int = 0 ) -> int :
164+ try :
165+ return int (v )
166+ except Exception :
167+ return default
168+
169+
170+ def _normalize_token_status (raw_status : Any ) -> str :
171+ s = str (raw_status or "active" ).strip ().lower ()
172+ if s == "expired" :
173+ return "invalid"
174+ if s in ("active" , "cooling" , "invalid" , "disabled" ):
175+ return s
176+ return "active"
177+
178+
179+ def _normalize_admin_token_item (pool_name : str , item : Any ) -> dict | None :
180+ token_type = _pool_to_token_type (pool_name )
181+
182+ if isinstance (item , str ):
183+ token = item .strip ()
184+ if not token :
185+ return None
186+ if token .startswith ("sso=" ):
187+ token = token [4 :]
188+ return {
189+ "token" : token ,
190+ "status" : "active" ,
191+ "quota" : 0 ,
192+ "quota_known" : False ,
193+ "heavy_quota" : - 1 ,
194+ "heavy_quota_known" : False ,
195+ "token_type" : token_type ,
196+ "note" : "" ,
197+ "fail_count" : 0 ,
198+ "use_count" : 0 ,
199+ }
200+
201+ if not isinstance (item , dict ):
202+ return None
203+
204+ token = str (item .get ("token" ) or "" ).strip ()
205+ if not token :
206+ return None
207+ if token .startswith ("sso=" ):
208+ token = token [4 :]
209+
210+ quota , quota_known = _parse_quota_value (item .get ("quota" ))
211+ heavy_quota , heavy_quota_known = _parse_quota_value (item .get ("heavy_quota" ))
212+
213+ return {
214+ "token" : token ,
215+ "status" : _normalize_token_status (item .get ("status" )),
216+ "quota" : quota if quota_known else 0 ,
217+ "quota_known" : quota_known ,
218+ "heavy_quota" : heavy_quota ,
219+ "heavy_quota_known" : heavy_quota_known ,
220+ "token_type" : token_type ,
221+ "note" : str (item .get ("note" ) or "" ),
222+ "fail_count" : _safe_int (item .get ("fail_count" ) or 0 , 0 ),
223+ "use_count" : _safe_int (item .get ("use_count" ) or 0 , 0 ),
224+ }
225+
226+
147227@router .get ("/api/v1/admin/keys" , dependencies = [Depends (verify_api_key )])
148228async def list_api_keys ():
149229 """List API keys + daily usage/remaining (for admin UI)."""
@@ -227,6 +307,10 @@ async def update_api_key(data: dict):
227307 if not key :
228308 raise HTTPException (status_code = 400 , detail = "Missing key" )
229309
310+ existing = api_key_manager .get_key_row (key )
311+ if not existing :
312+ raise HTTPException (status_code = 404 , detail = "Key not found" )
313+
230314 if "name" in data and data .get ("name" ) is not None :
231315 name = str (data .get ("name" ) or "" ).strip ()
232316 if name :
@@ -291,7 +375,17 @@ async def get_tokens_api():
291375 """获取所有 Token"""
292376 storage = get_storage ()
293377 tokens = await storage .load_tokens ()
294- return tokens or {}
378+ data = tokens if isinstance (tokens , dict ) else {}
379+ out : dict [str , list [dict ]] = {}
380+ for pool_name , raw_items in data .items ():
381+ arr = raw_items if isinstance (raw_items , list ) else []
382+ normalized : list [dict ] = []
383+ for item in arr :
384+ obj = _normalize_admin_token_item (pool_name , item )
385+ if obj :
386+ normalized .append (obj )
387+ out [str (pool_name )] = normalized
388+ return out
295389
296390@router .post ("/api/v1/admin/tokens" , dependencies = [Depends (verify_api_key )])
297391async def update_tokens_api (data : dict ):
0 commit comments