Back to the overview

Weeknotes (2023 week 11 and 12)

Mail user agents being mail user agents

django-authlib is my collection of utilities for implementing passwordless authentication, either using OAuth2 or by sending magic links by email.

The latter functionality has existed for a long time in django-registration (which is great!) but I wanted a way to generate links without the need for a storage somewhere. Django has utilities for Cryptographic signing built-in as the django.core.signing module. I’m using this module to send a signed version of the email address to users, and when I’m able to successfully verify the email addresses signature I can be sure (enough) that those links have actually been generated by my code.

The form of the generated verification URL is as follows: https://example.com/.../test@example.com:1pXJtx:aypKOlb5zaCg.../; the part before the first colon contains the data-to-be-verified, the short string between colons is the timestamp and the rest is the signature, everything generated by django.core.signing.

So far so boring.

But then mail user agents happened. Some MUAs insist to butcher the URL in various ways, e.g. by removing the signature or by making only the embedded email address clickable. This is “interesting” behavior and certainly unexpected.

Last week I implemented a change where I’m now also base64 encoding the email address itself. So, the URL is even longer and even more opaque now but it seems to work well. I also added a HTML version of the mail to hopefully prevent mail programs from creating their own worse version. I could have done that a long time ago but I really like text/plain mails so I did hold off on that as long as I could. Oh well.

feincms3-data and unique fields

I did a longer post on feincms3-data some time ago which explains what it is for.

A recurring problem was dumping and loading data in the presence of unique constraints. For example, website managers deleted data with a specific (unique) slug and created new data with the same slug. feincms3-data and also Django itself were unable to handle this. The former because it loads new data before deleting old data, the latter because it doesn’t even have a concept of data which should be deleted.

feincms3-data now has an ugly workaround for this problem: It generates random data for a list of explicitly specified fields (which is very unlikely to cause collisions) and only updates the records with the correct data after the cleanup step. The code wasn’t that hairy to write and I was again very happy that unittesting is a thing.

ProseMirror hacking

I’m back to hacking on ProseMirror plugins. I still feel really well about picking it as a basis for all those use cases when using the venerable CKEditor 4 isn’t a good fit.

I did like the fact a lot that ProseMirror was written in JavaScript. Now that it has been rewritten in TypeScript I’m reevaluating my resistance against TypeScript, but I just don’t know if it’s worth it. Why write down all those annotations when the code also works without? I still don’t really see the point. Yes I know, catching bugs early and all that. But still.