fix(auth): fix Android deep link intent URL format for Google OAuth
The intent:// URL in renderTauriDeepLinkPage was intent:/path (single slash), producing zeavisedu:/login?token=xxx — a non-hierarchical URL that new URL() cannot parse. Fixed to intent://login/path which produces a proper hierarchical URI (zeavisedu://login/login?token=xxx). Also hardened setupDeepLinkHandler to handle both double-slash (://) and single-slash (:/) custom-scheme URLs as fallback. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -80,7 +80,9 @@ function renderTauriDeepLinkPage(targetUrl: string): Response {
|
|||||||
const escapedPath = pathAndQuery.replace(/"/g, '"');
|
const escapedPath = pathAndQuery.replace(/"/g, '"');
|
||||||
// intent:// scheme: Chrome on Android opens the target app by package name
|
// intent:// scheme: Chrome on Android opens the target app by package name
|
||||||
// browser_fallback_url: shown if the app isn't installed
|
// browser_fallback_url: shown if the app isn't installed
|
||||||
const intentUrl = `intent:${escapedPath}#Intent;scheme=zeavisedu;package=com.zeavis.edu;S.browser_fallback_url=${encodeURIComponent(targetUrl)};end`;
|
// Use intent://login/... to produce data URI zeavisedu://login/login?token=xxx
|
||||||
|
// which new URL() can parse (single-slash non-hierarchical URLs break WebView)
|
||||||
|
const intentUrl = `intent://login${escapedPath}#Intent;scheme=zeavisedu;package=com.zeavis.edu;S.browser_fallback_url=${encodeURIComponent(targetUrl)};end`;
|
||||||
|
|
||||||
const html = `<!DOCTYPE html>
|
const html = `<!DOCTYPE html>
|
||||||
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
|||||||
@@ -35,21 +35,26 @@ export async function setupDeepLinkHandler(): Promise<void> {
|
|||||||
const { onOpenUrl } = await import('@tauri-apps/plugin-deep-link');
|
const { onOpenUrl } = await import('@tauri-apps/plugin-deep-link');
|
||||||
onOpenUrl((urls) => {
|
onOpenUrl((urls) => {
|
||||||
for (const url of urls) {
|
for (const url of urls) {
|
||||||
// url looks like: zeavisedu://zeavisedu.asepharyana.my.id/login?token=xxx
|
// url looks like: zeavisedu://login/login?token=xxx
|
||||||
// Extract path + query after the host
|
// Extract path + query after the host
|
||||||
try {
|
try {
|
||||||
const u = new URL(url);
|
const u = new URL(url);
|
||||||
const target = u.pathname + u.search + u.hash;
|
const target = u.pathname + u.search + u.hash;
|
||||||
if (target && target !== '/') {
|
if (target && target !== '/') {
|
||||||
window.location.href = target;
|
window.location.href = target;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch { /* try fallback below */ }
|
||||||
|
|
||||||
|
// Fallback: extract everything after scheme, handling both // and /
|
||||||
|
let match = url.match(/^[^:]+:\/\/(?:[^/]+)?(\/.*)?$/);
|
||||||
|
if (!match) {
|
||||||
|
// Also handle single-slash non-hierarchical URLs (e.g. zeavisedu:/path)
|
||||||
|
match = url.match(/^[^:]+:\/(\/.*)?$/);
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
// If URL parsing fails, try to extract everything after the scheme
|
|
||||||
const match = url.match(/^[^:]+:\/\/(?:[^/]+)?(\/.*)?$/);
|
|
||||||
if (match?.[1]) {
|
if (match?.[1]) {
|
||||||
window.location.href = match[1];
|
window.location.href = match[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user