Kaleidoscope#
a girl doesn't have much knowledge of how to bring all her dreams into reality, but she is overcome by a fey mood and wants to try anyway. she also imposes some challenges on herself to make it more fun :3
Objective: to create a threaded chat website servers for which could be unrolled wherever.
Rules:
- No consulting robber barons and their spawn.
- No automatic code generation of any kind.
- All code should be readable and sufficiently commented.
To run the server:#
- Build the project (
npm run tscwill happily translate all typescript i wrote into javascript ); - obtain an SSL certificate
from your local drug dealerin whichever way you see fit; - tweak server configuration settings in
settings.json(refer to subsequent sections for rundown on that part); - run the project with
node ./server.js.
You can also serve the client on the same IP address. This is turned off by default (the client isn't required for the server to work, you can even delete its package), but can be turned on by flipping the clientRunning flag in settings.json. However, if you do this, you should also compile the client (aka in addition to npm run tsc you should also run npm run esbuild to compile frontend scripts).
Note that as of now clientside authentification does not function in development environment, since ATProto requires localhost applications using its auth to be run off of strictly http://. I might do something about it later. However, the client is fully static and can be hosted with no backend of its own, so you can unroll it on i.e. Nekoweb (like i'm doing).
To host only the client on a static page with no backend, you should:
- compile it with
npm run tsc&npm run esbuildas previously stated; - get all the files in the
clientfolder to where you want to host it; - edit
client-metadata.jsonwith the URL that will host it. In a cohosted server-client environment that's done automatically on first launch, inferring the URL fromsettings.json.
Server settings:#
(all located in settings.json :D)
hostname,port,path: your server will be hosted onhttps://hostname:port/path(orwss://for the websocket). The hostname is the important one to change here, and i don't really recommend touching the path unless you host something else on the same address & port and therefore need a separate endpoint.ipLan: this is the local IP under which the machine hosting the server is known to your router (make sure there's no DHCP shenanigans going on there that could change it. oh and while you're at it don't forget to portforward :D)certificate: as mentioned above, you will need to make a certificate for your server to work (self-signed technically works, but throws cross-origin errors until the user goes out of their way to accept the certificate; therefore it is better to make a regularily signed one, with for example certbot). However your certificate was obtained, you can stuff the files generated by it (public & private keys) under the default locations provided (./util/client-key.pem,./util/client-cert.pem) or in whichever other location, in which case you'd have to update the paths. All paths are resolved against the root directory whereREADME.mdis, the only requirement is that a file be readable to your server process.dbPath: similarily, this is the path where your server will keep the database. It will happily create it on first launch like a good independent sophont, so the default value of./util/database.dbcan be left alone unless you want to move your database somewhere (to an external easily removable drive?)avatar: the URL for the avatar of your server. It can be stored wherever on the internet and it is actually recommended to upload it somewhere instead of hosting it yourself, as clients will need to render your avatar even in case your server goes offline. If you don't think that's likely to happen though, you can drop it in your own server files in/data, as everything within that folder is served by the HTTPS part of the server on the default endpoint (/data/avatar.pngbecomeshttps://url/avatar.png, of which you need the latter). Note that the avatar itself must be a 99×56 "poststamp" image, cause that's what the client will fit it to in a rather procrustean manner :D we looove poststamps in this household!serverName: take a wild guess what this is xDadvancedLogs: this is true by default, but turning it off disables some console messages in case you feel like they're spammy.Epoch: the capital E Epoch will be used for converting timestamps to internal IDs for your server (flow, user and message IDs), and can be provided in whichever format you so desire. Changing it down the road can lead to your messages appearing wildly out of timeline, so it's better not to touch it at all, honestly. If you want to have a bit of fun, may i suggest you instead:EpochOut: same format as Epoch, it is used to dispatch message IDs back into timestamps on the clientside and for nothing else, therefore setting it out of sync with the Epoch can lead to all clientside messags uniformly and harmlessly agreeing on the current date being somewhere in the sixties (yes, it works even beyond the Unix epoch ^^). Honestly no idea why i made this a thing but can be useful for roleplaying maybe?msgMaxLength: the maximum length of the message the server will tolerate. Will be trimmed to 65535 if above that value because that's the hard limit of my database schema.flowNameMaxLength: same for names of flows except the hard limit is 255.clientRunning: as outlined above, this setting turns on and off the hosting of the client from the same web server;admin: if you set your ATProto DID here before turning the server on, you'll be given admin permissions automatically upon first login which i think is quite nice!