From b72e4861ebf948b974eaa6e833e582b6dc0c0663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mih=C3=A1ly=20Andr=C3=A1s=20T=C3=B3th?= Date: Wed, 9 Jul 2025 13:49:23 +0200 Subject: [PATCH] helmet added, box real width/height --- README.md | 10 +++++++--- index.js | 51 +++++++++++++++++++++-------------------------- package-lock.json | 10 ++++++++++ package.json | 1 + 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 1011c16..aa48157 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ Az alábbi paraméterekkel szabályozhatod a `/badge` végpont működését: |-------------|----------|-----------------------|----------------------------------------------------------------------------------------|------------------------------| | `icon` | Igen |`simpleicons` | A SimpleIcons ikon neve (kisbetű, kötőjellel). | `github`, `docker`, `nginx` | | `label` | Nem |`Simple Icons` | A badge-en megjelenő szöveg. | `MyApp`, `Status` | -| `bg` | Nem |`#f0f0f0` | Háttérszín (hex vagy CSS színnév). | `#fff`, `#222`, `red` | +| `bgicon` | Nem |`#cccccc` | Icon Háttérszín (hex vagy CSS színnév). | `#fff`, `#222`, `red` | +| `bglabel` | Nem |`#cccccc` | Label Háttérszín (hex vagy CSS színnév). | `#fff`, `#222`, `red` | | `color` | Nem |`#000000` | Szöveg színe (hex vagy CSS színnév). Harmonizál az icon szinével ha nem kérünk külön. | `#333`, `white` | | `size` | Nem |`24` | Ikon (és badge) magassága pixelben. | `16`, `32`, `64` | | `labelpos` | Nem | `right` | Szöveg pozíciója az ikonhoz képest: `right`, `left`, `above`, `below`. | `left`, `above` | @@ -21,8 +22,11 @@ Az alábbi paraméterekkel szabályozhatod a `/badge` végpont működését: - **Alap badge:** `/badge` -- **GitHub ikon, piros háttér, fehér szöveg:** - `/badge?icon=github&bg=red&color=white` +- **React ikon, label, size: 64, font: bold, fehér label szöveg, sárga label háttérszín, piros ikon háttérszín, label jobbra** + `/badge?icon=react&label=React%20expert%20level&size=64&fontweight=bold&color=white&bgicon=red&bglabel=yellow&labelpos=right` + +- **GitHub ikon, piros label háttér, fehér szöveg:** + `/badge?icon=github&bglabel=red&color=white` - **Szöveg balra, ikon jobbra:** `/badge?labelpos=left` diff --git a/index.js b/index.js index 6073eb5..deffd3d 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,13 @@ const express = require('express'); const axios = require('axios'); - +const helmet = require('helmet'); const app = express(); const PORT = process.env.PORT || 3000; +app.use(helmet({ + crossOriginResourcePolicy: false, + })); + app.get('/badge', async (req, res) => { const { icon = 'simpleicons', @@ -17,7 +21,7 @@ app.get('/badge', async (req, res) => { } = req.query; try { - // Ikon letöltése + // download icon SVG from SimpleIcons CDN const iconUrl = `https://cdn.simpleicons.org/${icon}?viewbox=auto&size=${size}`; const iconResponse = await axios.get(iconUrl, { responseType: 'text' }); if (iconResponse.status !== 200) { @@ -25,7 +29,7 @@ app.get('/badge', async (req, res) => { } const iconSVG = iconResponse.data; - // Ha nincs label paraméter, akkor az ikon SVG mezőjét használjuk + // if there is no label query, use the title from the SVG let effectiveLabel = label; if (!req.query.label || req.query.label === 'Simple Icons') { const titleMatch = iconSVG.match(/<title>([^<]+)<\/title>/i); @@ -34,11 +38,11 @@ app.get('/badge', async (req, res) => { } } - // Badge méretek + // Badge size const padding = 10; const iconSize = parseInt(size); - const fontSize = Math.round(iconSize * 0.6); // Font size az ikon méret 60%-a - const textPadding = Math.round(iconSize * 0.4); // Dinamikus: size 40%-a + const fontSize = Math.round(iconSize * 0.6); + const textPadding = Math.round(iconSize * 0.4); const radius = 8; const approxCharWidth = fontSize * 0.6; const textWidth = effectiveLabel.length * approxCharWidth; @@ -58,26 +62,17 @@ app.get('/badge', async (req, res) => { // Ha a color paraméter nincs megadva, próbáljuk kinyerni az ikon színét let effectiveColor = color; if (!req.query.color || req.query.color === '#000000') { - // Próbáljuk kinyerni az ikon fő színét a SimpleIcons API-ból - try { - const iconMetaUrl = `https://cdn.simpleicons.org/${icon}`; - const iconMetaResp = await axios.get(iconMetaUrl, { responseType: 'text' }); - // Kikeressük az első "fill=" attribútumot - const match = iconMetaResp.data.match(/fill="([^"]+)"/); - if (match && match[1]) { - effectiveColor = match[1]; - } else { - effectiveColor = "#222"; // fallback - } - } catch { - effectiveColor = "#222"; + const match = iconSVG.match(/fill="([^"]+)"/); + if (match && match[1]) { + effectiveColor = match[1]; + } else { + effectiveColor = "#222"; // fallback } } - // ÚJ: doboz magasság 5 pixellel nagyobb legyen az ikon méreténél - const boxHeight = iconSize + 5; - const labelBoxHeight = boxHeight; - const totalHeight = Math.max(boxHeight, fontSize + padding * 2); + // doboz magasság 5 pixellel nagyobb legyen az ikon méreténél + const iconSizeAndPadding = iconSize + 5; + const labelRectHeight = fontSize + padding; let width, height, iconGroup, textElem; @@ -94,15 +89,15 @@ app.get('/badge', async (req, res) => { `; } else if (labelpos === 'above' || labelpos === 'below') { // Felső vagy alsó label: ikon doboz magassága = iconSize + 5, szélessége = szöveg doboz szélessége - width = Math.max(iconSize + 5, textWidth); - const labelRectHeight = fontSize + padding; + width = Math.max(iiconSizeAndPadding, textWidth); + const iconRectY = labelpos === 'above' ? labelRectHeight : 0; const labelRectY = labelpos === 'above' ? 0 - : iconSize + 5; - height = iconSize + 5 + textPadding + labelRectHeight; + : iiconSizeAndPadding; + height = iconSizeAndPadding + textPadding + labelRectHeight; // Label háttér const labelRect = `<rect x="0" y="${labelRectY}" width="${width}" height="${labelRectHeight}" rx="${radius}" fill="${bglabel}"/>`; @@ -135,7 +130,7 @@ app.get('/badge', async (req, res) => { // SVG badge string összefűzéssel, szöveg árnyékkal const svg = ` -<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" style="background:none"> +<svg xmlns="http://www.w3.org/2000/svg" width="${(labelpos === 'left' || labelpos === 'right') ? iconBoxWidth + textWidth : width}" height="${(labelpos === 'left' || labelpos === 'right') ? iconBoxHeight : labelRectHeight+iconSize + 5}" style="background:none"> <defs> <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%"> <feDropShadow dx="0" dy="1" stdDeviation="1" flood-color="#000" flood-opacity="0.25"/> diff --git a/package-lock.json b/package-lock.json index d1fdcf9..0e06c99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@svgdotjs/svg.js": "^3.2.4", "axios": "^1.10.0", "express": "^5.1.0", + "helmet": "^8.1.0", "svgdom": "^0.1.21" } }, @@ -595,6 +596,15 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.1.0.tgz", + "integrity": "sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", diff --git a/package.json b/package.json index b577f38..428fc9c 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@svgdotjs/svg.js": "^3.2.4", "axios": "^1.10.0", "express": "^5.1.0", + "helmet": "^8.1.0", "svgdom": "^0.1.21" } }