Cookie Consent by Free Privacy Policy Generator ๐Ÿ“Œ Adding client-side rendered webmentions to my blog

๐Ÿ  Team IT Security News

TSecurity.de ist eine Online-Plattform, die sich auf die Bereitstellung von Informationen,alle 15 Minuten neuste Nachrichten, Bildungsressourcen und Dienstleistungen rund um das Thema IT-Sicherheit spezialisiert hat.
Ob es sich um aktuelle Nachrichten, Fachartikel, Blogbeitrรคge, Webinare, Tutorials, oder Tipps & Tricks handelt, TSecurity.de bietet seinen Nutzern einen umfassenden รœberblick รผber die wichtigsten Aspekte der IT-Sicherheit in einer sich stรคndig verรคndernden digitalen Welt.

16.12.2023 - TIP: Wer den Cookie Consent Banner akzeptiert, kann z.B. von Englisch nach Deutsch รผbersetzen, erst Englisch auswรคhlen dann wieder Deutsch!

Google Android Playstore Download Button fรผr Team IT Security



๐Ÿ“š Adding client-side rendered webmentions to my blog


๐Ÿ’ก Newskategorie: Programmierung
๐Ÿ”— Quelle: dev.to

My blog is currently hosted on weblog.lol which allows for a simple and configurable weblog managed in git with posts formatted in markdown. I wanted to add webmentions to my blog which, as of now, doesn't include a build step. To accomplish this, I've added an intermediary api endpoint to the same next.js app that powers my /now page.

Robb has a handy write up on adding webmentions to your website, which I followed โ€” first adding the appropriate Mastodon link to my blog template, registering for webmentions.up and Bridgy, then adding the appropriate tags to my template document's <head> to record mentions.

Next it was simply a question of rendering the output from the webmentions endpoint.

My next.js api looks like this:

export default async function handler(req: any, res: any) {
    const KEY_CORYD = process.env.API_KEY_WEBMENTIONS_CORYD_DEV
    const KEY_BLOG = process.env.API_KEY_WEBMENTIONS_BLOG_CORYD_DEV
    const DOMAIN = req.query.domain;
    const TARGET = req.query.target;
    const data = await fetch(`https://webmention.io/api/mentions.jf2?token=${DOMAIN === 'coryd.dev' ? KEY_CORYD : KEY_BLOG}${TARGET ? `&target=${TARGET}` : ''}&per-page=1000`).then((response) => response.json())
    res.json(data)
}

I have a pair of keys depending on the mentioned and provides domain, though this is only used on my blog at present. I also support passing through the target parameter but don't leverage it at the moment.

This is called on the client side as follows:

document.addEventListener('DOMContentLoaded', (event) => {
    ;(function () {
        const formatDate = (date) => {
            var d = new Date(date),
                month = '' + (d.getMonth() + 1),
                day = '' + d.getDate(),
                year = d.getFullYear();

            if (month.length < 2)
                month = '0' + month;
            if (day.length < 2)
                day = '0' + day;

            return [month, day, year].join('-');
        };
        const webmentionsWrapper = document.getElementById('webmentions');
        const webmentionsLikesWrapper = document.getElementById('webmentions-likes-wrapper');
        const webmentionsBoostsWrapper = document.getElementById('webmentions-boosts-wrapper');
        const webmentionsCommentsWrapper = document.getElementById('webmentions-comments-wrapper');
        if (webmentionsWrapper && window) {
            try {
                fetch('https://utils.coryd.dev/api/webmentions?domain=blog.coryd.dev').then((response) => response.json()).then(data => {
                    const mentions = data.children;
                    if (mentions.length === 0 || window.location.pathname === '/') {
                        webmentionsWrapper.remove();
                        return;
                    }

                    let likes = '';
                    let boosts = '';
                    let comments = '';

                    mentions.map(mention => {
                        if (mention['wm-property'] === 'like-of' && mention['wm-target'].includes(window.location.href)) {
                            likes += `<a href="${mention.url}" rel="noopener noreferrer"><img class="avatar" src="${mention.author.photo}" alt="${mention.author.name}" /></a>`
                        }

                        if (mention['wm-property'] === 'repost-of' && mention['wm-target'].includes(window.location.href)) {
                            boosts += `<a href="${mention.url}" rel="noopener noreferrer"><img class="avatar" src="${mention.author.photo}" alt="${mention.author.name}" /></a>`
                        }

                        if (mention['wm-property'] === 'in-reply-to' && mention['wm-target'].includes(window.location.href)) {
                            comments += `<div class="webmention-comment"><a href="${mention.url}" rel="noopener noreferrer"><div class="webmention-comment-top"><img class="avatar" src="${mention.author.photo}" alt="${mention.author.name}" /><div class="time">${formatDate(mention.published)}</div></div><div class="comment-body">${mention.content.text}</div></a></div>`
                        }
                    });

                    webmentionsLikesWrapper.innerHTML = '';
                    webmentionsLikesWrapper.insertAdjacentHTML('beforeEnd', likes);
                    webmentionsBoostsWrapper.innerHTML = '';
                    webmentionsBoostsWrapper.insertAdjacentHTML('beforeEnd', boosts);
                    webmentionsCommentsWrapper.innerHTML = '';
                    webmentionsCommentsWrapper.insertAdjacentHTML('beforeEnd', comments);
                    webmentionsWrapper.style.opacity = 1;

                    if (likes === '') document.getElementById('webmentions-likes').innerHTML === '';
                    if (boosts === '') document.getElementById('webmentions-boosts').innerHTML === '';
                    if (comments === '') document.getElementById('webmentions-comments').innerHTML === '';

                    if (likes === '' && boosts === '' && comments === '') webmentionsWrapper.remove();
                });
            } catch (e) {
                webmentionsWrapper.remove();
            }
        }
    })();
});

