update to allow html readme, fx id page for colors
All checks were successful
Code quality checks / biome (push) Successful in 11s

This commit is contained in:
creations 2025-04-17 18:26:59 -04:00
parent 7f9f166f8a
commit 23f37beef3
Signed by: creations
GPG key ID: 8F553AA4320FC711
4 changed files with 30 additions and 17 deletions

View file

@ -494,7 +494,9 @@ ul {
/* readme :p */ /* readme :p */
.readme { .readme {
max-width: 700px; max-width: fit-content;
min-width: 700px;
overflow: hidden;
width: 100%; width: 100%;
background: var(--readme-bg); background: var(--readme-bg);
padding: 1.5rem; padding: 1.5rem;

View file

@ -49,11 +49,12 @@ export async function getLanyardData(id?: string): Promise<LanyardResponse> {
export async function handleReadMe(data: LanyardData): Promise<string | null> { export async function handleReadMe(data: LanyardData): Promise<string | null> {
const userReadMe: string | null = data.kv?.readme; const userReadMe: string | null = data.kv?.readme;
const validExtension = /\.(md|markdown|txt|html?)$/i;
if ( if (
!userReadMe || !userReadMe ||
!userReadMe.toLowerCase().endsWith("readme.md") || !userReadMe.startsWith("http") ||
!userReadMe.startsWith("http") !validExtension.test(userReadMe)
) { ) {
return null; return null;
} }
@ -65,15 +66,7 @@ export async function handleReadMe(data: LanyardData): Promise<string | null> {
}, },
}); });
const contentType: string = res.headers.get("content-type") || ""; if (!res.ok) return null;
if (
!res.ok ||
!(
contentType.includes("text/markdown") ||
contentType.includes("text/plain")
)
)
return null;
if (res.headers.has("content-length")) { if (res.headers.has("content-length")) {
const size: number = Number.parseInt( const size: number = Number.parseInt(
@ -86,9 +79,17 @@ export async function handleReadMe(data: LanyardData): Promise<string | null> {
const text: string = await res.text(); const text: string = await res.text();
if (!text || text.length < 10) return null; if (!text || text.length < 10) return null;
const html: string | null = await marked.parse(text); let html: string;
const safe: string | null = DOMPurify.sanitize(html); if (
userReadMe.toLowerCase().endsWith(".html") ||
userReadMe.toLowerCase().endsWith(".htm")
) {
html = text;
} else {
html = await marked.parse(text);
}
const safe: string | null = DOMPurify.sanitize(html);
return safe; return safe;
} catch { } catch {
return null; return null;

View file

@ -1,3 +1,4 @@
import { getImageColors } from "@/helpers/colors";
import { lanyardConfig } from "@config/environment"; import { lanyardConfig } from "@config/environment";
import { renderEjsTemplate } from "@helpers/ejs"; import { renderEjsTemplate } from "@helpers/ejs";
import { getLanyardData, handleReadMe } from "@helpers/lanyard"; import { getLanyardData, handleReadMe } from "@helpers/lanyard";
@ -38,6 +39,14 @@ async function handler(request: ExtendedRequest): Promise<Response> {
status = presence.discord_status; status = presence.discord_status;
} }
let colors: ImageColorResult | null = null;
if (presence.kv.colors === "true") {
const avatar: string = presence.discord_user.avatar
? `https://cdn.discordapp.com/avatars/${presence.discord_user.id}/${presence.discord_user.avatar}`
: `https://cdn.discordapp.com/embed/avatars/${presence.discord_user.discriminator || 1 % 5}`;
colors = await getImageColors(avatar, true);
}
const ejsTemplateData: EjsTemplateData = { const ejsTemplateData: EjsTemplateData = {
title: presence.discord_user.global_name || presence.discord_user.username, title: presence.discord_user.global_name || presence.discord_user.username,
username: username:
@ -52,8 +61,9 @@ async function handler(request: ExtendedRequest): Promise<Response> {
}, },
instance, instance,
readme, readme,
allowSnow: presence.kv.snow || false, allowSnow: presence.kv.snow === "true",
allowRain: presence.kv.rain || false, allowRain: presence.kv.rain === "true",
colors: colors?.colors ?? {},
}; };
return await renderEjsTemplate("index", ejsTemplateData); return await renderEjsTemplate("index", ejsTemplateData);

View file

@ -24,7 +24,7 @@
<meta name="color-scheme" content="dark"> <meta name="color-scheme" content="dark">
</head> </head>
<%- include('partial/style.ejs') %> <%- include("partial/style.ejs") %>
<body> <body>
<div class="user-card"> <div class="user-card">