+19
-2
islands/MigrationProgress.tsx
+19
-2
islands/MigrationProgress.tsx
···
532
532
))}
533
533
</div>
534
534
535
-
536
-
537
535
{steps[3].status === "completed" && (
538
536
<div class="p-4 bg-green-50 dark:bg-green-900 rounded-lg border-2 border-green-200 dark:border-green-800">
539
537
<p class="text-sm text-green-800 dark:text-green-200">
540
538
Migration completed successfully! You can now close this page.
541
539
</p>
540
+
<button
541
+
onClick={async () => {
542
+
try {
543
+
const response = await fetch("/api/logout", {
544
+
method: "POST",
545
+
credentials: "include",
546
+
});
547
+
if (!response.ok) {
548
+
throw new Error("Logout failed");
549
+
}
550
+
globalThis.location.href = "/";
551
+
} catch (error) {
552
+
console.error("Failed to logout:", error);
553
+
}
554
+
}}
555
+
class="mt-4 px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors duration-200"
556
+
>
557
+
Sign Out
558
+
</button>
542
559
</div>
543
560
)}
544
561
</div>
+17
-4
islands/MigrationSetup.tsx
+17
-4
islands/MigrationSetup.tsx
···
37
37
const [confirmationText, setConfirmationText] = useState("");
38
38
const [passport, setPassport] = useState<UserPassport | null>(null);
39
39
40
+
const ensureServiceUrl = (url: string): string => {
41
+
if (!url) return url;
42
+
try {
43
+
// If it already has a protocol, return as is
44
+
new URL(url);
45
+
return url;
46
+
} catch {
47
+
// If no protocol, add https://
48
+
return `https://${url}`;
49
+
}
50
+
};
51
+
40
52
useEffect(() => {
41
53
if (!IS_BROWSER) return;
42
54
···
100
112
};
101
113
102
114
const handleServiceChange = (value: string) => {
103
-
setService(value);
115
+
const urlWithProtocol = ensureServiceUrl(value);
116
+
setService(urlWithProtocol);
104
117
setError("");
105
-
if (value) {
106
-
checkServerDescription(value);
118
+
if (urlWithProtocol) {
119
+
checkServerDescription(urlWithProtocol);
107
120
} else {
108
121
setAvailableDomains([]);
109
122
setSelectedDomain("");
···
384
397
<div class="text-center mb-4 mt-6">
385
398
<h3 class="text-2xl font-bold text-red-600 mb-2 tracking-wide">Final Boarding Call</h3>
386
399
<p class="text-gray-700 dark:text-gray-300 mb-2 text-base">
387
-
<span class="font-semibold text-red-500">Warning:</span> This migration process can be <strong>irreversible</strong>.<br />Airport is in <strong>alpha</strong> currently, and we don't recommend it for main accounts.
400
+
<span class="font-semibold text-red-500">Warning:</span> This migration process can be <strong>irreversible</strong>.<br />Airport is in <strong>alpha</strong> currently, and we don't recommend it for main accounts. Migrate at your own risk. We reccomend backing up your data before proceeding.
388
401
</p>
389
402
<p class="text-gray-700 dark:text-gray-300 mb-4 text-base">
390
403
Please type <span class="font-mono font-bold text-blue-600">MIGRATE</span> below to confirm and proceed.
+4
-1
routes/api/logout.ts
+4
-1
routes/api/logout.ts
···
1
-
import { getSession } from "../../lib/sessions.ts";
1
+
import { getSession, destroyAllSessions } from "../../lib/sessions.ts";
2
2
import { oauthClient } from "../../lib/oauth/client.ts";
3
3
import { define } from "../../utils.ts";
4
4
···
18
18
// Then destroy the iron session
19
19
session.destroy();
20
20
}
21
+
22
+
// Destroy all sessions including migration session
23
+
await destroyAllSessions(req);
21
24
22
25
return response;
23
26
} catch (error: unknown) {