+73
-2
islands/MigrationSetup.tsx
+73
-2
islands/MigrationSetup.tsx
···
1
-
import { useState } from "preact/hooks";
1
+
import { useState, useEffect } from "preact/hooks";
2
+
import { IS_BROWSER } from "fresh/runtime";
2
3
3
4
interface MigrationSetupProps {
4
5
service?: string | null;
···
10
11
interface ServerDescription {
11
12
inviteCodeRequired: boolean;
12
13
availableUserDomains: string[];
14
+
}
15
+
16
+
interface UserPassport {
17
+
did: string;
18
+
handle: string;
19
+
pds: string;
20
+
createdAt?: string;
13
21
}
14
22
15
23
export default function MigrationSetup(props: MigrationSetupProps) {
···
27
35
const [isLoading, setIsLoading] = useState(false);
28
36
const [showConfirmation, setShowConfirmation] = useState(false);
29
37
const [confirmationText, setConfirmationText] = useState("");
38
+
const [passport, setPassport] = useState<UserPassport | null>(null);
39
+
40
+
useEffect(() => {
41
+
if (!IS_BROWSER) return;
42
+
43
+
const fetchPassport = async () => {
44
+
try {
45
+
const response = await fetch("/api/me", {
46
+
credentials: "include",
47
+
});
48
+
if (!response.ok) {
49
+
throw new Error("Failed to fetch user profile");
50
+
}
51
+
const userData = await response.json();
52
+
if (userData) {
53
+
// Get PDS URL from the current service
54
+
const pdsResponse = await fetch(`/api/resolve-pds?did=${userData.did}`);
55
+
const pdsData = await pdsResponse.json();
56
+
57
+
setPassport({
58
+
did: userData.did,
59
+
handle: userData.handle,
60
+
pds: pdsData.pds || "Unknown",
61
+
createdAt: new Date().toISOString() // TODO: Get actual creation date from API
62
+
});
63
+
}
64
+
} catch (error) {
65
+
console.error("Failed to fetch passport:", error);
66
+
}
67
+
};
68
+
69
+
fetchPassport();
70
+
}, []);
30
71
31
72
const checkServerDescription = async (serviceUrl: string) => {
32
73
try {
···
122
163
<div class="mt-2 text-sm text-gray-500 dark:text-gray-400 font-mono">FLIGHT: MIG-2024</div>
123
164
</div>
124
165
166
+
{/* Passport Section */}
167
+
{passport && (
168
+
<div class="mb-8 bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 border border-gray-200 dark:border-gray-700">
169
+
<div class="flex items-center justify-between mb-4">
170
+
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Current Passport</h3>
171
+
<div class="text-xs text-gray-500 dark:text-gray-400 font-mono">ISSUED: {new Date().toLocaleDateString()}</div>
172
+
</div>
173
+
<div class="grid grid-cols-2 gap-4 text-sm">
174
+
<div>
175
+
<div class="text-gray-500 dark:text-gray-400 mb-1">Handle</div>
176
+
<div class="font-mono text-gray-900 dark:text-white">{passport.handle}</div>
177
+
</div>
178
+
<div>
179
+
<div class="text-gray-500 dark:text-gray-400 mb-1">DID</div>
180
+
<div class="font-mono text-gray-900 dark:text-white break-all">{passport.did}</div>
181
+
</div>
182
+
<div>
183
+
<div class="text-gray-500 dark:text-gray-400 mb-1">Citizen of PDS</div>
184
+
<div class="font-mono text-gray-900 dark:text-white break-all">{passport.pds}</div>
185
+
</div>
186
+
<div>
187
+
<div class="text-gray-500 dark:text-gray-400 mb-1">Account Age</div>
188
+
<div class="font-mono text-gray-900 dark:text-white">
189
+
{passport.createdAt ? new Date(passport.createdAt).toLocaleDateString() : "Unknown"}
190
+
</div>
191
+
</div>
192
+
</div>
193
+
</div>
194
+
)}
195
+
125
196
<form onSubmit={handleSubmit} class="space-y-6">
126
197
{error && (
127
198
<div class="bg-red-50 dark:bg-red-900 rounded-lg">
···
221
292
222
293
<div>
223
294
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
224
-
Contact Email
295
+
Email
225
296
<span class="text-xs text-gray-500 ml-1">(Emergency Contact)</span>
226
297
</label>
227
298
<div class="relative">
+30
routes/api/resolve-pds.ts
+30
routes/api/resolve-pds.ts
···
1
+
import { resolver } from "../../lib/id-resolver.ts";
2
+
import { define } from "../../utils.ts";
3
+
4
+
export const handler = define.handlers({
5
+
async GET(ctx) {
6
+
const url = new URL(ctx.req.url);
7
+
const did = url.searchParams.get("did");
8
+
9
+
if (!did) {
10
+
return new Response(JSON.stringify({ error: "DID parameter is required" }), {
11
+
status: 400,
12
+
headers: { "Content-Type": "application/json" }
13
+
});
14
+
}
15
+
16
+
try {
17
+
const pds = await resolver.resolveDidToPdsUrl(did);
18
+
return new Response(JSON.stringify({ pds }), {
19
+
status: 200,
20
+
headers: { "Content-Type": "application/json" }
21
+
});
22
+
} catch (error) {
23
+
console.error("Failed to resolve PDS:", error);
24
+
return new Response(JSON.stringify({ error: "Failed to resolve PDS" }), {
25
+
status: 500,
26
+
headers: { "Content-Type": "application/json" }
27
+
});
28
+
}
29
+
}
30
+
});