Code style changes

This commit is contained in:
Alex Gleason 2024-08-07 18:50:32 -05:00
parent 020736fd47
commit 72970bf480
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
4 changed files with 61 additions and 48 deletions

View file

@ -250,8 +250,9 @@ class Conf {
static get cronEnabled(): boolean { static get cronEnabled(): boolean {
return optionalBooleanSchema.parse(Deno.env.get('CRON_ENABLED')) ?? true; return optionalBooleanSchema.parse(Deno.env.get('CRON_ENABLED')) ?? true;
} }
static get opengraphRouteRegex(): string { /** Crawler User-Agent regex to render link previews to. */
return Deno.env.get('OPENGRAPH_ROUTE_REGEX') || static get crawlerRegex(): string {
return Deno.env.get('CRAWLER_REGEX') ||
'googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterestbot|slackbot|vkShare|W3C_Validator|whatsapp|mastodon|pleroma|Discordbot|AhrefsBot|SEMrushBot|MJ12bot|SeekportBot|Synapse|Matrix'; 'googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterestbot|slackbot|vkShare|W3C_Validator|whatsapp|mastodon|pleroma|Discordbot|AhrefsBot|SEMrushBot|MJ12bot|SeekportBot|Synapse|Matrix';
} }
/** Path to the custom policy module. Must be an absolute path, https:, npm:, or jsr: URI. */ /** Path to the custom policy module. Must be an absolute path, https:, npm:, or jsr: URI. */

View file

@ -21,30 +21,43 @@ const META_PLACEHOLDER = '<!--server-generated-meta-->' as const;
async function buildTemplateOpts(params: PathParams, url: string): Promise<OpenGraphTemplateOpts> { async function buildTemplateOpts(params: PathParams, url: string): Promise<OpenGraphTemplateOpts> {
const store = await Storages.db(); const store = await Storages.db();
const meta = await getInstanceMetadata(store); const meta = await getInstanceMetadata(store);
const res: OpenGraphTemplateOpts = { const res: OpenGraphTemplateOpts = {
title: `View this page on ${meta.name}`, title: meta.name,
type: 'article', type: 'article',
description: meta.about, description: meta.about,
url, url,
site: meta.name, site: meta.name,
image: { image: {
url: Conf.local('/favicon.ico'), url: Conf.local('/favicon.ico'),
w: 48,
h: 48,
}, },
}; };
try { try {
if (params.acct && !params.statusId) { if (params.statusId) {
const { description, image, title } = await getStatusInfo(params.statusId);
res.description = description;
res.title = title;
if (res.image) {
res.image = image;
}
} else if (params.acct) {
const key = /^[a-f0-9]{64}$/.test(params.acct) ? 'pubkey' : 'handle'; const key = /^[a-f0-9]{64}$/.test(params.acct) ? 'pubkey' : 'handle';
let handle = ''; let handle = '';
try { try {
const profile = await fetchProfile({ [key]: params.acct }); const profile = await fetchProfile({ [key]: params.acct });
handle = await getHandle(params.acct, profile); handle = await getHandle(params.acct, profile);
res.description = profile.meta.about || `@${handle}'s Nostr profile`;
res.description = profile.meta.about;
if (profile.meta.picture) { if (profile.meta.picture) {
res.image = { url: profile.meta.picture, h: 150, w: 150 }; res.image = {
url: profile.meta.picture,
};
} }
} catch (_) { } catch {
console.debug(`couldn't find kind 0 for ${params.acct}`); console.debug(`couldn't find kind 0 for ${params.acct}`);
// @ts-ignore we don't want getHandle trying to do a lookup here // @ts-ignore we don't want getHandle trying to do a lookup here
// but we do want it to give us a nice pretty npub // but we do want it to give us a nice pretty npub
@ -52,14 +65,8 @@ async function buildTemplateOpts(params: PathParams, url: string): Promise<OpenG
res.description = `@${handle}'s Nostr profile`; res.description = `@${handle}'s Nostr profile`;
} }
Object.assign(res, { res.type = 'profile';
type: 'profile', res.title = `View @${handle}'s profile on Ditto`;
title: `View @${handle}'s profile on Ditto`,
});
} else if (params.statusId) {
const { description, image, title } = await getStatusInfo(params.statusId);
Object.assign(res, { description, title });
if (image) Object.assign(res, { image });
} }
} catch (e) { } catch (e) {
console.debug('Error getting OpenGraph metadata information:'); console.debug('Error getting OpenGraph metadata information:');
@ -70,16 +77,17 @@ async function buildTemplateOpts(params: PathParams, url: string): Promise<OpenG
return res; return res;
} }
const SHOULD_INJECT_RE = new RegExp(Conf.opengraphRouteRegex, 'i');
export const frontendController: AppMiddleware = async (c, next) => { export const frontendController: AppMiddleware = async (c, next) => {
try { try {
const content = await Deno.readTextFile(new URL('../../public/index.html', import.meta.url)); const content = await Deno.readTextFile(new URL('../../public/index.html', import.meta.url));
const ua = c.req.header('User-Agent'); const ua = c.req.header('User-Agent');
console.debug('ua', ua); console.debug('ua', ua);
if (!SHOULD_INJECT_RE.test(ua || '')) {
if (!new RegExp(Conf.crawlerRegex, 'i').test(ua ?? '')) {
return c.html(content); return c.html(content);
} }
if (content.includes(META_PLACEHOLDER)) { if (content.includes(META_PLACEHOLDER)) {
const params = getPathParams(c.req.path); const params = getPathParams(c.req.path);
if (params) { if (params) {
@ -87,7 +95,7 @@ export const frontendController: AppMiddleware = async (c, next) => {
const meta = metadataView(await buildTemplateOpts(params, Conf.local(c.req.path))); const meta = metadataView(await buildTemplateOpts(params, Conf.local(c.req.path)));
return c.html(content.replace(META_PLACEHOLDER, meta)); return c.html(content.replace(META_PLACEHOLDER, meta));
} catch (e) { } catch (e) {
console.log(`Error in building meta tags: ${e}`); console.log(`Error building meta tags: ${e}`);
return c.html(content); return c.html(content);
} }
} }

View file

@ -1,9 +1,9 @@
import { NostrEvent, NostrMetadata, NSchema as n } from '@nostrify/nostrify'; import { NostrEvent, NostrMetadata, NSchema as n } from '@nostrify/nostrify';
import { getAuthor, getEvent } from '@/queries.ts'; import { Stickynotes } from '@soapbox/stickynotes';
import { nip19, nip27 } from 'nostr-tools'; import { nip19, nip27 } from 'nostr-tools';
import { match } from 'path-to-regexp'; import { match } from 'path-to-regexp';
import { Stickynotes } from '@soapbox/stickynotes'; import { getAuthor, getEvent } from '@/queries.ts';
import { lookupPubkey } from '@/utils/lookup.ts'; import { lookupPubkey } from '@/utils/lookup.ts';
import { parseAndVerifyNip05 } from '@/utils/nip05.ts'; import { parseAndVerifyNip05 } from '@/utils/nip05.ts';
import { parseNip05 } from '@/utils.ts'; import { parseNip05 } from '@/utils.ts';
@ -15,7 +15,7 @@ export interface OpenGraphTemplateOpts {
type: 'article' | 'profile' | 'website'; type: 'article' | 'profile' | 'website';
url: string; url: string;
image?: StatusInfo['image']; image?: StatusInfo['image'];
description: string; description?: string;
site: string; site: string;
} }
@ -26,8 +26,8 @@ interface StatusInfo {
description: string; description: string;
image?: { image?: {
url: string; url: string;
w: number; w?: number;
h: number; h?: number;
alt?: string; alt?: string;
}; };
} }
@ -50,7 +50,7 @@ const SSR_ROUTES = [
const SSR_ROUTE_MATCHERS = SSR_ROUTES.map((route) => match(route, { decode: decodeURIComponent })); const SSR_ROUTE_MATCHERS = SSR_ROUTES.map((route) => match(route, { decode: decodeURIComponent }));
export function getPathParams(path: string) { export function getPathParams(path: string): PathParams | undefined {
for (const matcher of SSR_ROUTE_MATCHERS) { for (const matcher of SSR_ROUTE_MATCHERS) {
const result = matcher(path); const result = matcher(path);
if (!result) continue; if (!result) continue;
@ -144,7 +144,7 @@ export async function getHandle(id: string, acc?: ProfileInfo) {
export async function getStatusInfo(id: string): Promise<StatusInfo> { export async function getStatusInfo(id: string): Promise<StatusInfo> {
const event = await getEvent(id); const event = await getEvent(id);
if (!id || !event) throw new Error('Invalid post id supplied'); if (!event) throw new Error('Invalid post id supplied');
let title = 'View post on Ditto'; let title = 'View post on Ditto';
try { try {
const handle = await getHandle(event.pubkey); const handle = await getHandle(event.pubkey);

View file

@ -6,31 +6,35 @@ import { OpenGraphTemplateOpts } from '@/utils/og-metadata.ts';
* @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.
*/ */
export const metadataView = ({ title, type, url, image, description, site }: OpenGraphTemplateOpts): string => { export function metadataView({ title, type, url, image, description, site }: OpenGraphTemplateOpts): string {
const res = []; const res: string[] = [
res.push(html`\ html` <meta content="${title}" property="og:title">`,
<meta content="${title}" property="og:title"> html` <meta content="${type}" property="og:type">`,
<meta content="${type}" property="og:type"> html` <meta content="${url}" property="og:url">`,
<meta content="${url}" property="og:url"> html` <meta content="${site}" property="og:site_name">`,
<meta content="${description}" property="og:description"> html` <meta name="twitter:card" content="summary">`,
<meta content="${site}" property="og:site_name"> html` <meta name="twitter:title" content="${title}">`,
<meta name="twitter:card" content="summary"> ];
<meta name="twitter:title" content="${title}">
<meta name="twitter:description" content="${description}"> if (description) {
`); res.push(html`<meta content="${description}" property="og:description">`);
res.push(html`<meta content="${description}" property="twitter:description">`);
}
if (image) { if (image) {
res.push(html`\ res.push(html`<meta content="${image.url}" property="og:image">`);
<meta content="${image.url}" property="og:image"> res.push(html`<meta name="twitter:image" content="${image.url}">`);
<meta content="${image.w}" property="og:image:width">
<meta content="${image.h}" property="og:image:height"> if (image.w && image.h) {
<meta name="twitter:image" content="${image.url}"> res.push(html`<meta content="${image.w}" property="og:image:width">`);
`); res.push(html`<meta content="${image.h}" property="og:image:height">`);
}
if (image.alt) { if (image.alt) {
res.push(html`<meta content="${image.alt}" property="og:image:alt">`); res.push(html`<meta content="${image.alt}" property="og:image:alt">`);
res.push(html`<meta content="${image.alt}" property="twitter:image:alt">`); res.push(html`<meta content="${image.alt}" property="twitter:image:alt">`);
} }
} }
return res.join('\n').replace(/\n+/g, '\n').replace(/^[ ]+/gm, ''); return res.join('');
}; }