Compare commits
No commits in common. "main" and "dev" have entirely different histories.
5 changed files with 28 additions and 100 deletions
|
@ -45,10 +45,7 @@ body {
|
|||
.avatar-status-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
|
||||
width: fit-content;
|
||||
max-width: 700px;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.avatar-wrapper {
|
||||
|
@ -119,48 +116,6 @@ body {
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.user-info-inner {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
gap: .5rem;
|
||||
}
|
||||
|
||||
.user-info-inner h1 {
|
||||
font-size: 2rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.clan-badge {
|
||||
width: 50px;
|
||||
height: 20px;
|
||||
border-radius: 8px;
|
||||
background-color: var(--card-bg);
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.3rem;
|
||||
padding: 0.2rem 0.3rem;
|
||||
}
|
||||
|
||||
.clan-badge img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.clan-badge span {
|
||||
font-size: 1rem;
|
||||
color: var(--text-color);
|
||||
margin: 0;
|
||||
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
margin: 0;
|
||||
|
@ -539,9 +494,7 @@ ul {
|
|||
|
||||
/* readme :p */
|
||||
.readme {
|
||||
max-width: fit-content;
|
||||
min-width: 700px;
|
||||
overflow: hidden;
|
||||
max-width: 700px;
|
||||
width: 100%;
|
||||
background: var(--readme-bg);
|
||||
padding: 1.5rem;
|
||||
|
|
|
@ -49,12 +49,11 @@ export async function getLanyardData(id?: string): Promise<LanyardResponse> {
|
|||
|
||||
export async function handleReadMe(data: LanyardData): Promise<string | null> {
|
||||
const userReadMe: string | null = data.kv?.readme;
|
||||
const validExtension = /\.(md|markdown|txt|html?)$/i;
|
||||
|
||||
if (
|
||||
!userReadMe ||
|
||||
!userReadMe.startsWith("http") ||
|
||||
!validExtension.test(userReadMe)
|
||||
!userReadMe.toLowerCase().endsWith("readme.md") ||
|
||||
!userReadMe.startsWith("http")
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
@ -66,7 +65,15 @@ export async function handleReadMe(data: LanyardData): Promise<string | null> {
|
|||
},
|
||||
});
|
||||
|
||||
if (!res.ok) return null;
|
||||
const contentType: string = res.headers.get("content-type") || "";
|
||||
if (
|
||||
!res.ok ||
|
||||
!(
|
||||
contentType.includes("text/markdown") ||
|
||||
contentType.includes("text/plain")
|
||||
)
|
||||
)
|
||||
return null;
|
||||
|
||||
if (res.headers.has("content-length")) {
|
||||
const size: number = Number.parseInt(
|
||||
|
@ -79,17 +86,9 @@ export async function handleReadMe(data: LanyardData): Promise<string | null> {
|
|||
const text: string = await res.text();
|
||||
if (!text || text.length < 10) return null;
|
||||
|
||||
let html: string;
|
||||
if (
|
||||
userReadMe.toLowerCase().endsWith(".html") ||
|
||||
userReadMe.toLowerCase().endsWith(".htm")
|
||||
) {
|
||||
html = text;
|
||||
} else {
|
||||
html = await marked.parse(text);
|
||||
}
|
||||
|
||||
const html: string | null = await marked.parse(text);
|
||||
const safe: string | null = DOMPurify.sanitize(html);
|
||||
|
||||
return safe;
|
||||
} catch {
|
||||
return null;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { getImageColors } from "@/helpers/colors";
|
||||
import { lanyardConfig } from "@config/environment";
|
||||
import { renderEjsTemplate } from "@helpers/ejs";
|
||||
import { getLanyardData, handleReadMe } from "@helpers/lanyard";
|
||||
|
@ -39,14 +38,6 @@ async function handler(request: ExtendedRequest): Promise<Response> {
|
|||
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 = {
|
||||
title: presence.discord_user.global_name || presence.discord_user.username,
|
||||
username:
|
||||
|
@ -61,9 +52,8 @@ async function handler(request: ExtendedRequest): Promise<Response> {
|
|||
},
|
||||
instance,
|
||||
readme,
|
||||
allowSnow: presence.kv.snow === "true",
|
||||
allowRain: presence.kv.rain === "true",
|
||||
colors: colors?.colors ?? {},
|
||||
allowSnow: presence.kv.snow || false,
|
||||
allowRain: presence.kv.rain || false,
|
||||
};
|
||||
|
||||
return await renderEjsTemplate("index", ejsTemplateData);
|
||||
|
|
|
@ -225,18 +225,17 @@ class ServerHandler {
|
|||
);
|
||||
}
|
||||
|
||||
const headers = request.headers;
|
||||
let ip = server.requestIP(request)?.address;
|
||||
const headers: Headers = response.headers;
|
||||
let ip: string | null = server.requestIP(request)?.address || null;
|
||||
|
||||
if (!ip || ip.startsWith("172.") || ip === "127.0.0.1") {
|
||||
if (!ip) {
|
||||
ip =
|
||||
headers.get("CF-Connecting-IP")?.trim() ||
|
||||
headers.get("X-Real-IP")?.trim() ||
|
||||
headers.get("X-Forwarded-For")?.split(",")[0].trim() ||
|
||||
"unknown";
|
||||
headers.get("CF-Connecting-IP") ||
|
||||
headers.get("X-Real-IP") ||
|
||||
headers.get("X-Forwarded-For") ||
|
||||
null;
|
||||
}
|
||||
|
||||
|
||||
logger.custom(
|
||||
`[${request.method}]`,
|
||||
`(${response.status})`,
|
||||
|
|
|
@ -5,14 +5,9 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<%
|
||||
const displayName = username.endsWith('s') ? `${username}'` : `${username}'s`;
|
||||
const profileUrl = `https://discord.com/users/${user.id}`;
|
||||
%>
|
||||
<meta property="og:title" content="<%= displayName %> Discord Presence">
|
||||
<meta property="og:description" content="<%= activities?.[0]?.state || 'See what ' + displayName + ' is doing on Discord.' %>">
|
||||
<meta property="og:title" content="<%= username %>'s Presence">
|
||||
<meta property="og:image" content="https://cdn.discordapp.com/avatars/<%= user.id %>/<%= user.avatar %>">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta property="og:description" content="<%= activities[0]?.state || 'Discord Presence' %>">
|
||||
|
||||
<title><%= title %></title>
|
||||
|
||||
|
@ -29,7 +24,7 @@
|
|||
<meta name="color-scheme" content="dark">
|
||||
</head>
|
||||
|
||||
<%- include("partial/style.ejs") %>
|
||||
<%- include('partial/style.ejs') %>
|
||||
|
||||
<body>
|
||||
<div class="user-card">
|
||||
|
@ -48,15 +43,7 @@
|
|||
<% } %>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-info-inner">
|
||||
<h1><%= username %></h1>
|
||||
<% if (user.clan) { %>
|
||||
<div class="clan-badge">
|
||||
<img src="https://cdn.discordapp.com/clan-badges/<%= user.clan.identity_guild_id %>/<%= user.clan.badge %>" alt="Clan Badge" class="clan-badge">
|
||||
<span class="clan-name"><%= user.clan.tag %></span>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<h1><%= username %></h1>
|
||||
<% if (activities.length && activities[0].type === 4) {
|
||||
const emoji = activities[0].emoji;
|
||||
const isCustom = emoji?.id;
|
||||
|
|
Loading…
Add table
Reference in a new issue