my review #1

Open
opened 2026-02-25 19:55:53 -06:00 by sea · 0 comments

server:

  • don't trust input by default - strict validation of data as it comes in
    • username: making sure there aren't any special characters, whitespaces
    • message: data.text can be any data type
      • can be used as an attack vector depending on how it gets handled in the client or server
    • libraries like zod can help quite a lot here, typescript can make it ergonomic to handle
  • security mindset: server should NEVER trust the client's data, and ideally the client shouldnt trust the server that much either
  • changing username doesn't clear old user from the connectedUsers list
  • no rate limiting - can spam any command really hard
    • not a big deal for small chats but it's a good practice anyway
  • exhaustive switches are a really nice typescript way to make sure you're handling all message types

client:

  • no websocket connection error handling, no reconnection logic
  • username acceptance logic will let you in if someone else joins the chat
  • you can make it so you send username at http upgrade (which is usually where authentication happens anyway)
    • this way you don't have to listen to system messages
    • and you can't connect without providing a username
  • raw DOM is a good way to learn how the DOM works, but is far less ergonomic to using a library
    that helps you render things as components (e.g. react, vue, svelte, even choo.js)
  • you can make it easier to send messages by turning the chat input into a <form>, and listening to "onsubmit"
    • you'll have to preventDefault(), but when the input is part of a form, and you have a "send" button that is type="submit",
      both pressing enter, clicking the button, or some other means will "submit" the form, making it ideal for situations like this
  • ditto for username selection
server: - don't trust input by default - strict validation of data as it comes in - username: making sure there aren't any special characters, whitespaces - message: data.text can be any data type - can be used as an attack vector depending on how it gets handled in the client or server - libraries like zod can help quite a lot here, typescript can make it ergonomic to handle - security mindset: server should NEVER trust the client's data, and ideally the client shouldnt trust the server that much either - changing username doesn't clear old user from the connectedUsers list - no rate limiting - can spam any command really hard - not a big deal for small chats but it's a good practice anyway - exhaustive switches are a really nice typescript way to make sure you're handling all message types client: - no websocket connection error handling, no reconnection logic - username acceptance logic will let you in if someone else joins the chat - you can make it so you send username at http upgrade (which is usually where authentication happens anyway) - this way you don't have to listen to system messages - and you can't connect without providing a username - raw DOM is a good way to learn how the DOM works, but is far less ergonomic to using a library that helps you render things as components (e.g. react, vue, svelte, even choo.js) - you can make it easier to send messages by turning the chat input into a `<form>`, and listening to "onsubmit" - you'll have to preventDefault(), but when the input is part of a form, and you have a "send" button that is type="submit", both pressing enter, clicking the button, or some other means will "submit" the form, making it ideal for situations like this - ditto for username selection
maple self-assigned this 2026-03-06 12:35:59 -06:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
maple/bun-chat#1
No description provided.