diff --git a/scripts/smoke-production.mjs b/scripts/smoke-production.mjs
index 909f339..4138cdc 100644
--- a/scripts/smoke-production.mjs
+++ b/scripts/smoke-production.mjs
@@ -4,6 +4,21 @@ import { pathToFileURL } from 'node:url';
const sha256Pattern = /^[a-f0-9]{64}$/u;
const privateIdentifiers = /(?:simpastil|simpasteel|neon[ -]?debugger|yourhealth)/iu;
const sourceMapReference = /(?:sourceMappingURL\s*=|["'(]\/?[^"')\s]+\.map(?:[?"')\s]|$))/iu;
+const publicMetadata = Object.freeze({
+ name: 'Luca Pîslaru',
+ role: 'System Administrator & Full-Stack Developer',
+ title: 'Luca Pîslaru — System Administrator & Full-Stack Developer',
+ description: 'Portfolio of Luca Pîslaru, a Bucharest-based System Administrator and Full-Stack Developer working across Linux infrastructure and end-to-end software delivery.',
+ email: 'mailto:luca.pislaru@gmail.com',
+ sameAs: Object.freeze([
+ 'https://github.com/LucaPisl',
+ 'https://gitlab.com/luca_pisl',
+ 'https://linkedin.com/in/luca-pisl',
+ ]),
+ location: Object.freeze({ city: 'Bucharest', countryCode: 'RO' }),
+ socialImagePath: '/assets/project-social-preview.webp',
+ socialImageType: 'image/webp',
+});
function rootHttpsUrl(value, label) {
let url;
@@ -65,19 +80,63 @@ function exactTagContent(html, expression, label) {
return decodedText(values[0]);
}
+function exactObjectKeys(value, expectedKeys, label) {
+ if (typeof value !== 'object' || value === null || Array.isArray(value) ||
+ JSON.stringify(Object.keys(value).sort()) !== JSON.stringify([...expectedKeys].sort())) {
+ throw new Error(`${label} has missing or forbidden fields.`);
+ }
+}
+
function verifyMetadata(html, canonicalUrl) {
- const canonical = exactTagContent(html, /]*\brel=["']canonical["'])[^>]*\bhref=["']([^"']+)["'][^>]*>/giu, 'canonical link');
- const ogUrl = exactTagContent(html, /]*\bproperty=["']og:url["'])[^>]*\bcontent=["']([^"']+)["'][^>]*>/giu, 'og:url');
- const robots = exactTagContent(html, /]*\bname=["']robots["'])[^>]*\bcontent=["']([^"']+)["'][^>]*>/giu, 'robots meta');
- exactTagContent(html, /]*\bname=["']description["'])[^>]*\bcontent=["']([^"']+)["'][^>]*>/giu, 'description meta');
- exactTagContent(html, /]*\bproperty=["']og:title["'])[^>]*\bcontent=["']([^"']+)["'][^>]*>/giu, 'og:title');
- exactTagContent(html, /]*\bproperty=["']og:description["'])[^>]*\bcontent=["']([^"']+)["'][^>]*>/giu, 'og:description');
- if (canonical !== canonicalUrl || ogUrl !== canonicalUrl || !/^index\s*,\s*follow$/iu.test(robots)) throw new Error('Canonical, Open Graph, or robots metadata is inconsistent.');
+ const title = exactTagContent(html, /
]*>([\s\S]*?)<\/title>/giu, 'title');
+ const canonicalLink = exactTagContent(html, /]*\brel=["']canonical["'])(?=[^>]*\bhref=["']([^"']+)["'])[^>]*>/giu, 'canonical link');
+ const description = exactTagContent(html, /]*\bname=["']description["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'description meta');
+ const robots = exactTagContent(html, /]*\bname=["']robots["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'robots meta');
+ const ogType = exactTagContent(html, /]*\bproperty=["']og:type["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'og:type');
+ const ogTitle = exactTagContent(html, /]*\bproperty=["']og:title["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'og:title');
+ const ogDescription = exactTagContent(html, /]*\bproperty=["']og:description["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'og:description');
+ const ogUrl = exactTagContent(html, /]*\bproperty=["']og:url["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'og:url');
+ const ogImage = exactTagContent(html, /]*\bproperty=["']og:image["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'og:image');
+ const twitterCard = exactTagContent(html, /]*\bname=["']twitter:card["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'twitter:card');
+ const twitterTitle = exactTagContent(html, /]*\bname=["']twitter:title["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'twitter:title');
+ const twitterDescription = exactTagContent(html, /]*\bname=["']twitter:description["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'twitter:description');
+ const twitterImage = exactTagContent(html, /]*\bname=["']twitter:image["'])(?=[^>]*\bcontent=["']([^"']+)["'])[^>]*>/giu, 'twitter:image');
+ if (title !== publicMetadata.title || description !== publicMetadata.description ||
+ canonicalLink !== canonicalUrl || !/^index\s*,\s*follow$/iu.test(robots) ||
+ ogType !== 'profile' || ogTitle !== title || ogDescription !== description || ogUrl !== canonicalLink ||
+ twitterCard !== 'summary_large_image' || twitterTitle !== title || twitterDescription !== description ||
+ twitterImage !== ogImage) {
+ throw new Error('Canonical, title, description, Open Graph, Twitter, or robots metadata is inconsistent.');
+ }
+ let socialImage;
+ try { socialImage = new URL(ogImage); } catch { throw new Error('Social image URL is invalid.'); }
+ const canonicalOrigin = new URL(canonicalUrl);
+ if (socialImage.origin !== canonicalOrigin.origin || socialImage.username || socialImage.password || socialImage.port ||
+ socialImage.pathname !== publicMetadata.socialImagePath || socialImage.search || socialImage.hash) {
+ throw new Error('Social image must use the expected path on the canonical host.');
+ }
const jsonLdText = exactTagContent(html, /