Skip to content

Commit beff52a

Browse files
web: open the Windows app from the /auth page (cascade:// handoff) (#15)
PR #13's static /auth page shows the magic-link token with a Copy button and relies on Apple Universal Links to open the native app automatically. Windows has no Universal Link for an unpackaged app, so the link minted with &app=windows (server, #14) only ever showed the copy-the-code fallback. When app=windows is present, redirect to cascade://auth?token=... so the desktop app launches and signs in, with an "Open Cascade" button as the fallback if the browser blocks the programmatic protocol navigation. The copy-the-code path remains for when the app isn't installed. Co-authored-by: Jacob Stephens <jstephens@vagabondtours.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 65df6bb commit beff52a

1 file changed

Lines changed: 32 additions & 2 deletions

File tree

apps/web/public/auth/index.html

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,29 @@
7171
button:active { transform: translateY(1px); }
7272
.hint { font-size: 0.85rem; margin-top: 18px; }
7373
.err { color: #e2786e; }
74+
.open {
75+
display: inline-block;
76+
margin: 0 0 18px;
77+
padding: 12px 22px;
78+
border-radius: 10px;
79+
background: var(--accent);
80+
color: #042029;
81+
font-weight: 600;
82+
text-decoration: none;
83+
}
84+
.open[hidden] { display: none; }
7485
</style>
7586
</head>
7687
<body>
7788
<main class="card">
7889
<h1>Sign in to Cascade</h1>
7990
<div id="content">
80-
<p>
91+
<p id="lead">
8192
If the Cascade app is installed it should have opened automatically.
8293
Otherwise, open Cascade, then paste this sign-in code into the
8394
<em>“paste the sign-in link”</em> box:
8495
</p>
96+
<a id="open" class="open" href="#" hidden>Open Cascade</a>
8597
<div class="token">
8698
<code id="token"></code>
8799
<button id="copy" type="button">Copy</button>
@@ -92,11 +104,29 @@ <h1>Sign in to Cascade</h1>
92104
<script>
93105
// The whole sign-in link works too — the app extracts the token itself —
94106
// but showing just the token keeps the copy/paste short.
95-
const token = new URLSearchParams(location.search).get("token");
107+
const params = new URLSearchParams(location.search);
108+
const token = params.get("token");
96109
const tokenEl = document.getElementById("token");
97110
const copyBtn = document.getElementById("copy");
98111
if (token) {
99112
tokenEl.textContent = token;
113+
114+
// Windows desktop handoff: links minted for the Windows app carry
115+
// &app=windows. The unpackaged app has no Universal Link (unlike
116+
// Apple), so launch it explicitly via its cascade:// scheme — auto-
117+
// attempt, plus a button as the reliable fallback if the browser
118+
// blocks programmatic protocol navigation. The copy-the-code path
119+
// below still works if the app isn't installed.
120+
if (params.get("app") === "windows") {
121+
const deepLink = "cascade://auth?token=" + encodeURIComponent(token);
122+
document.getElementById("lead").textContent =
123+
"Opening the Cascade app to finish signing in…";
124+
const openBtn = document.getElementById("open");
125+
openBtn.href = deepLink;
126+
openBtn.hidden = false;
127+
location.href = deepLink;
128+
}
129+
100130
copyBtn.addEventListener("click", async () => {
101131
try {
102132
await navigator.clipboard.writeText(token);

0 commit comments

Comments
 (0)