Marty McGuire

Posts Tagged πŸ•ΈοΈπŸ’

2024
Sun Aug 25

πŸ”πŸ•ΈοΈπŸ’ Restored sign-in options for an IndieWeb webring

Are you a member of the πŸ•ΈοΈπŸ’ IndieWeb Webring? Or have you wanted to be, but you couldn't sign in because it strictly required IndieAuth for sign-in?

I was recently gently reminded that the IndieWeb webring at one time allowed you to verify your identity using an alternative sign-in mechanism. For instance, by making bi-directional links between your home page and your GitHub account, you can delegate the step of "proving" that you are the person in control of your homepage to GitHub, and let them worry about storing and checking usernames and passwords.

This concept is called RelMeAuth (because it works by embedding links in your homepage let look like <a rel="me" ... >). The original version of the webring would first check to see if your site specifies its own IndieAuth provider and, if not, would fall back to using Aaron Parecki's indielogin.com, which handles checking for these rel="me" links to supported sites. It also supports sending codes to your email, if you prefer!

So it used to work?

Yeah! I, uh, broke it when I moved the site over to PHP some time ago.

But it works now?

It should! If your homepage has no IndieAuth server specified, but has rel="me" links to your GitHub or an email "mailto:" link, you should be able to sign in to the webring using those methods!

It was broken for how long?

πŸ˜… it was fixed within a day of someone telling me it was broken!

Please don't share any links to code-

Here are the updates I added today to enable indielogin.com support. Some of it is a little hacky until indielogin.com is updated to allow the full client_id URL for the webring, but it works OK!

Sigh, ok.

Okay that's it, for now! Thanks for reading, imaginary interlocutor! As always, feel free to reply to this post on your own site, or feel free to drop me a line in the #indieweb chat (I’m schmarty there)!

Sun Jun 23

πŸ•ΈοΈπŸ‘‰πŸ‘ˆπŸ’ Ordering an IndieWeb webring

Are you a member of the πŸ•ΈοΈπŸ’ IndieWeb Webring? Perhaps one of many who noticed that the "previous" and "next" links were actually going to random active member sites in the ring?

I'm pleased to announce that the "next" and "previous" links between webring member sites should now be, more or less, deterministic! For example, if you visit gRegor's site, scroll to the webring links at the bottom, and click "next", you'll be taken to a site like mine! (at this moment, it is mine!) From my site, if you click the "previous" link, you'll be taken back to gRegor's site! This should m-

Wait, did you say "more or less"?

Well, uh, yeah, good spot. At a high level, the update works like this:

Each active member site gets a pseudo-random "sorting" number. For a given site, the "next" site is the one with the next highest sorting order, and the "previous" is the one with the next lowest.

When you click on a "next" or "previous" webring link from a member site, your browser tells* the webring where you're coming from with a "referrer" header. If the webring recognizes the referer as an active member site, it'll look up the next - or previous - site in the ring to redirect you.

Woah, woah, I see that asterisk

Way to stay sharp! Referrer headers can leak potentially sensitive information, so over time browsers have added ways to restrict how and when referrer headers are sent between sites.

Most of the time, the webring will only see the referring URL up to the first slash after the domain. For folks whose site on the webring has a path component, the webring won't be able to match it against most referrers.

It's also possible that your site is configured to not send referrer headers at all - in that case, the webring has nothing to go on to figure out that the visitor came from your site.

If the webring can't figure out where a visitor came from, they'll just get directed to a random active site.

That feels kinda broken if you ask me

Well, it's no worse than before!

Isn't there a way to improve it?

There is! Or... was. The first version of the webring included unique identifiers in the webring "next" and "previous" links for each member site. These unique IDs would have made it straightforward to figure out where a visitor is coming from.

Oh, don't tell me-

Yeah, I removed that feature last year. πŸ˜…

