This is the code that runs https://bandolier.learnjsthehardway.com/ for you to review. It uses the https://git.learnjsthehardway.com/learn-javascript-the-hard-way/bandolier-template to create the documentation for the project.
https://bandolier.learnjsthehardway.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
6.5 KiB
150 lines
6.5 KiB
/*
|
|
Used to abstract away the Queue system used. It uses the Bull queue system
|
|
internally, which uses Redis as a queue. This works fine but if you wanted
|
|
to use something else you'd need to rewrite this file and maintain the data
|
|
formats sent.
|
|
|
|
The point of using a Queue is to take processing that might take a while and
|
|
push it to a separate process. For example, after a user has paid you may
|
|
need to run complicated PDF libraries to craft their receipt. You don't want
|
|
to do that _inside_ your `api/` handler as that will slow down the response.
|
|
The PDF/receipt also isn't something they need to know about immediately, so
|
|
just shove that into a queue a queue and let another process (or multiple
|
|
processes) do it.
|
|
|
|
A good pattern is to create your `api/` handler so that it works, then identify
|
|
any code that could be placed in a queue job, then move that code into a
|
|
queue handler in `queues/`. The ideal situation is where your `api/` handler
|
|
does nothing but send a message to a queue. If the operation the user requested
|
|
doesn't need immediate feedback, then consider using a queue and sending them
|
|
an email when it's done.
|
|
*/
|
|
import Queue from 'bull';
|
|
|
|
/*
|
|
Create a new Queue with the given name. Mostly used internally but
|
|
you if you need to use the queue system in your own code then this
|
|
how you do it.
|
|
|
|
___BUG___: I'm not clear on the semantics of the bull queues. Should I make
|
|
one per process and use it in all functions? Or, make one for every
|
|
place I need it and don't share them?
|
|
|
|
+ `name string` -- Name for the queue.
|
|
+ ___return___ `Queue` object to use.
|
|
*/
|
|
export const create = (name) => {
|
|
return new Queue(name);
|
|
}
|
|
|
|
/*
|
|
Sends a `mail/registration` message to the queue that handles mail. See `queues/mail.js`
|
|
for how the sending actually works.
|
|
|
|
___WARNING__: This doesn't restrict what can go in the queue, and it's possible Bull isn't
|
|
that good at clearing the queue of records, so user information may be leaked into redis.
|
|
|
|
+ `user User` -- The `User` object should be ready to use by the quee in `queues/mail.js`.
|
|
*/
|
|
export const send_registration = (user) => {
|
|
const mail = create("mail/registration");
|
|
mail.add({user});
|
|
}
|
|
|
|
/*
|
|
Sends the welcome email to a user. Look in `queues/mail.js` to see how this is really done.
|
|
|
|
___WARNING__: This doesn't restrict what can go in the queue, and it's possible Bull isn't
|
|
that good at clearing the queue of records, so user information may be leaked into redis.
|
|
|
|
+ `user User` -- The `User` object should be ready to use by the quee in `queues/mail.js`.
|
|
*/
|
|
export const send_welcome = (user) => {
|
|
const mail = create("mail/welcome");
|
|
mail.add({user});
|
|
}
|
|
|
|
/*
|
|
Sends a receipt request to the queue process. Receipt processing can get insanely complicated
|
|
depending on what the user needs. I tend to use simple HTML email, but if you want to get
|
|
into pointless PDF receipts then definitely use a queue handler.
|
|
|
|
___WARNING__: This doesn't restrict what can go in the queue, and it's possible Bull isn't
|
|
that good at clearing the queue of records, so user information may be leaked into redis.
|
|
|
|
+ `user User` -- The `User` object should be ready to use by the quee in `queues/mail.js`.
|
|
+ `payment_id number` -- The `id` for the payment to attach to the receipt.
|
|
+ `product_id number` -- The `Product` they purchased.
|
|
*/
|
|
export const send_receipt = (user, payment_id, product_id) => {
|
|
const mail = create("mail/receipt");
|
|
mail.add({user, payment_id, product_id});
|
|
}
|
|
|
|
/*
|
|
Sends a password reset __REQUEST__ email. This doesn't do the reset, only give them
|
|
the code to their email for the reset. One thing this does is include the IP address
|
|
and browser User Agent so the receiver will know if they requested it or not. The security
|
|
mechanism to prevent repeated reset attempts is:
|
|
|
|
+ There's a max limit on requests in `api/password_reset.js:RESET_MAX`.
|
|
+ There's an enforced delay on requests of 1 per 10 hours in `api/password_reset.js:RESET_HOURS_MAX`.
|
|
+ The user's email is notified of the IP address and browser used on request _and_ reset complete.
|
|
+ The account is locked if `RESET_MAX` is reached and no more attempts are accepted.
|
|
|
|
With this an attacker would get one guess every 10 hours, the user would be notified of the attempt (giving them time to notify admins), and if the attacker makes > `RESET_MAX` attempts the account is locked.
|
|
|
|
___WARNING__: This doesn't restrict what can go in the queue, and it's possible Bull isn't
|
|
that good at clearing the queue of records, so user information may be leaked into redis.
|
|
|
|
+ `user User` -- The `User` object should be ready to use by the queue in `queues/mail.js`.
|
|
+ `ip_address string` -- The IP address of the computer requesting the reset.
|
|
+ `browser string` -- The user agent of the browser requesting.
|
|
*/
|
|
export const send_reset = (user, ip_address, browser) => {
|
|
const mail = create("mail/reset");
|
|
mail.add({user, ip_address, browser});
|
|
}
|
|
|
|
/*
|
|
Send the final notification that the reset was successful. See `send_reset` for more
|
|
security rules.
|
|
|
|
___WARNING__: This doesn't restrict what can go in the queue, and it's possible Bull isn't
|
|
that good at clearing the queue of records, so user information may be leaked into redis.
|
|
|
|
+ `user User` -- The `User` object should be ready to use by the queue in `queues/mail.js`.
|
|
+ `ip_address string` -- The IP address of the computer requesting the reset.
|
|
+ `browser string` -- The user agent of the browser requesting.
|
|
*/
|
|
export const send_reset_finished = (user, ip_address, browser) => {
|
|
const mail = create("mail/reset_finished");
|
|
mail.add({user, ip_address, browser});
|
|
}
|
|
|
|
/*
|
|
Used to quickly update the current view statistics on `Livestream` to all
|
|
users viewing it. Since this isn't crucial and not something a user expects
|
|
to be updated immediately it's easy to shove it into a queue. The queue handler
|
|
in `queues/live.js` will use `sockets/live.js` to send out an announce.
|
|
|
|
+ `api_key string` -- Used to make sure this is from the server. Users shouldn't see this.
|
|
*/
|
|
export const send_update_viewers = (api_key) => {
|
|
const live = create("live/update_viewers");
|
|
live.add({api_key});
|
|
}
|
|
|
|
/*
|
|
Adds to a `Livesteam` view count in the database for statistics.
|
|
|
|
+ `livestream_id number` -- The `id` of the `Livestream` to update.
|
|
*/
|
|
export const add_view_count = (livestream_id) => {
|
|
const live = create("live/add_view_count");
|
|
live.add({livestream_id});
|
|
}
|
|
|
|
export default {
|
|
create, send_welcome, send_reset, send_reset_finished, send_update_viewers
|
|
}
|
|
|