@ -30,86 +30,22 @@ const load_notes_stmt =
+ " JOIN note AS n"
+ " JOIN note AS n"
+ " ON n.id = bn.note_id"
+ " ON n.id = bn.note_id"
+ " WHERE bn.bin_id = $1" ;
+ " WHERE bn.bin_id = $1" ;
const load _bin _stmt =
"SELECT b.id, b.name, bu.user_id as owner_user_id, s.user_id as session_user_id FROM bin AS b"
+ " FULL JOIN bin_user AS bu" // we want the bin regardless of whether it has an associated user, hence LEFT JOIN
+ " ON bu.bin_id = b.id"
+ " FULL JOIN session AS s"
+ " ON s.id = $2"
+ " WHERE b.id = $1" ;
const search _stmt =
"SELECT n.id, n.text, n.modified FROM note AS n"
+ " INNER JOIN bin_note AS bn"
+ " ON bn.note_id = n.id AND bn.bin_id = $2"
+ " WHERE n.text LIKE '%' || $1 || '%'" ; // need to use string concat otherwise the `$1` is viewed as part of the string instead of a placeholder
const order _desc _stmt = " ORDER BY n.modified DESC" ;
const order _asc _stmt = " ORDER BY n.modified ASC" ;
const upsert _note _stmt =
"INSERT INTO note (id, text, modified) VALUES ($1, $2, NOW())"
+ " ON CONFLICT (id)"
+ " DO UPDATE SET text = EXCLUDED.text, modified = EXCLUDED.modified" ;
const upsert _bin _stmt =
"INSERT INTO bin (id, name) VALUES ($1, $1)"
+ " ON CONFLICT (id)"
+ " DO NOTHING" ;
const upsert _bin _note _stmt =
"INSERT INTO bin_note (bin_id, note_id) VALUES ($1, $2)"
+ " ON CONFLICT (bin_id, note_id)"
+ " DO NOTHING" ;
const upsert _bin _user _stmt =
"INSERT INTO bin_user (bin_id, user_id)"
+ " (SELECT $1, s.user_id FROM session AS s WHERE s.id = $2)"
+ " ON CONFLICT (bin_id, user_id)"
+ " DO NOTHING" ;
const login _check _stmt =
"SELECT id, password FROM user_ AS u"
+ " WHERE u.username = $1" ;
const register _stmt =
"INSERT INTO user_ (id, username, password) VALUES ($1, $2, $3)" ;
const session _create _stmt =
"INSERT INTO session (id, user_id) VALUES ($1, $2)" ;
const user _bin _list _stmt =
"SELECT b.id, b.name FROM bin_user AS bu"
+ " INNER JOIN bin AS b"
+ " ON bu.bin_id = b.id"
+ " WHERE bu.user_id = $1" ;
const delete _session _stmt =
"DELETE FROM session WHERE id = $1" ;
const rename _bin _stmt =
"INSERT INTO bin (id, name) VALUES ($1, $2)"
+ " ON CONFLICT (id)"
+ " DO UPDATE SET name = EXCLUDED.name;" ;
// {bin_id}
// {bin_id}
router . post ( '/load-notes' , ( req , res ) => {
router . post ( '/load-notes' , ( req , res ) => {
const { bin _id , session _id } = req . body ;
const bin _id = req . body . bin _id ;
db . query ( load _bin _stmt , [ bin _id , session _id ] )
db . query ( load _notes _stmt , [ bin _id ] )
. then ( bin _result => {
. then ( result => {
if ( bin _result . rows . length > 0 ) {
res . json ( { success : true , notes : result . rows } )
const bin = bin _result . rows [ 0 ] ;
// if it's a public bin:
if ( bin . owner _user _id === null ) {
db . query ( load _notes _stmt , [ bin _id ] )
. then ( result => {
res . json ( { success : true , authorized : false , notes : result . rows } )
} ) ;
}
// if it's a private bin, and the owner is signed-in:
else if ( bin . owner _user _id === bin . session _user _id ) {
db . query ( load _notes _stmt , [ bin _id ] )
. then ( result => {
res . json ( { success : true , authorized : true , notes : result . rows } )
} ) ;
}
else {
res . json ( { success : false , authorized : false } ) ;
}
}
} ) ;
} ) ;
} ) ;
} ) ;
const load _bin _stmt =
"SELECT b.id, b.name FROM bin AS b"
+ " FULL JOIN bin_user AS bu" // we want the bin regardless of whether it has an associated user, hence LEFT JOIN
+ " ON bu.bin_id = b.id"
+ " INNER JOIN session AS s"
+ " ON (bu.bin_id IS NULL) OR (s.id = $2 AND s.user_id = bu.user_id)"
+ " WHERE b.id = $1" ;
router . post ( '/load-bin' , ( req , res ) => {
router . post ( '/load-bin' , ( req , res ) => {
const { bin _id , session _id } = req . body ;
const { bin _id , session _id } = req . body ;
// if a bin has no associated user, it's considered public and can be accessed even when not logged-in.
// if a bin has no associated user, it's considered public and can be accessed even when not logged-in.
@ -119,26 +55,22 @@ router.post('/load-bin', (req, res)=>{
const bin = result . rows [ 0 ] ;
const bin = result . rows [ 0 ] ;
// if a bin with given id was found:
// if a bin with given id was found:
if ( result . rows . length > 0 ) {
if ( result . rows . length > 0 ) {
const bin = result . rows [ 0 ] ;
res . json ( { success : true , bin : { id : bin . id , name : bin . name } } ) ;
// if it's a public bin:
if ( bin . owner _user _id === null ) {
res . json ( { success : true , authorized : false , bin : { id : bin . id , name : bin . name } } ) ;
}
// if it's a private bin, and the owner is signed-in:
else if ( bin . owner _user _id === bin . session _user _id ) {
res . json ( { success : true , authorized : true , bin : { id : bin . id , name : bin . name } } ) ;
}
else {
res . json ( { success : false , authorized : false } ) ;
}
}
}
else {
else {
res . json ( { success : true , authorized: true , bin: { id : bin _id , name : bin _id } } ) ;
res . json ( { success : true , bin : { id : bin _id , name : bin _id } } ) ;
}
}
} ) ;
} ) ;
// {status: 'ok', bin:{id:bin.id}, notes: bin.notes}
// {status: 'ok', bin:{id:bin.id}, notes: bin.notes}
} ) ;
} ) ;
const search _stmt =
"SELECT n.id, n.text, n.modified FROM note AS n"
+ " INNER JOIN bin_note AS bn"
+ " ON bn.note_id = n.id AND bn.bin_id = $2"
+ " WHERE n.text LIKE '%' || $1 || '%'" ; // need to use string concat otherwise the `$1` is viewed as part of the string instead of a placeholder
const order _desc _stmt = " ORDER BY n.modified DESC" ;
const order _asc _stmt = " ORDER BY n.modified ASC" ;
// {search_term, sorting, bin_id}
// {search_term, sorting, bin_id}
router . post ( '/search' , ( req , res ) => {
router . post ( '/search' , ( req , res ) => {
const { search _term , bin _id , sorting } = req . body ;
const { search _term , bin _id , sorting } = req . body ;
@ -148,6 +80,23 @@ router.post('/search', (req, res)=>{
} ) ;
} ) ;
} ) ;
} ) ;
const upsert _note _stmt =
"INSERT INTO note (id, text, modified) VALUES ($1, $2, NOW())"
+ " ON CONFLICT (id)"
+ " DO UPDATE SET text = EXCLUDED.text, modified = EXCLUDED.modified" ;
const upsert _bin _stmt =
"INSERT INTO bin (id, name) VALUES ($1, $1)"
+ " ON CONFLICT (id)"
+ " DO NOTHING" ;
const upsert _bin _note _stmt =
"INSERT INTO bin_note (bin_id, note_id) VALUES ($1, $2)"
+ " ON CONFLICT (bin_id, note_id)"
+ " DO NOTHING" ;
const upsert _bin _user _stmt =
"INSERT INTO bin_user (bin_id, user_id)"
+ " (SELECT $1, s.user_id FROM session AS s WHERE s.id = $2)"
+ " ON CONFLICT (bin_id, user_id)"
+ " DO NOTHING" ;
// {bin_id, note_id, text}
// {bin_id, note_id, text}
router . post ( '/save' , ( req , res ) => {
router . post ( '/save' , ( req , res ) => {
const { bin _id , note _id , text , session _id } = req . body ;
const { bin _id , note _id , text , session _id } = req . body ;
@ -167,6 +116,18 @@ router.post('/save', (req, res)=>{
// {status: 'ok'}
// {status: 'ok'}
} ) ;
} ) ;
const login _check _stmt =
"SELECT id, password FROM user_ AS u"
+ " WHERE u.username = $1" ;
const register _stmt =
"INSERT INTO user_ (id, username, password) VALUES ($1, $2, $3)" ;
const session _create _stmt =
"INSERT INTO session (id, user_id) VALUES ($1, $2)" ;
const user _bin _list _stmt =
"SELECT b.id, b.name FROM bin_user AS bu"
+ " INNER JOIN bin AS b"
+ " ON bu.bin_id = b.id"
+ " WHERE bu.user_id = $1" ;
router . post ( '/login' , ( req , res ) => {
router . post ( '/login' , ( req , res ) => {
const { username , password } = req . body ;
const { username , password } = req . body ;
const password _from _client = password ;
const password _from _client = password ;
@ -204,13 +165,17 @@ router.post('/login', (req, res)=>{
} ) ;
} ) ;
} ) ;
} ) ;
const delete _session _stmt =
"DELETE FROM session WHERE id = $1" ;
router . post ( '/logout' , ( req , res ) => {
router . post ( '/logout' , ( req , res ) => {
db . query ( delete _session _stmt , [ req . body . session _id ] ) ;
db . query ( delete _session _stmt , [ req . body . session _id ] ) ;
res . json ( { success : true } ) ;
res . json ( { success : true } ) ;
} ) ;
} ) ;
const rename _bin _stmt =
"INSERT INTO bin (id, name) VALUES ($1, $2)"
+ " ON CONFLICT (id)"
+ " DO UPDATE SET name = EXCLUDED.name;" ;
router . post ( '/bin-rename' , ( req , res ) => {
router . post ( '/bin-rename' , ( req , res ) => {
const { bin _id , name , session _id } = req . body ;
const { bin _id , name , session _id } = req . body ;
db . query ( rename _bin _stmt , [ bin _id , name ] )
db . query ( rename _bin _stmt , [ bin _id , name ] )