fix(auth): bind mailbox callbacks to pending popup
This commit is contained in:
@@ -44,6 +44,7 @@ import {
|
||||
import { useDialogActions } from "../dialogs";
|
||||
import { useI18n } from "../i18n/I18nProvider";
|
||||
import ViewStateNotice from "./ViewStateNotice";
|
||||
import { emailOAuthCallbackOrigin, emailOAuthMessage, type EmailOAuthAttempt } from "../emailOAuth";
|
||||
|
||||
function parseRawEmail(raw: string): { subject?: string; date?: string; from?: string; to?: string; body: string } {
|
||||
const lines = raw.replace(/\r\n/g, "\n").split("\n");
|
||||
@@ -155,6 +156,16 @@ export default function Correspondence({ jobId, jobContext }: { jobId: number; j
|
||||
const [manageNote, setManageNote] = useState("");
|
||||
const [manageSaving, setManageSaving] = useState(false);
|
||||
const autoRefreshKeyRef = useRef<string | null>(null);
|
||||
const gmailOAuth = useRef<{ active: boolean; generation: number; starting: boolean; attempt: EmailOAuthAttempt | null }>({ active: true, generation: 0, starting: false, attempt: null });
|
||||
const startupTranslation = useRef(t);
|
||||
|
||||
useEffect(() => { startupTranslation.current = t; }, [t]);
|
||||
|
||||
useEffect(() => {
|
||||
const session = gmailOAuth.current;
|
||||
session.active = true;
|
||||
return () => { session.active = false; session.generation += 1; session.starting = false; session.attempt = null; };
|
||||
}, [jobId]);
|
||||
|
||||
const load = useCallback(async () => {
|
||||
setMessagesLoading(true);
|
||||
@@ -292,8 +303,11 @@ export default function Correspondence({ jobId, jobContext }: { jobId: number; j
|
||||
|
||||
useEffect(() => {
|
||||
const onMessage = (event: MessageEvent) => {
|
||||
const data = event.data as { source?: string; status?: string; message?: string };
|
||||
if (data?.source !== "jobtracker-gmail-oauth") return;
|
||||
const session = gmailOAuth.current;
|
||||
if (!session.active || !session.attempt) return;
|
||||
const data = emailOAuthMessage(event, session.attempt);
|
||||
if (!data) return;
|
||||
session.attempt = null;
|
||||
if (data.status === "connected") {
|
||||
toast(data.message || t("googleLinkedSuccess"), "success");
|
||||
void loadGmailStatus();
|
||||
@@ -356,12 +370,24 @@ export default function Correspondence({ jobId, jobContext }: { jobId: number; j
|
||||
};
|
||||
|
||||
const connectGmail = async () => {
|
||||
const session = gmailOAuth.current;
|
||||
if (!session.active || session.starting) return;
|
||||
if (session.attempt && !session.attempt.popup.closed) { session.attempt.popup.focus(); return; }
|
||||
session.attempt = null;
|
||||
session.starting = true;
|
||||
const generation = session.generation;
|
||||
try {
|
||||
const res = await api.get<{ url: string }>("/gmail/connect-url");
|
||||
if (!session.active || generation !== session.generation) return;
|
||||
const origin = emailOAuthCallbackOrigin(res.data.url, "gmail");
|
||||
if (!origin) { toast(startupTranslation.current("correspondenceStartGmailFailed"), "error"); return; }
|
||||
const popup = window.open(res.data.url, "jobtracker-gmail-connect", "width=620,height=760,resizable=yes,scrollbars=yes");
|
||||
if (!popup) toast(t("correspondenceBlockedPopup"), "error");
|
||||
if (!popup) toast(startupTranslation.current("correspondenceBlockedPopup"), "error");
|
||||
else session.attempt = { provider: "gmail", origin, popup };
|
||||
} catch (error) {
|
||||
toast(getApiErrorMessage(error, t("correspondenceStartGmailFailed")), "error");
|
||||
if (session.active && generation === session.generation) toast(getApiErrorMessage(error, startupTranslation.current("correspondenceStartGmailFailed")), "error");
|
||||
} finally {
|
||||
if (generation === session.generation) session.starting = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user