@ -1,42 +1,145 @@
/ *
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' ;
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 ) => {
export const create = ( name ) => {
// 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?
return new Queue ( 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 ) => {
export const send _registration = ( user ) => {
const mail = create ( "mail/registration" ) ;
const mail = create ( "mail/registration" ) ;
mail . add ( { user } ) ;
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 ) => {
export const send _welcome = ( user ) => {
const mail = create ( "mail/welcome" ) ;
const mail = create ( "mail/welcome" ) ;
mail . add ( { user } ) ;
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 ) => {
export const send _receipt = ( user , payment _id , product _id ) => {
const mail = create ( "mail/receipt" ) ;
const mail = create ( "mail/receipt" ) ;
mail . add ( { user , payment _id , product _id } ) ;
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 ) => {
export const send _reset = ( user , ip _address , browser ) => {
const mail = create ( "mail/reset" ) ;
const mail = create ( "mail/reset" ) ;
mail . add ( { user , ip _address , browser } ) ;
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 ) => {
export const send _reset _finished = ( user , ip _address , browser ) => {
const mail = create ( "mail/reset_finished" ) ;
const mail = create ( "mail/reset_finished" ) ;
mail . add ( { user , ip _address , browser } ) ;
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 ) => {
export const send _update _viewers = ( api _key ) => {
const live = create ( "live/update_viewers" ) ;
const live = create ( "live/update_viewers" ) ;
live . add ( { api _key } ) ;
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 ) => {
export const add _view _count = ( livestream _id ) => {
const live = create ( "live/add_view_count" ) ;
const live = create ( "live/add_view_count" ) ;
live . add ( { livestream _id } ) ;
live . add ( { livestream _id } ) ;