The Wiki Weekend Part 4: Users, Locking

Back to HTML WARDen.
-
The Wiki Weekend Part 1: Motivation and Other Wikis
-
The Wiki Weekend Part 2: The Page Editor Idea
-
The Wiki Weekend Part 3: The Storage
-
The Wiki Weekend Part 4
You are here
-
The Wiki Weekend Part 5: Finishing Touches, Conclusion
I seriously considered having just one login or no login at all and using HTTP’s Basic Authentication (wikipedia.org) to protect pages.
But experience has shown me that it’s a really bad idea to have a shared resource with no concept of user management. Even when sharing with friends and family.
Cookie-based login
Again, I had recently solved some of this stuff for my little Famsite project, so I took the login system from that.
Except Famsite used a database. So it was even simpler (or sillier) for HTML WARDen.
Here’s user management in settings.php
:
$GLOBALS['wiki_logins'] = [ '1234'=>'Guest', ];
Yup, just a static array. What’s funny is that it’s much faster to just edit the settings file than open SQLite and write the SQL command to update a user account (plus I’m probably going to screw it up at least once before I get it right). So this is just faster all around.
In this system, users don’t type their usernames. Instead, the "password" is more of a key, a long chunk of random characters (I just generate them from the hash of garbage text).
You give somebody a "login link" that looks like this:
https://example.com/wiki/login.php?login=1234
And that would log you in as "Guest" in the example configuration above.
That’s it.
Arguably, POSTing the login code is more secure because it won’t be saved in the browser history. That’s why I have a login form in the Famsite where you paste your code instead of using a login URL.
I didn’t feel like I needed it for this wiki. We’re going extreme minimalism with this one.
Anyway, after you’re logged in, I set a cookie that lasts a very long time. Now you can just go to the wiki with that browser any time you want and you’ll still be logged in. No fuss.
I think it’s secure enough, but maybe don’t build your banking software on top of this?
Page locking
As soon as I made accounts for my kids, I knew I needed to create per-page/per-user locking or I would be responsible for "accidents" and sadness.
As mentioned in part 3, I still needed some way to store metadata about pages.
Here’s what I settled on. When you click the Lock button, it inserts the following snippet of HTML at the bottom of the page:
<b id="page_lock" data-by="<?=$GLOBALS['user_name']?>">🔒</b>
It shows up at the bottom of the page as a Unicode lock symbol. I could have made it invisible instead, but I think the visual is useful when you’re viewing the page.

Also, I'm probably just easily amused, but I get a kick out of the fact that this thing that looks like a lock at the bottom of the page is actually the thing that is locking the page!
Because, again, as I mentioned in Part 3, HTML is structured data and the browser is made to handle it, I find out if the page has a lock like this:
var page_lock = document.getElementById('page_lock');
If it is, I simply remove the "Save" button entirely and replace it with a message explaining the page is locked, and by whom:
var page_lock = document.getElementById('page_lock'); if(page_lock){ var lock_by = page_lock.dataset.by; if(lock_by !== '<?=$GLOBALS['user_name']?>'){ myform.action = '#'; tool_save.outerHTML = '<b>This page is locked by ' + lock_by + '</b>'; } }
That’s it, that’s the whole locking feature.
It would be trivial for anyone tech-savvy to bypass and yet completely effective at keeping your non-malicious friends and family from "accidentally" messing with each other’s pages.
Again, if you need to store state secrets, this may not be the wiki for you.
(Update: A week later, I ended up
scrapping the WYSIWYG editor and (temporarily?)
removed the page locking feature in an
effort to simplify the wiki before complicating
it.
To get a copy of HTML WARDen as described on this
page, clone the
repo
and checkout commit
801ab2cd0839fc150061fccc1f71ee1e360cf3eb
.)
Title also stored in HTML
While we’re on the subject of metadata…
I thought about storing the dates of page creation/updating, but I don’t need that for this use-case. I’m not even storing the username of the person who did the editing! I could always add those things later.
But I do need to store a page title and it can’t be in the <title>
tag because
these pages are just the body, not the whole HTML document.
Initially, I had a separate text field for editing the title. But as I was
rendering it with an <h1>
tag it on the "rich text" side, I realized how
silly I was being. Why not just have an <h1>
in the source and edit the
darn thing visually or in the raw HTML like everything else?
So that’s what I did. Now the title of the page is just whatever appears in the
<h1>
tag in the page source.
I grab that with JavaScript when displaying the page and put it in the window title:
var tt = document.querySelector('h1'); if(tt){ document.title = tt.textContent; }
(If I needed to render complete static HTML pages (discussed in Part 5),
I would need to parse the <h1>
with PHP. There’s a module for that or I could
just do a naughty thing with a regular expression.)
So that’s it, everything’s just stored in the document itself.
Onward, to The Wiki Weekend Part 5: Finishing Touches, Conclusion!