8 Commits

Author SHA1 Message Date
91eff4ad07 Add missing unbind
All checks were successful
CI / Test and lint (push) Successful in 24s
2025-05-21 16:34:12 +04:00
994053e080 Ignore test coverage results dir
All checks were successful
CI / Test and lint (push) Successful in 16s
2025-05-02 13:22:41 +04:00
bc37756097 Add exclude option to compile command
All checks were successful
CI / Test and lint (push) Successful in 18s
2025-05-02 13:09:11 +04:00
3a5733eeee Use nprofile for article author link 2025-05-02 13:04:15 +04:00
7c2549cbfe Add more link rel elements, use nprofile
All checks were successful
CI / Test and lint (push) Successful in 17s
2025-04-30 12:28:10 +04:00
e3bd385c96 Add rel=author Nostr links to article pages 2025-04-30 12:22:39 +04:00
038ce15908 Fix and complete author element in Atom feed 2025-04-30 12:22:16 +04:00
7aebcfc43f Add nprofile property to profile model 2025-04-30 12:21:51 +04:00
8 changed files with 27 additions and 4 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.env .env
users.yaml users.yaml
build/ build/
coverage/

View File

@@ -2,7 +2,7 @@
"tasks": { "tasks": {
"dev": "deno run --allow-all --watch server.ts", "dev": "deno run --allow-all --watch server.ts",
"server": "deno run --allow-all server.ts", "server": "deno run --allow-all server.ts",
"compile": "deno compile --allow-all --include ./assets/ --output ./build/substr_x86_64-unknown-linux-gnu server.ts", "compile": "deno compile --allow-all --include ./assets/ --exclude ./tests/ --output ./build/substr_x86_64-unknown-linux-gnu server.ts",
"test": "DENO_ENV=test deno test --allow-read --allow-env" "test": "DENO_ENV=test deno test --allow-read --allow-env"
}, },
"imports": { "imports": {

View File

@@ -42,7 +42,9 @@ export async function profileAtomFeed(
<updated>${isoDate(lastUpdate)}</updated> <updated>${isoDate(lastUpdate)}</updated>
<icon>${profile.avatarImageUrl}</icon> <icon>${profile.avatarImageUrl}</icon>
<author> <author>
<name>${name}</name> <name>${profile.name}</name>
<uri>${profile.profileUrl}</uri>
<nostr:uri>nostr:${profile.nprofile}</nostr>
</author> </author>
${articlesXml} ${articlesXml}
</feed> </feed>

View File

@@ -210,7 +210,8 @@ function feedLinksHtml(profile: Profile) {
function profileMetaHtml(profile: Profile) { function profileMetaHtml(profile: Profile) {
return ` return `
<link rel="icon" href="${profile.avatarImageUrl}" type="image/png"> <link rel="icon" href="${profile.avatarImageUrl}" type="image/png">
<link rel="alternate" type="application/nostr+json" href="nostr:${profile.npub}" title="${profile.name} on Nostr"> <link rel="me" type="application/nostr+json" href="nostr:${profile.nprofile}" title="${profile.name}">
<link rel="alternate" type="application/nostr+json" href="nostr:${profile.nprofile}" title="${profile.name} on Nostr">
<meta property="og:url" content="${profile.profileUrl}"> <meta property="og:url" content="${profile.profileUrl}">
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:title" content="${profile.name} on Nostr"> <meta property="og:title" content="${profile.name} on Nostr">
@@ -231,6 +232,8 @@ function articleMetaHtml(article: Article, profile: Profile) {
return ` return `
<link rel="icon" href="${profile.avatarImageUrl}" type="image/png"> <link rel="icon" href="${profile.avatarImageUrl}" type="image/png">
<link rel="alternate" type="application/nostr+json" href="nostr:${article.naddr}" title="This article on Nostr"> <link rel="alternate" type="application/nostr+json" href="nostr:${article.naddr}" title="This article on Nostr">
<link rel="author" type="text/html" href="${profile.profileUrl}" title="${profile.name}">
<link rel="author" type="application/nostr+json" href="nostr:${profile.nprofile}" title="${profile.name}">
<meta property="og:url" content="${article.url}"> <meta property="og:url" content="${article.url}">
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:title" content="${article.title}"> <meta property="og:title" content="${article.title}">

View File

@@ -49,6 +49,8 @@ export async function lookupUsernameByPubkey(pubkey: string): Promise<string | u
if (searchEntries.length > 0) { if (searchEntries.length > 0) {
username = searchEntries[0].cn.toString(); username = searchEntries[0].cn.toString();
} }
await client.unbind();
} catch (e) { } catch (e) {
await client.unbind(); await client.unbind();
throw e; throw e;

View File

@@ -59,6 +59,13 @@ export default class Profile {
return nip19.npubEncode(this.pubkey); return nip19.npubEncode(this.pubkey);
} }
get nprofile(): string {
return nip19.nprofileEncode({
pubkey: this.pubkey,
relays: [config.relay_urls[0]],
});
}
get profileUrl(): string { get profileUrl(): string {
return `${config.base_url}/@${this.username}`; return `${config.base_url}/@${this.username}`;
} }

View File

@@ -69,7 +69,7 @@ describe("Article", () => {
describe("#naddr", () => { describe("#naddr", () => {
it("returns a bech32 addressable event ID", () => { it("returns a bech32 addressable event ID", () => {
expect(article.naddr).toMatch( expect(article.naddr).toMatch(
/naddr1qvzqqqr4gupzq8meqkx80g3yuklzymy0qf/, /^naddr1qvzqqqr4gupzq8meqkx80g3yuklzymy0qf/,
); );
}); });
}); });

View File

@@ -40,4 +40,12 @@ describe("Profile", () => {
); );
}); });
}); });
describe("#nprofile", () => {
it("returns a bech32 profile ID", () => {
expect(profile.nprofile).toMatch(
/^nprofile1qyt8wumn8ghj7mn0wd68ytntdaek6mmn9ehhyecqyq0hjpvvw73zfed7yf/,
);
});
});
}); });