This JavaScript is all quite imperative โ€” it verifies the existence of the appropriate DOM nodes, concatenates templated HTML strings and then injects them into the targeted DOM elements. If there aren't mentions of a supported type, the container node is removed. If there are no mentions, the whole node is removed.

The webmentions HTML shell is as follows:

<div id="webmentions" class="container background-purple">
    <div id="webmentions-likes">
        <h2><i class="fa-solid fa-fw fa-star"></i> Likes</h2>
        <div id="webmentions-likes-wrapper"></div>
    </div>
    <div id="webmentions-boosts">

        <h2><i class="fa-solid fa-fw fa-rocket"></i> Boosts</h2>
        <div id="webmentions-boosts-wrapper"></div>
    </div>
    <div id="webmentions-comments">
        <h2><i class="fa-solid fa-fw fa-comment"></i> Comments</h2>
        <div id="webmentions-comments-wrapper"></div>
    </div>
</div>

And there you have it โ€” webmentions loaded client side and updated as they occur. There's an example visible on my post Automating (and probably overengineering) my /now page.

...



๐Ÿ“Œ CVE-2017-20174 | bastianallgeier Kirby Webmentions Plugin injection


๐Ÿ“ˆ 35.58 Punkte

๐Ÿ“Œ How to Install Winscp FTP Client/SFTP Client/SCP Client (WinSCP Client) In Ubuntu


๐Ÿ“ˆ 28.57 Punkte

๐Ÿ“Œ Headless email client which outputs the rendered version


๐Ÿ“ˆ 25.9 Punkte

๐Ÿ“Œ Adding comments to my Astro blog with PlanetScale & Prisma on Vercel Edge


๐Ÿ“ˆ 22.11 Punkte

๐Ÿ“Œ Blog: Adding complex Firestore queries to a Jetpack Compose app


๐Ÿ“ˆ 22.11 Punkte

๐Ÿ“Œ ABT Blog v2.0 Blog Scripti Disclosure Exploit


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ BP Blog v10.0 Blog Scripti Database Disclosure Exploit


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ CentOS Seven blog: Seven.centos.org is dead .. long life to blog.centos.org !


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ Mooseguy Blog System MGBS 1.0 blog.php month sql injection


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ A-Blog 2 blog.php id sql injection


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ Leif M. Wright Web Blog 1.1 blog.cgi file privilege escalation


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ Blog about what you do! | Sam Thursfield's Blog


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ Croogo up to 3.0.5 Blog Field blog cross site scripting


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ Medium CVE-2020-21179: Koa2-blog project Koa2-blog


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ Medium CVE-2020-21180: Koa2-blog project Koa2-blog


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ How to change Primary Blog & Blog Name on Tumblr


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ How to change Primary Blog and Blog Name on Tumblr


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ CVE-2022-2740 | SourceCodester Company Website CMS Add Blog /dashboard/add-blog.php ufile unrestricted upload


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ CVE-2023-29639 | zhenfeng13 My-Blog Blog Article Page cross site scripting (Issue 131)


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ CVE-2023-29636 | zhenfeng13 My-Blog Blog Management Page title cross site scripting (Issue 131)


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ CVE-2019-17535 | Gila CMS up to 1.11.4 Blog Theme/Mag Theme blog-list.php search cross site scripting


๐Ÿ“ˆ 19.45 Punkte

๐Ÿ“Œ A fully interactive, real-time, and modern text-based browser rendered to TTYs and browsers.


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Patch blues-day: Microsoft yanks code after some PCs are rendered super secure (and unbootable) following update


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Ask Slashdot: Why Are 3D Games, VR/AR Still Rendered Using Polygons In 2019?


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ As Linux is in violation of GPL, would it mean if GNU pulls the plug, any derivative work would be rendered license-less?


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Vimยณ - Vim rendered on a cube for no reason


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ IBM API Connect up to V2018.4.1.10 improper restriction of rendered ui layers


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ HCL AppScan Enterprise API Documentation improper restriction of rendered ui layers


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Microsoft Edge jetzt mit Pre-Rendered Tabs fรผr Linux


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Mozilla Firefox up to 81.x External Protocol improper restriction of rendered ui layers


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Google Chrome prior 86.0.4240.75 on ChromeOS webUI improper restriction of rendered ui layers


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ IBM App Connect Enterprise Certified Container 1.0.0/1.0.1/1.0.2/1.0.3/1.0.4 improper restriction of rendered ui layers


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Fujitsu Eternus Storage DX200 S4 cgi-bin/csp improper restriction of rendered ui layers


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Mozilla Firefox up to 82.x on Android Fullscreen improper restriction of rendered ui layers


๐Ÿ“ˆ 18.76 Punkte

๐Ÿ“Œ Mozilla Firefox/Thunderbird Fullscreen improper restriction of rendered ui layers


๐Ÿ“ˆ 18.76 Punkte











matomo