Skip to content

Commit 596ea9e

Browse files
committed
fix: login dialog
1 parent 6b4eed7 commit 596ea9e

File tree

1 file changed

+91
-94
lines changed

1 file changed

+91
-94
lines changed

xinference/ui/web/ui/src/scenes/launch_model/components/addModelDialog.js

Lines changed: 91 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
DialogTitle,
77
TextField,
88
} from '@mui/material'
9-
import React, { useState } from 'react'
9+
import React, { useEffect, useRef, useState } from 'react'
1010
import { useTranslation } from 'react-i18next'
1111

1212
const API_BASE_URL = 'https://model.xinference.io'
@@ -15,11 +15,10 @@ const AddModelDialog = ({ open, onClose }) => {
1515
const { t } = useTranslation()
1616
const [url, setUrl] = useState('')
1717
const [loginOpen, setLoginOpen] = useState(false)
18-
const [usernameOrEmail, setUsernameOrEmail] = useState('')
19-
const [password, setPassword] = useState('')
2018
const [pendingModelId, setPendingModelId] = useState(null)
2119
const [loading, setLoading] = useState(false)
2220
const [errorMsg, setErrorMsg] = useState('')
21+
const loginIframeRef = useRef(null)
2322

2423
const handleClose = (type) => {
2524
setErrorMsg('')
@@ -46,18 +45,62 @@ const AddModelDialog = ({ open, onClose }) => {
4645
return null
4746
}
4847

49-
const performDownload = async (modelId, token, fromLogin = false) => {
48+
// 修改:download 默认从 sessionStorage 读取 token(若传参提供则优先)
49+
// performDownload:收到 token 后直连接口,获取 JSON
50+
const performDownload = async (modelId, tokenFromParam, fromLogin = false) => {
5051
const endpoint = `${API_BASE_URL}/api/models/download?model_id=${encodeURIComponent(
5152
modelId
5253
)}`
53-
const headers = token ? { Authorization: `Bearer ${token}` } : {}
54+
const effectiveToken =
55+
tokenFromParam ||
56+
sessionStorage.getItem('model_hub_token') ||
57+
localStorage.getItem('io_login_success')
58+
const headers = effectiveToken ? { Authorization: `Bearer ${effectiveToken}` } : {}
5459
setLoading(true)
5560
setErrorMsg('')
5661
try {
5762
const res = await fetch(endpoint, {
5863
method: 'GET',
5964
headers,
6065
})
66+
67+
if (res.status === 401) {
68+
const refreshToken = sessionStorage.getItem('model_hub_refresh_token')
69+
if (!refreshToken) {
70+
sessionStorage.removeItem('model_hub_token')
71+
setPendingModelId(modelId)
72+
setLoginOpen(true)
73+
return
74+
}
75+
try {
76+
const refreshRes = await fetch(`${API_BASE_URL}/api/users/refresh`, {
77+
method: 'POST',
78+
headers: { 'Content-Type': 'application/json' },
79+
body: JSON.stringify({ token: refreshToken }),
80+
})
81+
if (!refreshRes.ok) {
82+
throw new Error(`refresh failed: ${refreshRes.status}`)
83+
}
84+
const refreshData = await refreshRes.json().catch(() => ({}))
85+
const newToken = refreshData?.data?.accessToken
86+
if (newToken) {
87+
sessionStorage.setItem('model_hub_token', newToken)
88+
await performDownload(modelId, newToken, false)
89+
return
90+
} else {
91+
sessionStorage.removeItem('model_hub_token')
92+
setPendingModelId(modelId)
93+
setLoginOpen(true)
94+
return
95+
}
96+
} catch (e) {
97+
sessionStorage.removeItem('model_hub_token')
98+
setPendingModelId(modelId)
99+
setLoginOpen(true)
100+
return
101+
}
102+
}
103+
61104
if (res.status === 403) {
62105
let detailMsg = ''
63106
try {
@@ -68,20 +111,19 @@ const AddModelDialog = ({ open, onClose }) => {
68111
detailMsg = body.message
69112
}
70113
} catch {
71-
// ignore and use default message
114+
console.log('');
115+
72116
}
73-
74117
if (fromLogin) {
75-
setErrorMsg(
76-
detailMsg || t('launchModel.error.noPermissionAfterLogin')
77-
)
118+
setErrorMsg(detailMsg || t('launchModel.error.noPermissionAfterLogin'))
78119
return
79120
} else {
80121
setPendingModelId(modelId)
81122
setLoginOpen(true)
82123
return
83124
}
84125
}
126+
85127
if (!res.ok) {
86128
const text = await res.text().catch(() => '')
87129
throw new Error(
@@ -109,43 +151,26 @@ const AddModelDialog = ({ open, onClose }) => {
109151
await performDownload(modelId)
110152
}
111153

112-
const handleLoginSubmit = async (e) => {
113-
e.preventDefault()
114-
if (!pendingModelId) return
115-
setLoading(true)
116-
setErrorMsg('')
117-
try {
118-
const loginRes = await fetch(`${API_BASE_URL}/api/users/login`, {
119-
method: 'POST',
120-
headers: { 'Content-Type': 'application/json' },
121-
body: JSON.stringify({
122-
usernameOrEmail: usernameOrEmail.trim(),
123-
password: password,
124-
}),
125-
})
126-
if (!loginRes.ok) {
127-
const text = await loginRes.text().catch(() => '')
128-
throw new Error(
129-
t('launchModel.error.loginFailedText', {
130-
status: loginRes.status,
131-
text,
132-
})
133-
)
134-
}
135-
const loginJson = await loginRes.json()
136-
const token = loginJson.data?.accessToken
137-
if (!token) {
138-
throw new Error(t('launchModel.error.noTokenAfterLogin'))
154+
useEffect(() => {
155+
const listener = (event) => {
156+
if (event.origin !== API_BASE_URL) return
157+
const { type, token, refresh_token } = event.data || {}
158+
159+
if (type === 'io_login_success' && token && refresh_token) {
160+
handleClose('login')
161+
sessionStorage.setItem('model_hub_token', token)
162+
sessionStorage.setItem('model_hub_refresh_token', refresh_token)
163+
if (pendingModelId) {
164+
void performDownload(pendingModelId, token, true)
165+
}
139166
}
140-
handleClose('login')
141-
await performDownload(pendingModelId, token, true)
142-
} catch (err) {
143-
console.error(err)
144-
setErrorMsg(err.message || t('launchModel.error.requestFailed'))
145-
} finally {
146-
setLoading(false)
147167
}
148-
}
168+
169+
window.addEventListener('message', listener)
170+
return () => {
171+
window.removeEventListener('message', listener)
172+
}
173+
}, [pendingModelId])
149174

150175
return (
151176
<Dialog open={open} onClose={() => handleClose('add')} width={500}>
@@ -163,7 +188,7 @@ const AddModelDialog = ({ open, onClose }) => {
163188
<div>
164189
{t('launchModel.addModelDialog.introPrefix')}{' '}
165190
<a
166-
href="https://model.xinference.io/models"
191+
href={`${API_BASE_URL}/models`}
167192
target="_blank"
168193
rel="noopener noreferrer"
169194
style={{ textDecoration: 'none', color: '#1976d2' }}
@@ -212,55 +237,27 @@ const AddModelDialog = ({ open, onClose }) => {
212237
</Button>
213238
</DialogActions>
214239

215-
{/* 403 */}
216240
<Dialog open={loginOpen} onClose={() => handleClose('login')}>
217-
<DialogTitle>{t('launchModel.loginDialog.title')}</DialogTitle>
218-
<DialogContent>
219-
<form
220-
onSubmit={handleLoginSubmit}
221-
id="login-form"
222-
style={{
223-
display: 'flex',
224-
flexDirection: 'column',
225-
gap: 12,
226-
width: 360,
227-
paddingTop: 10,
228-
}}
229-
>
230-
<TextField
231-
required
232-
id="usernameOrEmail"
233-
name="usernameOrEmail"
234-
label={t('launchModel.loginDialog.usernameOrEmail')}
235-
fullWidth
236-
value={usernameOrEmail}
237-
onChange={(e) => setUsernameOrEmail(e.target.value)}
238-
disabled={loading}
239-
/>
240-
<TextField
241-
required
242-
id="password"
243-
name="password"
244-
label={t('launchModel.loginDialog.password')}
245-
type="password"
246-
fullWidth
247-
value={password}
248-
onChange={(e) => setPassword(e.target.value)}
249-
disabled={loading}
250-
/>
251-
</form>
252-
{errorMsg && (
253-
<div style={{ color: '#d32f2f', marginTop: 8 }}>{errorMsg}</div>
254-
)}
255-
</DialogContent>
256-
<DialogActions>
257-
<Button onClick={() => handleClose('login')} disabled={loading}>
258-
{t('launchModel.cancel')}
259-
</Button>
260-
<Button type="submit" form="login-form" disabled={loading}>
261-
{t('launchModel.loginDialog.login')}
262-
</Button>
263-
</DialogActions>
241+
<div
242+
style={{
243+
width: '100%',
244+
maxWidth: 640,
245+
padding: 16,
246+
boxSizing: 'border-box',
247+
}}
248+
>
249+
<iframe
250+
ref={loginIframeRef}
251+
src={`${API_BASE_URL}/signin`}
252+
title="Model Platform Signin"
253+
style={{ width: '100%', minHeight: 520, border: 0 }}
254+
/>
255+
<div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 12 }}>
256+
<Button onClick={() => handleClose('login')} disabled={loading}>
257+
关闭
258+
</Button>
259+
</div>
260+
</div>
264261
</Dialog>
265262
</Dialog>
266263
)

0 commit comments

Comments
 (0)