move parseAndVerifyNip05 to utils/nip05

This commit is contained in:
Siddharth Singh 2024-08-05 18:12:53 +05:30
parent 29d7495c39
commit c7e5aed679
No known key found for this signature in database
3 changed files with 59 additions and 63 deletions

View file

@ -1,14 +1,15 @@
import { AppMiddleware } from '@/app.ts'; import { AppMiddleware } from '@/app.ts';
import { Conf } from '@/config.ts'; import { Conf } from '@/config.ts';
import { html, r } from '@/utils/html.ts'; import { html } from '@/utils/html.ts';
import { Storages } from '@/storages.ts';
import { import {
getInstanceName,
getPathParams, getPathParams,
getProfileInfo, getProfileInfo,
getStatusInfo, getStatusInfo,
OpenGraphTemplateOpts, OpenGraphTemplateOpts,
PathParams, PathParams,
} from '@/utils/og-metadata.ts'; } from '@/utils/og-metadata.ts';
import { getInstanceMetadata } from '@/utils/instance.ts';
/** Placeholder to find & replace with metadata. */ /** Placeholder to find & replace with metadata. */
const META_PLACEHOLDER = '<!--server-generated-meta-->' as const; const META_PLACEHOLDER = '<!--server-generated-meta-->' as const;
@ -22,54 +23,45 @@ const META_PLACEHOLDER = '<!--server-generated-meta-->' as const;
* @param opts the metadata to use to fill the template. * @param opts the metadata to use to fill the template.
* @returns the built OpenGraph metadata. * @returns the built OpenGraph metadata.
*/ */
const tpl = async ({ title, type, url, image, description }: OpenGraphTemplateOpts): Promise<string> => const tpl = ({ title, type, url, image, description, site }: OpenGraphTemplateOpts): string => {
html`\ const res = [];
<meta content="${title}" property="og:title"> res.push(html`\
<meta content="${type}" property="og:type"> <meta content="${title}" property="og:title">
<meta content="${url}" property="og:url"> <meta content="${type}" property="og:type">
<meta content="${description}" property="og:description"> <meta content="${url}" property="og:url">
<meta content="${await getInstanceName()}" property="og:site_name"> <meta content="${description}" property="og:description">
<meta content="${site}" property="og:site_name">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="${title}">
<meta name="twitter:description" content="${description}">
`);
${ if (image) {
image res.push(html`\
? r(html` <meta content="${image.url}" property="og:image">
<meta content="${image.url}" property="og:image"> <meta content="${image.w}" property="og:image:width">
<meta content="${image.w}" property="og:image:width"> <meta content="${image.h}" property="og:image:height">
<meta content="${image.h}" property="og:image:height"> <meta name="twitter:image" content="${image.url}">
${image.alt ? r(html`<meta content="${image.alt}" property="og:image:alt">`) : ''} `);
`) if (image.alt) {
: '' res.push(html`<meta content="${image.alt}" property="og:image:alt">`);
res.push(html`<meta content="${image.alt}" property="twitter:image:alt">`);
}
} }
<meta name="twitter:card" content="summary"> return res.join('\n').replace(/\n+/g, '\n').replace(/^[ ]+/gm, '');
<meta name="twitter:title" content="${title}"> };
<meta name="twitter:description" content="${description}">
${
image
? r(html`
<meta name="twitter:image" content="${image.url}">
${image.alt ? r(html`<meta content="${image.alt}" property="twitter:image:alt">`) : ''}
`)
: ''
}
`.replace(/\n+/g, '\n');
const BLANK_META = (url: string) => const store = await Storages.db();
tpl({
title: 'Ditto',
type: 'website',
url,
description: 'Ditto, a decentralized, self-hosted social media server',
});
const buildMetaTags = async (params: PathParams, url: string): Promise<string> => { async function buildMetaTags(params: PathParams, url: string): Promise<string> {
if (!params.acct && !params.statusId) return await BLANK_META(url); // should never happen
if (!params.acct && !params.statusId) return '';
const meta = await getInstanceMetadata(store);
const kind0 = await getProfileInfo(params.acct); const kind0 = await getProfileInfo(params.acct);
console.log(params.acct);
const { description, image } = await getStatusInfo(params.statusId || ''); const { description, image } = await getStatusInfo(params.statusId || '');
const handle = kind0.nip05?.replace(/^_@/, '') || kind0.name || 'npub1xxx'; const handle = kind0.nip05?.replace(/^_@/, '') || kind0.name || 'npub1xxx';
console.log({ n: kind0.nip05, handle });
if (params.acct && params.statusId) { if (params.acct && params.statusId) {
return tpl({ return tpl({
@ -78,6 +70,7 @@ const buildMetaTags = async (params: PathParams, url: string): Promise<string> =
image, image,
description, description,
url, url,
site: meta.name,
}); });
} else if (params.acct) { } else if (params.acct) {
return tpl({ return tpl({
@ -85,6 +78,7 @@ const buildMetaTags = async (params: PathParams, url: string): Promise<string> =
type: 'profile', type: 'profile',
description: kind0.about || '', description: kind0.about || '',
url, url,
site: meta.name,
image: kind0.picture image: kind0.picture
? { ? {
url: kind0.picture, url: kind0.picture,
@ -101,11 +95,12 @@ const buildMetaTags = async (params: PathParams, url: string): Promise<string> =
description, description,
image, image,
url, url,
site: meta.name,
}); });
} }
return await BLANK_META(url); return '';
}; }
export const frontendController: AppMiddleware = async (c, next) => { export const frontendController: AppMiddleware = async (c, next) => {
try { try {

View file

@ -1,12 +1,13 @@
import { nip19 } from 'nostr-tools';
import { NIP05, NStore } from '@nostrify/nostrify'; import { NIP05, NStore } from '@nostrify/nostrify';
import Debug from '@soapbox/stickynotes/debug'; import Debug from '@soapbox/stickynotes/debug';
import { nip19 } from 'nostr-tools';
import tldts from 'tldts'; import tldts from 'tldts';
import { Conf } from '@/config.ts'; import { Conf } from '@/config.ts';
import { Storages } from '@/storages.ts';
import { SimpleLRU } from '@/utils/SimpleLRU.ts'; import { SimpleLRU } from '@/utils/SimpleLRU.ts';
import { Time } from '@/utils/time.ts'; import { Time } from '@/utils/time.ts';
import { Storages } from '@/storages.ts'; import { Nip05, parseNip05 } from '@/utils.ts';
import { fetchWorker } from '@/workers/fetch.ts'; import { fetchWorker } from '@/workers/fetch.ts';
const debug = Debug('ditto:nip05'); const debug = Debug('ditto:nip05');
@ -60,4 +61,20 @@ async function localNip05Lookup(store: NStore, localpart: string): Promise<nip19
} }
} }
export async function parseAndVerifyNip05(
nip05: string | undefined,
pubkey: string,
signal = AbortSignal.timeout(3000),
): Promise<Nip05 | undefined> {
if (!nip05) return;
try {
const result = await nip05Cache.fetch(nip05, { signal });
if (result.pubkey === pubkey) {
return parseNip05(nip05);
}
} catch (_e) {
// do nothing
}
}
export { localNip05Lookup, nip05Cache }; export { localNip05Lookup, nip05Cache };

View file

@ -6,9 +6,9 @@ import { Conf } from '@/config.ts';
import { MastodonAccount } from '@/entities/MastodonAccount.ts'; import { MastodonAccount } from '@/entities/MastodonAccount.ts';
import { type DittoEvent } from '@/interfaces/DittoEvent.ts'; import { type DittoEvent } from '@/interfaces/DittoEvent.ts';
import { getLnurl } from '@/utils/lnurl.ts'; import { getLnurl } from '@/utils/lnurl.ts';
import { nip05Cache } from '@/utils/nip05.ts'; import { parseAndVerifyNip05 } from '@/utils/nip05.ts';
import { getTagSet } from '@/utils/tags.ts'; import { getTagSet } from '@/utils/tags.ts';
import { Nip05, nostrDate, nostrNow, parseNip05 } from '@/utils.ts'; import { nostrDate, nostrNow } from '@/utils.ts';
import { renderEmojis } from '@/views/mastodon/emojis.ts'; import { renderEmojis } from '@/views/mastodon/emojis.ts';
interface ToAccountOpts { interface ToAccountOpts {
@ -113,20 +113,4 @@ function accountFromPubkey(pubkey: string, opts: ToAccountOpts = {}): Promise<Ma
return renderAccount(event, opts); return renderAccount(event, opts);
} }
async function parseAndVerifyNip05(
nip05: string | undefined,
pubkey: string,
signal = AbortSignal.timeout(3000),
): Promise<Nip05 | undefined> {
if (!nip05) return;
try {
const result = await nip05Cache.fetch(nip05, { signal });
if (result.pubkey === pubkey) {
return parseNip05(nip05);
}
} catch (_e) {
// do nothing
}
}
export { accountFromPubkey, renderAccount }; export { accountFromPubkey, renderAccount };