feat(email): use popup flow for gmail oauth callback (#307)

* feat(email): use popup flow for gmail oauth callback

* fix(email): satisfy lint in oauth callback helper
This commit is contained in:
Yiming Qi
2026-03-29 20:13:45 +08:00
committed by GitHub
parent c93ddc3a87
commit ba0569c1fa
4 changed files with 73 additions and 11 deletions
+1 -1
View File
@@ -413,7 +413,7 @@
"title": "OAuth2 Authorization",
"description": "Authorize this provider to send emails on your behalf. You will be redirected to the provider's login page.",
"authorize": "Authorize",
"authorizeOpened": "Authorization page opened in a new tab",
"authorizeOpened": "Authorization completed",
"authorizeFailed": "Failed to start authorization",
"status": {
"checking": "Checking authorization status...",
+1 -1
View File
@@ -409,7 +409,7 @@
"title": "OAuth2 授权",
"description": "授权此提供商以您的名义发送邮件,系统将跳转到提供商登录页面。",
"authorize": "授权",
"authorizeOpened": "授权页面已在新标签页打开",
"authorizeOpened": "授权完成",
"authorizeFailed": "启动授权失败",
"status": {
"checking": "正在检查授权状态...",
@@ -379,8 +379,35 @@ async function handleAuthorize() {
if (error || !data?.auth_url) {
throw new Error(t('email.oauth.authorizeFailed'))
}
window.open(data.auth_url, '_blank', 'noopener,noreferrer')
toast.success(t('email.oauth.authorizeOpened'))
const popup = window.open(data.auth_url, 'email-oauth', 'width=600,height=720')
if (!popup) {
throw new Error(t('email.oauth.authorizeFailed'))
}
await new Promise<void>((resolve, reject) => {
const cleanup = () => {
window.removeEventListener('message', onMessage)
}
const onMessage = async (event: MessageEvent) => {
if (event.data?.type !== 'memoh-email-oauth-callback') return
if (event.data?.providerId && event.data.providerId !== curProviderId.value) return
cleanup()
if (event.data?.status === 'success') {
await fetchOAuthStatus()
toast.success(t('email.oauth.authorizeOpened'))
resolve()
return
}
reject(new Error(typeof event.data?.error === 'string' && event.data.error ? event.data.error : t('email.oauth.authorizeFailed')))
}
window.addEventListener('message', onMessage)
})
} catch (e: unknown) {
toast.error(e instanceof Error ? e.message : t('email.oauth.authorizeFailed'))
} finally {