11import { ApiResponse } from '../types' ;
2+ import { showToast } from '../components/Toast'
23
34const TOKEN_KEY = 'webui_token' ;
45let passwordPromptHandler : ( ( tip : string ) => Promise < string > ) | null = null ;
@@ -23,88 +24,88 @@ export async function apiFetch<T = any>(
2324 const headers : HeadersInit = {
2425 ...options . headers ,
2526 } ;
26-
27+
2728 // 使用后端期望的 x-webui-token 请求头
2829 if ( authToken ) {
2930 headers [ 'x-webui-token' ] = authToken ;
3031 }
31-
32+
3233 return fetch ( url , {
3334 ...options ,
3435 headers,
3536 } ) ;
3637 } ;
37-
38+
3839 try {
3940 let response = await makeRequest ( getToken ( ) ) ;
40-
41+
4142 // 401: 未设置密码,需要调用 set-token 设置
4243 if ( response . status === 401 && passwordPromptHandler ) {
4344 console . log ( '401 - Password not set, prompting to set password...' ) ;
44-
45+
4546 const newPassword = await passwordPromptHandler ( '请设置密码' ) ;
46-
47+
4748 if ( ! newPassword || ! newPassword . trim ( ) ) {
4849 throw new Error ( '密码不能为空' ) ;
4950 }
50-
51+
5152 // 调用设置密码接口
5253 const setTokenResponse = await fetch ( '/api/set-token' , {
5354 method : 'POST' ,
5455 headers : { 'Content-Type' : 'application/json' } ,
5556 body : JSON . stringify ( { token : newPassword . trim ( ) } ) ,
5657 } ) ;
57-
58+
5859 if ( ! setTokenResponse . ok ) {
5960 throw new Error ( '设置密码失败' ) ;
6061 }
61-
62+
6263 setTokenStorage ( newPassword . trim ( ) ) ;
63-
64+
6465 // 重新请求原接口
6566 response = await makeRequest ( newPassword . trim ( ) ) ;
6667 }
67-
68+
6869 // 403: 密码错误或账户锁定,需要重新输入
6970 if ( response . status === 403 && passwordPromptHandler ) {
7071 console . log ( '403 - Token verification failed, prompting for password...' ) ;
71-
72+
7273 // 解析错误信息
7374 let errorData : any = null ;
7475 try {
7576 errorData = await response . clone ( ) . json ( ) ;
7677 } catch ( e ) {
7778 // 忽略
7879 }
79-
80+
8081 // 检查是否被锁定
8182 if ( errorData ?. locked ) {
82- throw new Error ( errorData . message || '账户已被锁定' ) ;
83+ showToast ( errorData . message || '账户已被锁定' , 'error ') ;
8384 }
84-
85+
8586 // 循环提示密码
8687 let retryCount = 0 ;
8788 const maxRetries = 5 ;
88-
89+
8990 while ( response . status === 403 && retryCount < maxRetries ) {
9091 try {
9192 const errorMessage = retryCount > 0 ? '密码错误,请重新输入' : '请输入密码' ;
9293 const newPassword = await passwordPromptHandler ( errorMessage ) ;
93-
94+
9495 if ( ! newPassword || ! newPassword . trim ( ) ) {
9596 throw new Error ( '密码不能为空' ) ;
9697 }
97-
98+
9899 setTokenStorage ( newPassword . trim ( ) ) ;
99-
100+
100101 // 重新请求
101102 response = await makeRequest ( newPassword . trim ( ) ) ;
102-
103+
103104 if ( response . status === 200 ) {
104105 console . log ( 'Authentication successful!' ) ;
105106 break ;
106107 }
107-
108+
108109 // 解析新的错误信息
109110 try {
110111 errorData = await response . clone ( ) . json ( ) ;
@@ -114,24 +115,24 @@ export async function apiFetch<T = any>(
114115 } catch ( e ) {
115116 // 忽略
116117 }
117-
118+
118119 retryCount ++ ;
119120 } catch ( error ) {
120121 console . error ( 'Password prompt error:' , error ) ;
121122 throw error ;
122123 }
123124 }
124-
125+
125126 if ( response . status === 403 ) {
126127 throw new Error ( errorData ?. message || '认证失败' ) ;
127128 }
128129 }
129-
130+
130131 if ( ! response . ok ) {
131132 const errorText = await response . text ( ) ;
132133 throw new Error ( `HTTP error! status: ${ response . status } , message: ${ errorText } ` ) ;
133134 }
134-
135+
135136 return await response . json ( ) ;
136137 } catch ( error ) {
137138 console . error ( 'API fetch error:' , error ) ;
0 commit comments