コミットグラフ

271 コミット

作成者 SHA1 メッセージ 日付
n9k 45965fc1db Forgot some licence headers 2022-06-24 03:31:01 +00:00
n9k abf7574ea9 v1.3.1 2022-06-23 03:48:13 +00:00
n9k 2a16f6a835 Debug: print colorized tag/token_hash/token 2022-06-23 03:36:37 +00:00
n9k 3bb2a81c5a Bypass initial chat captcha if solved access captcha 2022-06-23 02:53:41 +00:00
n9k 45224e0779 Never gonna give broadcaster a captcha 2022-06-23 02:36:44 +00:00
n9k 77e0183c15 v1.3.0 2022-06-22 08:58:40 +00:00
n9k c3237890ad Rule out edge case where MAX_CAPTCHAS is 0 2022-06-22 08:41:46 +00:00
n9k 95a940a14f Limit number of stored failures
Failures are messages shown on the access captcha screen when the
captcha answer was not accepted for whatever reason.
2022-06-22 08:35:41 +00:00
n9k 6046598ed8 Fix deletion of old messages exceeding threshold 2022-06-22 08:34:16 +00:00
n9k 4a76fb023e Access captcha: special case for websocket
There doesn't seem to be a way to catch a 403 Forbidden error opening a
websocket with JavaScript, so this commit changes the behaviour to this:
open the websocket normally, send one "kick" message, close the
websocket.
2022-06-22 08:11:12 +00:00
n9k 0548065b1d Error pages: custom descriptions 2022-06-22 08:11:12 +00:00
n9k 35ce606d64 Custom error pages 2022-06-22 08:11:12 +00:00
n9k 9143acafd1 Access captcha 2022-06-22 08:11:12 +00:00
n9k 4c5faf7dba Use 303 See Other for {POST|GET}->GET redirects 2022-06-22 04:54:02 +00:00
n9k 6ae87be229 anonstream/__main__.py: disable Server header 2022-06-21 06:23:24 +00:00
n9k a41f0d4f14 Escape disallowed cookie characters 2022-06-20 04:15:09 +00:00
n9k 46f9b0ec08 Reset websocket aliveness timer on first connecting
This should eliminate the possibilty of the websocket-closing background
task closing a newly opened websocket that hasn't yet ponged our ping
(if we have even sent a ping yet).
2022-06-20 04:15:09 +00:00
n9k 22c84bc230 Give timestamp to route handlers 2022-06-20 04:15:09 +00:00
n9k 90e1e2099a Manual static folder 2022-06-20 04:15:08 +00:00
n9k 1581e6ac89 Minor logic formatting 2022-06-19 08:21:40 +00:00
n9k 1d5b446291 Track the last time users were sent chat messages 2022-06-19 08:21:40 +00:00
n9k 0b78a79111 Use single quotes 2022-06-19 07:53:31 +00:00
n9k 893c4273b0 Licence headers formatting for real 2022-06-17 01:10:27 +00:00
n9k fc4a528b04 anonstream/__main__.py: tidy magic numbers for real 2022-06-17 00:48:04 +00:00
n9k 1ce4b4f568 v1.2.3 2022-06-17 00:41:20 +00:00
n9k 56ee52699a Nojs chat form: on failure truncate long comments 2022-06-17 00:40:38 +00:00
n9k e147aa0d22 Chat: always enforce length limits from config 2022-06-17 00:40:02 +00:00
n9k 3c5d3af40d Typo: comment max length was name max length instead 2022-06-17 00:40:02 +00:00
n9k 88d3785ec6 Rename config section from 'thresholds' to 'presence' 2022-06-17 00:40:02 +00:00
n9k dc5c4db3de Move nojs refresh magic numbers to config 2022-06-17 00:40:02 +00:00
n9k febb0e36d3 v1.2.2 2022-06-16 03:19:13 +00:00
n9k 617a687145 Give `create_app` a dictionary, not a file location 2022-06-16 03:15:21 +00:00
n9k 0e7bb62291 anonstream/__main__.py: tidy magic numbers 2022-06-16 03:14:46 +00:00
n9k 6746f7b859 Simplify starting: create anonstream/__main__.py 2022-06-16 02:56:38 +00:00
n9k fdf4713c71 Licence headers in every new file 2022-06-16 01:31:10 +00:00
n9k 1c7818cc0b Licence headers formatting 2022-06-16 01:31:10 +00:00
n9k 309b2ad54f Control socket: minor redo exceptions 2022-06-16 01:05:18 +00:00
n9k c07910b6c5 v1.2.1 2022-06-15 21:19:21 +00:00
n9k 50d03ba8d5 Control socket: specify users by token hash 2022-06-15 21:17:25 +00:00
n9k f3e58fd3fa Refactor info update background task
We now time the interval between consecutive tasks. This is more precise
than using the constant interval the task is supposed to run at since
there is some drift on each run (~0.004s).
2022-06-15 21:03:08 +00:00
n9k e449caff5f Reimplement `with_timestamp`, allow ints & floats 2022-06-15 20:54:55 +00:00
n9k 1f56e635b9 Ensure chat stays at bottom if names/tripcodes change 2022-06-15 20:39:06 +00:00
n9k 55a713991c Nojs info: fix invisible uptime counter taking up space
Also adds "visibility: hidden;" to `disappear`. It would replace
"opacity: 0;" but Firefox acts weird with only visibility set, it only
half works until you switch between desktop and mobile view. IDK this
isn't that important.
2022-06-15 10:14:37 +00:00
n9k 46cd032510 CSS: always fullheight info in desktop view 2022-06-15 10:10:04 +00:00
n9k d06a279be6 Sanitize newlines in usernames with js
Previously usernames with newlines in them actually went over multiple
lines.
2022-06-15 09:38:47 +00:00
n9k dd1d98361f v1.2.0 2022-06-15 09:09:03 +00:00
n9k 976abc0ede WS: increase uptime drift tolerance for resending 2022-06-15 09:07:25 +00:00
n9k 5c8062466d Control socket: overhaul finished for now
This unbreaks the commands broken by the last commit. Everything is
still better.
2022-06-15 08:55:44 +00:00
n9k abfa3fe865 Control socket: overhaul implementation
This breaks some commands, everything else is better though.
2022-06-15 05:39:54 +00:00
n9k 65d28a6937 Event socket
This commit adds a unix socket on which you can receive internal events
as they happen. Currently the only supported event is a chat message
being added. Intended for external applications that depend on chat
messages, e.g. text-to-speech or Twitch Plays Pokémon.
2022-06-15 03:53:34 +00:00
n9k 0cb2f226d7 Control socket: view and delete eyes 2022-06-14 10:15:03 +00:00
n9k 70c5836ed0 Control socket: cleanup 2022-06-14 10:15:03 +00:00
n9k 3a1254d30f Control socket: separate files 2022-06-14 10:15:00 +00:00
n9k 751664d1c4 More sensible variable names in colour generation 2022-06-14 08:50:31 +00:00
n9k 47ee5fe607 Take a range of contrasts for generating colours 2022-06-14 08:50:31 +00:00
n9k 1422bebd8e Require Authorization header for broadcaster
As opposed to just the broadcaster token. This makes the broadcaster
username/password login mandatory, which previously was only mandatory
in the `auth_required` wrapper, but not elsewhere (so for example
leaving comments as the broadcaster was possible with the token only). A
less safe alternative to this would be to compare tokens in `check_auth`
once the Authorization header didn't match.
2022-06-14 08:50:31 +00:00
n9k 6ef3a77465 Explicitly reject weird tokens
Includes really long tokens
2022-06-14 08:50:31 +00:00
n9k 506f91a41b Control socket: escape json whitespace if necessary 2022-06-14 08:49:54 +00:00
n9k 7db8895750 Eyes: send Retry-After header during cooldown 2022-06-14 03:33:14 +00:00
n9k a594b6ed73 Eyes: only necessary arguments in exceptions 2022-06-14 03:32:12 +00:00
n9k f081284876 Eyes: cooldown on creating new eyes 2022-06-14 03:02:45 +00:00
n9k 51265fb277 Eyes: delete old eyes
Also implements stack/queue behaviour where if the eyes limit would be
exceeded, either the new eyes cause the oldest eyes to be deleted OR
the new eyes aren't created at all. The default is the first option.
2022-06-14 02:58:11 +00:00
n9k 31ce80b2bf Control socket: view and change users' attributes
Changing things without thinking about it is probably going to cause
weird undefined behaviour.
2022-06-14 02:40:20 +00:00
n9k 84ad17f13d Eyes
This commit adds the concept of eyes. One "eyes" is one instance of a
response to GET /stream.mp4. Currently the number of eyes clients can
have is unbounded, but this is a DoS vector.
2022-06-14 02:40:18 +00:00
n9k 8f06121d8f WS: ping before init 2022-06-14 00:34:24 +00:00
n9k f40637b786 WS: don't close because no pings if already closed 2022-06-13 22:04:59 +00:00
n9k 5751297f10 Control socket: delete chat messages 2022-06-13 21:25:25 +00:00
n9k 36666f8cdf Catch all OSErrors when reading title.txt
Previously we only caught FileNotFoundError. If there was a
PermissionError for example, it would have percolated up and
stopped some background tasks.
2022-06-13 03:46:53 +00:00
n9k 588ecc4c02 Control socket: progress 2022-06-13 03:46:02 +00:00
n9k e491f54b24 Control socket (WIP) 2022-06-12 22:26:48 +00:00
n9k 7f2e75bc98 Read config.toml more organizedly 2022-06-12 22:26:46 +00:00
n9k 98d1beb1b0 v1.1.0 2022-06-12 04:53:57 +00:00
n9k d621f8ceda Reorder chat form inputs so submit has priority
When you press enter to submit a form and there are multiple submittable
inputs (e.g. type="image" / type="submit"), Firefox chooses the one that
appears first in markup. Before this commit the image input (aka the "I
want a new captcha" button) appeared before the submit button which
meant pressing enter just reloaded the captcha instead of submitting the
comment.
2022-06-11 23:14:49 +00:00
n9k 971ab4769a Use accesskey 'r' for reload stream button 2022-06-11 23:14:16 +00:00
n9k 667e35bf16 Handle OSErrors reading playlist, give reasons for offline 2022-06-11 23:14:16 +00:00
n9k ae6c1ba5a9 Reject whitespace-only comments 2022-06-11 23:14:16 +00:00
n9k 542d6c9ae5 Detect chat flooding by counting lines
Reject comments by line count. Ratelimit users by number of lines sent
in chat.
2022-06-11 23:14:16 +00:00
n9k 9e91349ca9 m3u8 init_section may not exist 2022-06-11 23:14:16 +00:00
n9k 31b82a9983 Websocket: ping immediately 2022-06-11 23:14:16 +00:00
n9k 57053b5eca Chat insignia: solid orangered background 2022-06-11 23:14:16 +00:00
n9k 77d68629b6 CSS: fullheight mobile chat, remove iframe margins 2022-06-11 23:14:16 +00:00
n9k 95f12fa632 Send <!doctype html> in responses when auth fails 2022-06-11 23:14:16 +00:00
n9k 2c899cc18d Add timeout for each ASGI http.response.body message
Ensures that if a client becomes idle the segment generator is exited
within a constant amount of time (probably more than this timeout
because of the ASGI server's write buffer and the OS's socket write
buffer, but still constant).
2022-06-11 23:14:16 +00:00
n9k c0de94bc5d Remove redundant failsafe `websocket.close()`
Ping timeouts should do the same thing.
2022-06-11 23:14:16 +00:00
n9k 4b68023cf2 Add websocket ping/pong
Client and server both close the connection if they don't hear from the
other party after a timeout period. This is a failsafe and should
improve reliability.
2022-06-11 23:14:16 +00:00
n9k a7bfab4f26 Offline screen 2022-06-11 23:14:12 +00:00
n9k 6a4e16eaf4 Use &times; instead of &cross;
Tor Browser on Linux prefers &times;
2022-06-09 01:34:59 +00:00
n9k 0aad555408 Info iframe: properly show uptime text-only fallback 2022-06-09 01:34:59 +00:00
n9k 0352358611 Compress some responses
Adds dependency `quart-compress`
2022-06-09 01:34:59 +00:00
n9k 73824f70d7 Lock js chat scroll when not at bottom 2022-06-09 01:34:59 +00:00
n9k dab389abcc More precise debug messages when segment generator exits 2022-06-09 01:34:45 +00:00
n9k 4eaf9b56f7 Try to ensure websocket is closed when forgetting about it
Might not be necessary, but if it is then it prevents a sitation where a
websocket is still open but we've forgotten about it, so we will never
broadcast any new messages to it and the client will be practically frozen in
time until they disconnect and open a new websocket.

Also update the user's last_seen when the websocket is closed. This prevents a
user with js enabled who's actually idle being considered absent and being
rotated when their websocket accidentally closes for a few seconds.
2022-03-10 07:47:57 +13:00
n9k 88fc9493cf v1.0.1 2022-03-10 07:47:46 +13:00
n9k ca669833e3 CSS: add `white-space: pre-wrap;` to chat messages 2022-03-10 07:46:53 +13:00
n9k cda687294e Nojs chat: fix users names/tripcodes having wrong colors 2022-03-10 07:45:56 +13:00
n9k 66eabd67af CSS: add `overflow: hidden;` to chat messages
Stops messages being able to obscure other messages with weird unicode
characters.
2022-03-09 17:42:44 +13:00
n9k 4c491e5318 v1.0.0 2022-03-09 16:57:59 +13:00
n9k 829f3f004b Add licences 2022-03-08 16:41:47 +13:00
n9k 4bab173237 Add Content Security Policy meta tags 2022-03-08 16:13:22 +13:00
n9k 5bd5d7ff6d Nojs chat form: more accesskeys 2022-03-08 16:13:22 +13:00
n9k 4cde4ea07a Add js appearance form (not complete c.f. nojs) 2022-03-08 16:13:22 +13:00
n9k ce5b7ba0ba Fix js memory leak
Already existing tripcode css rules were being re-inserted because of a typo.
2022-03-08 16:13:22 +13:00
n9k 55c16d7214 Nojs chat form: use `:checked` instead of `:target`
This works around a bug in mobile Firefox where under certain cirucmstances two
elements inside an iframe both become the iframe's target elment at the same
time, which breaks the CSS logic so instead of exactly one form being displayed,
nothing is displayed.
2022-03-08 16:13:22 +13:00
n9k 9c5fc4bc71 Keyboard accessible js captcha 2022-03-08 16:13:22 +13:00
n9k f48a27525e Autofocus chat form textarea 2022-03-08 16:13:22 +13:00
n9k 0ce1902918 Show notice from websocket in js chat form 2022-03-08 16:13:22 +13:00
n9k 5153f5d112 Add config option for old tripcode algorithm 2022-03-08 16:13:22 +13:00
n9k ade3ca4e9e Add broadcaster insignia
Also surrounded users' name tags in <b> (HTML) tags.
2022-03-08 16:13:21 +13:00
n9k 9ebcf57de5 Nojs uptime counter 2022-03-07 16:36:36 +13:00
n9k 5590fbbdbe Chat: use breaking space between name and message 2022-03-07 12:56:08 +13:00
n9k 2bb23ab4c4 Rename templates & routes to fit naming scheme 2022-03-07 12:56:08 +13:00
n9k c103de9849 Add meta viewport tags 2022-03-07 12:56:08 +13:00
n9k bb3002ffd5 Nojs chat: add fallback meta refresh to redirect url
Hacky workaround of weird behaviour in Firefox where on a page whose url has a
fragment/hash/anchor in it, sometimes a urlless meta refresh tag will jump to
the element instead of refreshing the page. Same thing happens if the meta
refresh tag's url component is the same as the page's url.
2022-03-07 12:56:08 +13:00
n9k 46fce9c393 Add nojs 'Reload stream' button
The nojs button appears when the stream is online and the user is not watching.
The js button appears when the stream is online and the media element either
(1) is not using the network or (2) fires an error event.
2022-03-07 12:56:08 +13:00
n9k 2763891a4e Nojs chat: only deverify user when they leave a message
Matches the behaviour of the js chat. Makes it so if you submit an empty
message but with a correct captcha, you won't be deverified and given another
captcha until you successfully send a message (and exceed the flood threshold).
Previously you could fill in the captcha with no message and be given back a
new captcha, which doesn't make that much sense.
2022-03-07 12:56:08 +13:00
n9k d4b0594103 Add `?token=...` to every url 2022-03-07 12:56:08 +13:00
n9k 6eda20a244 Add 'Reload stream' button in js 2022-03-07 12:56:08 +13:00
n9k edddbf00bc Show tripcodes in users list 2022-03-07 12:56:08 +13:00
n9k 7962de87e3 WS: combine `uptime` and `viewership` into `stats`
If the stream is offline, `stats` is null, otherwise it contains uptime and
viewership.
2022-03-07 12:56:08 +13:00
n9k ba90e18e30 Minor changes to the appearance of the users list
Made the 'Users in chat' header above the overflow area, so it always stays on
top. Now using `visibility: hidden;` instead of `display: none;` to show/hide
messages/users so that nojs css animations don't reset.
2022-03-07 12:56:08 +13:00
n9k a970368ee6 Nojs users list: add meta refresh tag & timeout 2022-03-07 12:56:08 +13:00
n9k 84ec253001 Show list of watching/non-watching users with js 2022-03-07 12:56:08 +13:00
n9k bfa77b738d Tell websockets which users are watching
This adds a field 'watching' in `user_for_websocket` that's True iff WATCHING,
False iff NOTWATCHING, and None otherwise (since clients don't need to know if
a user is tentative or absent). When the value of this field changes for any
user, they get added to the update buffer (like with any other change).

Removed race condition in `t_sunset_users`: `broadcast_users_update` was being
called *after* a user was removed from memory (and for each user being removed,
which was redundant). In that scenario if there's a user in the update buffer
and `t_sunset_users` wins the race between it and `t_broadcast_users_update`,
then when `t_sunset_users` calls `broadcast_users_update` a KeyError would be
raised since the user's already been removed.

Fixed unintended behaviour of `t_sunset_users`: it was removing users based on
the result of `is_visible`, so users who were actually tenative (as opposed to
absent) were being removed.
2022-03-07 12:54:35 +13:00
n9k 2b1cf7d7b0 CSS: make users button lighter 2022-03-07 12:54:35 +13:00
n9k 1b26ddb816 Nojs chat: add list of watching/non-watching users 2022-03-07 12:54:35 +13:00
n9k 3583005123 Link to git repos 2022-03-07 12:54:35 +13:00
n9k 8589216bf1 Send new captcha over websocket with js 2022-03-07 12:54:35 +13:00
n9k 3016705783 Keep track of stream viewership (number of viewers) 2022-03-07 12:54:35 +13:00
n9k da6e0352b8 Beautify nojs chat template, strip jinja whitespace 2022-03-07 12:54:35 +13:00
n9k a3b18bdc9f Background task for broadcasting title/uptime changes 2022-03-07 12:54:35 +13:00
n9k c36d2b2c38 Catch exception when inbound websocket data is not JSON 2022-03-07 12:54:35 +13:00
n9k 8b4d6e8c09 Get stream title from disk
By default from `title.txt`. Also replace newlines with spaces when setting the
title in js, for parity with the nojs info iframe.
2022-03-07 12:54:35 +13:00
n9k 8d1f273a99 Show and update stream uptime in js 2022-03-07 12:54:33 +13:00
n9k 672ef10159 Add 3-hexdigit tags for default-name users 2022-02-23 09:21:07 +00:00
n9k 86c4efee6b Minor non-breaking nojs chat change
Moved `data-seq` and `data-token-hash` attributes to `.chat-message` from
`.chat-message__name`.
2022-02-23 15:57:05 +13:00
n9k 93409f8095 Message dates and times in chat
Now using `get_message_for_websocket` when sending an individual message.
2022-02-23 15:57:05 +13:00
n9k cc6ed63764 Segment streaming redux, accurate stream uptime 2022-02-23 15:57:04 +13:00
n9k 2f4a9739c0 Show and enforce the captcha in js
Also clear the chat form comment input only if the message was accepted.
2022-02-22 16:25:43 +13:00
n9k 0f8676e2f8 Nojs chat form: change default submittable input on Firefox
This reorders the elements so the comment submit input comes before the
captcha image input (that reloads the form). If a non-submittable input
is active and you press enter, Firefox chooses the first submittable
input and submits the form as if that input were clicked. Before this,
pressing enter on the captcha answer input would reload the form instead
of submitting the comment.
2022-02-22 16:25:43 +13:00
n9k 4889449e1f Properly handle captcha signature exceptions
BadSignature is raised is the digest is empty, and SignatureExpired is a
descendant of BadSignature so it needs to be handled first.
2022-02-22 16:25:43 +13:00
n9k 8c9b0d9da0 Flood detection 2022-02-22 16:25:43 +13:00
n9k 41ee90870d Minor non-breaking changes to captcha
Added image/jpeg content-type header to /captcha.jpg. Made unsigned digests
urlsafe (as they were intended to be).
2022-02-22 16:25:43 +13:00
n9k 0901483837 Add background task for deleting expired captchas 2022-02-22 16:25:43 +13:00
n9k 6ceb553b29 Buffer new and mutated users before sending to websockets
By default the buffer is exhausted every 4 seconds. This should defend against
a potential DoS against clients with JavaScript enabled. Before this, any
request with no token would generate a new user and immediately broadcast the
new user to all the websockets. It's best to lock down as much as possible the
number of places a client can cause the server to broadcasts to all the
websockets.
2022-02-22 16:25:43 +13:00
n9k 546b5b2f6f Always use config.toml in same directory as app.py 2022-02-22 16:25:43 +13:00
n9k b7313eec22 Captchas, require captcha initially, generalize notices to states 2022-02-22 16:25:43 +13:00
n9k 3cc1f633cf Remove chat's pointless scrollbar when there are no messages 2022-02-22 16:25:43 +13:00
n9k 236d73a342 Gracefully finish background tasks on shutdown 2022-02-22 16:25:43 +13:00
n9k 7058677000 Setup background tasks, create t_sunset_users task 2022-02-22 16:25:43 +13:00
n9k 20f79c5265 Fix js typos 2022-02-22 16:25:43 +13:00