The emoji-based IDs were hard to manage, added messy unintended meaning, and made it easy to mess up the webring links (or spoof someone else's) when copy-pasting!

You're going to link us to some code, aren't you?

You bet! You can find today's updates to the code here on my git hosting.

Thanks, I guess. So, what's next?

I'm not sure! I feel like this update has the webring in a pretty good place. It's simple enough that I understand it and it works. I might look into some updates for the directory or the site layout, or help surface more information about member sites, like whether they advertise RSS feeds.

Okay that's it, for now! Thanks for reading, imaginary interlocutor! As always, feel free to reply to this post on your own site, or feel free to drop me a line in the #indieweb chat (I’m schmarty there)!

Sat Jun 15

πŸ€–βœ€πŸŒΏ Gardening an IndieWeb webring

Are you a member of the πŸ•ΈοΈπŸ’ IndieWeb Webring? Perhaps one of many who have been confused to discover that member sites are not automatically removed when the webring links disappear from their site?

I'm pleased to announce that the webring will now be self-gardening! Webring member sites th-

Hold on, links to what now?

That-... is actually a good question!

In order for webrings to work, member sites have to link to one another, usually through the webring itself.

When you sign in to the πŸ•ΈοΈπŸ’ IndieWeb Webring, you see this prompt on your dashboard page:

Screenshot of a warning "to stay active, make sure these links are visible on your site", followed by a text area with HTML links to copy and paste.

These links should be copied and pasted into your site so that they appear on the page that matches your webring sign-in. For example, I sign in with my homepage https://martymcgui.re/, so I put my links to the webring on my homepage. They look like this on my site, but you can style them up to look like anything you want.

"An IndieWeb Webring πŸ•ΈοΈπŸ’" text flanked by left and right unicode arrow links.

The basic deal for most webrings is that, in order to receive incoming traffic from other member sites, you need to also display links back to the webring so a visitor can continue on their journey browsing sites from the webring.

If that's the deal, then when a member site goes offline, or removes the webring links from their page, the webring should no longer direct visitors to that site.

The IndieWeb webring tracks whether a site is "Active" or ... "Not Active" (ahem, Inactive). Active sites can receive traffic from webring visitors and, if you choose, appear on the Directory page. Inactive sites... can't do those things.

As the owner of an webring member site, you can sign in to the webring and your Dashboard page will show your site's current "Active" / "Not Active" status and the results of the most recent attempts to check your site for webring links. If you've made changes to your site, there's a "Check links now!" button on the Dashboard to scan for them again.

Okay that's enough background, I think.

Right, thanks. But actually no, there is more.

Initially, Active status on the webring kiiiiind of worked like an honor system. The first time you successfully sign in, your site is added to the webring and set to Active. From that point on, there were only two ways for your site to get marked as Not Active:

  • If you clicked "Check links now!" while your site was offline or didn't have webring links on it.
  • OR if I ran a "gardener" script that checked the webring links for one or more sites.

Since the webring came online in, um, 2018, I've only received a handful of nudges from folks who have been willing to track me down to the IndieWeb chat and complain. That led me to think this honor system was "okay" or "at least not so bad that folks are willing to jump through hoops to bring it to my attention".

That's definitely enough background.

Agreed!

So what's new?

Well, the honor system days are over! Which should be good for all webring member sites, I think.

I've built a little automated gardener that will periodically check member sites for their links. It's designed in a way that trends towards polling member sites about once per month.

For a new member site, it basically works like this: about an hour after you sign up, your site will be checked for links. If they're there, the gardener will check again the next day. It will check again a few days later, then a week, then two weeks.

Finally, as long as the links are there at every check, the gardener will only check once per month.

What happens if the webring links disappear from my site?

If the gardener finds that an Active member site has gone offline or lost the webring links, the site is marked Not Active. It's checked again the next day, then a few days later, then a week and then two.

Finally, the Not Active site will be checked once per month for 3 months. If the site stays Not Active that whole time, the gardener will stop checking and the site owner will need to sign in to re-check links manually if they want the site to become Active again.

What happens if I put the webring links back on my site?

If the gardener finds that a Not Active member site has their webring links back, the site is marked as Active and the schedule resets. The gardener will then check it the next day, then three days later, then a week, then...

Okay, got it!

Woohoo!

Why now, though?

Oh dang, that's a good question.

I've found the energy and space to start working on the webring again, including some possible projects like those I listed in my last update. Before jumping into any of those, though, I want to feel like I can "trust" that the webring is taking care of itself and its visitors. That means not sending folks to sites where the owner changed their mind about being a webring member or, worse, lost sites, and keeping track of active sites on its own!

Can we see the code?

Sure! The bulk of the updates are here on my git hosting. As with most things webring there's a little bit that's well thought out and some attempts at rigor followed by a rush of throwing things together when it appears near working.

I'm open if folks have suggestio-

Wait, I didn't actually want to look at code!

I put some words in your mouth, there, yeah. Sorry. πŸ™ˆ

Okay! That's it for now. As always, feel free to reply to this post on your own site, or feel free to drop me a line in the #indieweb chat (I’m schmarty there).

Sun Jun 9

An absentee webring steward returns

Are you a member of the πŸ•ΈπŸ’ IndieWeb Webring? Everything is fine! We are up to around 450 active sites, with more than 250 of those appearing on the webring directory page!

Okay so what is this update?

Ha! Ha. Reader, you see right through me. Since the last IndieWeb Webring update, an afficionado of IndieWeb, webrings, and PHP who goes by Von Explaino (aka Colin) reached out about collaborating!

He posted about his own updates in Playing with IndieWeb ring's code, and I posted a follow-up with my interest, and he shared his fork of the codebase and posted some ideas for future work. Look at this lovely back and forth discussion between our IndieWeb-powered sites! You love to see it.

That all started in, =ahem=, JULY OF 2023. After a slow email exchange between a patient Colin and a very embarrassed and tired me promising to take a look any day now, I eventually apologized for not having the energy to work on the web ring at that time, and around September we stopped corresponding.

The update is that there's no update?

No! Well, sort of? This weekend I finally made time to reading through Colin's updates and additions, especially focused around the PHPUnit tests that he added for the basic database logic and site fetching and parsing and link-finding code.

The tl;dr is: I've incorporated most of Colin's updates, hooray!

I want to see!

Sure! You can find today's updates to the code here on my git hosting!

I don't want to look at code! Show me what changed for webring members!

Oh! Fair enough. None of today's updates affect how the webring looks or works at this time. It's more like setting up support infrastructure around the way the webring works now to make sure that nothing breaks unintentionally during future updates.

Does that mean changes are coming?

Most likely! But all good stuff, I think. At the top of my list are:

  • Automating the "gardener" that checks whether active member sites have lost (or inactive members have regained!) their webring links.
  • The directory page sure is getting unwieldy with so many profiles on there. It could use some improvements.
  • General design and navigation cleanups.
  • I've seen some interest in having the webring be a "true ring" - with deterministic next / previous links. I'm open to this but I want to keep it simple. (And I'll probably want to shake things up every once in a while!)
  • I've seen some interest in using the active member sites on the webring as a "Who to Follow" for folks who are setting up their feed readers. I don't have it in me to maintain a "planet" feed that contains posts from everybody, but I could probably add some feed discovery so you can see which sites have clearly labeled feeds and maybe let you export an OPML list.
  • Oh! And I keep wonderi-

Okay! Okay.

Right, haha. That's it, for now. As always, feel free to reply to this post on your own site, or feel free to drop me a line in the #indieweb chat (I’m schmarty there).

2023
Sat May 20

Rebooting πŸ•ΈοΈπŸ’ an IndieWeb webring

Are you a member of the πŸ•ΈπŸ’ IndieWeb Webring? Today I swapped out the underlying codebase. Don't worry about it!

Nothing to worry about??

Okay, okay, there are some changes that you might notice!

RIP emoji IDs

I wrote about why I think emoji IDs ended up being a bad idea.

This webring is about personal sites and uses IndieAuth for sign-in. So, I decided to lean into the IndieAuth philosophy "End-Users [...] are all represented by URLs". If your entry on the ring is already identified by your site's URL, there's no need for an extra identifier, emoji or not.

You'll notice this change in a couple of ways:

  • You don't need to put your emojis in your previous/next links to the webring. So, a link to https://xn--sr8hvo.ws//🚭/next can just link to https://xn--sr8hvo.ws/next , no problem. You can update them directly on your site, or visit your webring dashboard to copy-and-paste them again. But! I'll also more-or-less keep supporting URLs with the old emoji IDs, so feel free not to worry about it.
  • Emoji IDs no longer appear on the webring directory. We don't have them, so there's nothing to show! The rest of your profile info should still appear as before.

RIP webring profile pages

One reason I adopted emoji IDs in the first place was to allow profile pages to exist without having to figure out a scheme for encoding your URLs in the webring's URLs. I still don't want to solve that problem! So, the old profile pages at your emoji ID (e.g. https://xn--sr8hvo.ws/🚭) are just not there anymore.

But to be clear: profiles are not gone! They still exist in the webring directory. You can still update or remove your profile via your dashboard page as before!

A new codebase, eh?

The first version of this webring was slapped together over a weekend. It was a proof-of-concept and, honestly, was intended to be a way to experiment with how IndieWeb building blocks might support and extend the idea of a webring. I used the excellent Glitch.com and their NodeJS-based Express template app as a way of "sketching with code", getting something up and running fast, and working in the open where I could invite others to collaborate.

However, I don't work with that stack on a regular basis! So as time went on, and dependencies inevitably churned, I found it harder and harder to come back and make updates quickly.

I've ported the codebase to PHP because I, without citation, feel like a lot of the functionality I was relying on slowly-drifting libraries for in NodeJS is built directly into PHP or implemented via agreed-upon interfaces that shouldn't change out from under me as I apply the inevitable security updates.

Similarly, the IndieAuth stuff for the NodeJS version was really banged-together (by me) and was now out of date with the specification. I had never been that comfortable with my implementation, and moving to PHP where there is a larger set of well-maintained (by other people) IndieWeb building blocks feels like a stabilizing one.

(I'm also using the webring and other IndieWeb projects I maintain to sharpen the tools and smooth the edges on a lil framework for making IndieWeb web apps, shh, keep it on the down-low.)

You can find the new codebase here: https://git.schmarty.net/schmarty/gem-diamond

You can find the old codebase here: https://github.com/martymcguire/indiewebring.ws

Is that all?

It is not! I am hoping this can be a nice solid base for tackling some long-standing issues and requests for improvements.

Can I ask you a different question or give you feedback?

Of course! Please do! You can reply to this post on your own site or via Twitter, or feel free to drop me a line in the #indieweb chat (I’m `schmarty` there).

Wed Apr 26

Bad web dev ideas: emoji as IDs in URLs

It's another rambling web dev post sorry not sorry grab a beverage and let's go.

Begin with the Horrible Admission 🀫😳

Rather than make you wait, here it is:

I created and maintain An IndieWeb Webring and it uses emojis as IDs. When you add your site to the webring by signing in, an emoji ID is created for you, and it acts, in some ways, like your username or profile ID.

For example my webring profile is: πŸ•ΈοΈπŸ’.ws/🚯

Hopefully you see the appeal. The webring is on an emoji domain, which I registered at IndieWeb Summit 2018 inspired by something Doug Beal presented. It was soon decided that I must in fact build a webring there and, leveraging his influence as the originator of the idea, Doug insisted that emojis be used as user IDs. Probably because: moar emojis!

Why even have IDs? πŸ›‚πŸ€·πŸ»β€β™‚οΈ

This is a dang good question and I could probably sleep better if I drop them.

Ring-ness and identifying click sources

At the time, the idea was that a webring should be a ring, with adjacency. In other words, if I click the "next site" link on your website, it should consistently go to the same site. If I click the "previous site" link on their site, it should consistently go back to yours. In order to consistently know which site to send them to next, the webring needs to know where you're coming from.

Historically there has been a way to know where a visitor is coming from: the HTTP "Referer" [sic] header. However, at the time (and in the time since) there have been privacy issues around using this header, and it was not uncommon to see sites sabotage this info with purposeful redirects, browser standards were added to allow degrading or removing referrer info, and Chrome even implemented default policies to degrade it.

So the more reliable thing would be to put some identifier in the URL and trust that webring members wouldn't like weirdly spoof one anothers' unique webring URLs.

Profile pages

Another at the time thought was that webring members might want to "prove" that they were on the webring. An active profile page with rel-me verification linking back to their homepage could allow other sites and tools to say "oh hey! you're a member of this webring". Maybe we could show some stats there! At any rate, none of those use cases ever came into existence as far as I know. (Besides, stats are gross.)

Why not use <xyz> as an ID? πŸ€”πŸ’‘

Some things I considered and discarded:

  • Just use the URL. URLs-appended-to-URLs require escaping and sanitizing and this gets ugly and long.
  • Use a hash of the URL. I like this approach (spoiler alert) but even when they are short hashes are also long and ugly.
  • Use a numeric ID like a database row. This would probably be fine but numeric IDs can be easily crawled (fine for a webring I guess??) and people get weird about low ID numbers sometimes (warning: orange site link). Also they are boring.
  • Something more clever. Well, we probably could have but this was a weekend hack kind of project.

The original sin 🍎🐍

There is a fun little NodeJS library called hash-emoji that takes any-ol-thing and gives you back a string of emojis of the length you ask. Under the hood, it uses a strong SHA256 hash in hexadecimal, parses that hexadecimal number, then uses modulo arithmetic to keep adding "digits" just like any hash algorithm, only the "digits" come from a collection of emojis that were in wide use back in 2017 when the library was created.

I alluded to this in my post about adding a directory to the webring in 2019, but slapping a random emoji or two or three on someone's profile is potentially problematic. When some folks pointed out it was odd that they were assigned a country flag for a place they had never been, I cheekily forked hash-emoji to make hash-emoji-without-borders, which is identical in all ways except I pulled out all flags. Now nobody would get a flag!

However, by removing the flags I had shrunk the key space for the emoji hash. It wasn't great to begin with - using one emoji from the initial set of ~1300 was bound to lead to collisions eventually - but by changing the set I felt like I was increasing the likelihood that some new signup would be assigned the same emoji ID as an already existing site in the ring.

So, I bumped the length of new IDs up to 2. And then, after an unrelated change where I started normalizing URLs differently before creating their hash ID, up to 3.

Let me tell you. 3 emoji almost always tell a story. You can't not see them. Sometimes those stories can be problematic! Or maybe it's nice but you don't find it relatable. Or maybe there is no story, per se, but you're assigned something that you object to being associated with, like weapons or kissing faces or drugs and alcohol or religious symbols, or ...

Some folks also ran into issues with the URLs on their web hosting. While I tend to think of the web as being universally UTF-8, that's not necessarily the case. Some hosts would mangle the Unicode URLs, resulting in the webring not being able to find them, resulting in sites being de-listed from the ring. To make it easy for the widest possible of webring users to simply copy their webring links and paste them into their site, I change it to use the %-encoded versions of the emojis. So now my beautiful πŸ•ΈοΈπŸ’.ws/🚯 has become the horrific: https://xn--sr8hvo.ws/%F0%9F%9A%AF

Instead of worrying too much about any of this I just ... left it alone. A few times I received requests for folks who wanted something custom, and sometimes I obliged as long as it was a request for a unique one- or two-emoji ID, so it couldn't collide with someone's future random ID.

Fooling around, finding out πŸ₯«πŸͺ±

I've been low-key working on porting the webring from its old and crumbling NodeJS implementation to (hear me out) PHP (I SAID HEAR ME OUT). The basic idea is to reduce the number of emails I get from GitHub where dependabot reports a vulnerability in this or that dependency-of-a-dependency, and more importantly to reduce the amount of time that updating those dependencies takes by reducing the amount of breakage that occurs. I guess this is me saying that churn among dependencies for NodeJS apps feels more disruptive to me than I expect churn to be for PHP. Please don't @ me. Any way.

hash-emoji is broken

When porting hash-emoji from Javascript to PHP I had some issues where the modulo and division math wasn't working. Turns out SHA256 digests, which are hex-encoded strings 64-characters in length, make for very large numbers when you represent them as numbers to do number math on them. With basic PHP numeric types this was turning up junk, zeroes for every modulo division.

So I tried out both of the main PHP extensions for arbitrary precision math, GMP and BC Math, and got results that were at least functional. However, they weren't the same as the Javascript hash-emoji implementation.

At least, they weren't the same until I updated my copy of hash-emoji to use BigInt to make sure it was doing its arbitrary precision math properly. It was at this point that Javascript hash-emoji now began consistently outputting the same results as my new PHP implementation.

That means the original hash-emoji algorithm, due to some quirks of Javascript Number math for large numbers, gives results that are not consistent with the same algorithm when using arbitrary precision math types.

With my skills I cannot hope to make a PHP port of hash-emoji that produces identically quirky results to the Javascript version, so, it looks like emoji IDs will have to change again.

Considering the abyss βš«πŸ‘€

I thought that, if the emoji ID generation has to change, maybe I can change it for the better? I brainstormed some ideas in the IndieWeb chat. One nice change would be to bring the emoji set up-to-date to at least Unicode 14 (published 2021, implemented widely during 2022). One major unsolved challenge would be to come up with some "unproblematic" set of emojis. For example, modifiers for skin tone and gender are widely supported, even in complex combinations like people kissing.

Thanks to sknebel some helpful suggestions, like generating IDs without skin tone modifiers and stripping out skin tone modifiers before looking up an ID. This would allow webring users to customize any emoji that have skin tone variants. Maybe that could be expanded to customizing more things when there are variants by gender, or complex combinations like family with two adults and two children, if it should come up. A "customize your ID" tool begins to design itself (lol).

sknebel also pointed me to an excellent resource that the Unicode consortium calls the "best definition of the full set [of emoji]" - the emoji-test.txt file. Here's the Unicode 14 emoji-test.txt file. It encodes each emoji in a line-oriented format, organized helpfully into groups and sub-groups like the ones you see on your favorite emoji keyboard.

I could parse this file out into various datasets annotated with their groupings and sub-groupings. Then, I could use those definitions to pull together any combination of (sub-)groupings that I want into different hash-emoji datasets.

I could expand a "customize your ID" tool to allow folks who don't like their initial ID to opt out of any groups they don't want emojis from. I could treat those groupings as a flag set and map that flag set to an emoji to prepend to their ID, so each combination of groups becomes its own key space. Nice!

Reader, let me tell you: I do not want to do all of that.

End with the other Horrible Admission 🀫😏

As implemented, the webring isn't a true ring. Whether a visitor clicks your custom emoji /next link or your custom emoji /previous link, the webring, in fact, sends you to another active site in the ring at random.

So what's next? I think the webring can function fine without these IDs. The copy-paste webring links can become identical for everyone, and the directory, sign-in, and dashboard pages don't make use of them at all. The one exception is individual profile page URLs for member pages, which I think I can safely drop.

What do you think? Are you horrified by any of this? Enraged? Got an ideas I can try instead? Drop me a reply, I'd love to hear from you!