+
+ {page.title}
+ {#if page.publishedAt || page.updatedAt}
+
+ {#if page.publishedAt}Published {page.publishedAt.slice(0, 10)}{/if}
+ {#if page.updatedAt}·Updated
+ {page.updatedAt.slice(0, 10)}{/if}
+
+ {/if}
+
+
+
+ {@html page.html}
+
+
+
diff --git a/apps/web/src/lib/server/atmosphere/atmosphere.test.ts b/apps/web/src/lib/server/atmosphere/atmosphere.test.ts
--- a/apps/web/src/lib/server/atmosphere/atmosphere.test.ts
+++ b/apps/web/src/lib/server/atmosphere/atmosphere.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import { listAllRecords, blobUrl, type AtmosphereContext } from './xrpc';
-import { pdsEndpoint } from './identity';
+import { handleFromDidDocument, pdsEndpoint } from './identity';
import { fetchBlueskyPosts, fetchBlueskyProfile } from './bluesky';
import { fetchDocuments } from './standard-site';
import { fetchSifaProfile, fetchSifaSkills } from './sifa';
@@ -80,6 +80,16 @@ ]
};
expect(pdsEndpoint(doc)).toBe('https://pds.example');
expect(pdsEndpoint({ id: 'did:plc:x' })).toBeUndefined();
+ });
+
+ it('extracts the handle from alsoKnownAs', () => {
+ const doc = {
+ id: 'did:plc:test123',
+ alsoKnownAs: ['https://example.com', 'at://jacob.example.com']
+ };
+ expect(handleFromDidDocument(doc)).toBe('jacob.example.com');
+ expect(handleFromDidDocument({ id: 'did:plc:x' })).toBeUndefined();
+ expect(handleFromDidDocument({ alsoKnownAs: ['https://only-web.example'] })).toBeUndefined();
});
});
diff --git a/apps/web/src/lib/server/atmosphere/identity.ts b/apps/web/src/lib/server/atmosphere/identity.ts
--- a/apps/web/src/lib/server/atmosphere/identity.ts
+++ b/apps/web/src/lib/server/atmosphere/identity.ts
@@ -55,6 +55,18 @@ if (!res.ok) throw new Error(`DID resolution failed (HTTP ${res.status}) for ${did}`);
return res.json() as Promise