From a2872cd013eb0304a2d9621048b045a597b989ed Mon Sep 17 00:00:00 2001 From: Eduardolans Date: Mon, 24 Jun 2024 21:58:35 +0200 Subject: [PATCH] split api data into files; #136 --- .../socialcode/api/data/deletePost-Orig.js | 36 + .../socialcode/api/data/deletePost.js | 36 + .../socialcode/api/data/deletePost.test.js | 28 + .../socialcode/api/data/findOnePost.js | 22 + .../socialcode/api/data/findOnePost.test.js | 15 + .../socialcode/api/data/findPosts.js | 22 + .../socialcode/api/data/findPosts.test.js | 29 + .../socialcode/api/data/findUser.js | 22 + .../socialcode/api/data/findUser.test.js | 11 + .../socialcode/api/data/index.js | 161 +--- .../socialcode/api/data/insertPost.js | 34 + .../socialcode/api/data/insertPost.test.js | 16 + .../socialcode/api/data/insertUser-Orig.js | 32 + .../socialcode/api/data/insertUser.js | 48 + .../socialcode/api/data/insertUser.test.js | 11 + .../socialcode/api/data/posts.json | 235 ++++- .../socialcode/api/data/users.json | 7 + staff/eduardo-sanchez/socialcode/api_/.env | 3 + .../socialcode/api_/.gitignore | 2 + .../eduardo-sanchez/socialcode/api_/README.md | 61 ++ .../socialcode/api_/data/index.js | 150 ++++ .../socialcode/api_/data/index.test.js | 56 ++ .../socialcode/api_/data/posts.json | 1 + .../socialcode/api_/data/users.json | 58 ++ .../eduardo-sanchez/socialcode/api_/index.js | 160 ++++ .../socialcode/api_/logic/authenticateUser.js | 42 + .../api_/logic/authenticateUser.test.js | 16 + .../socialcode/api_/logic/createPost.js | 45 + .../socialcode/api_/logic/createPost.test.js | 15 + .../socialcode/api_/logic/deletePost.js | 55 ++ .../socialcode/api_/logic/deletePost.test.js | 15 + .../socialcode/api_/logic/getAllPosts.js | 34 + .../socialcode/api_/logic/getAllPosts.test.js | 15 + .../socialcode/api_/logic/getUserName.js | 41 + .../socialcode/api_/logic/getUserName.test.js | 15 + .../socialcode/api_/logic/index.js | 19 + .../socialcode/api_/logic/registerUser.js | 58 ++ .../api_/logic/registerUser.test.js | 19 + .../socialcode/api_/package-lock.json | 847 ++++++++++++++++++ .../socialcode/api_/package.json | 23 + 40 files changed, 2368 insertions(+), 147 deletions(-) create mode 100644 staff/eduardo-sanchez/socialcode/api/data/deletePost-Orig.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/deletePost.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/deletePost.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/findOnePost.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/findOnePost.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/findPosts.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/findPosts.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/findUser.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/findUser.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/insertPost.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/insertPost.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/insertUser-Orig.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/insertUser.js create mode 100644 staff/eduardo-sanchez/socialcode/api/data/insertUser.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/.env create mode 100644 staff/eduardo-sanchez/socialcode/api_/.gitignore create mode 100644 staff/eduardo-sanchez/socialcode/api_/README.md create mode 100644 staff/eduardo-sanchez/socialcode/api_/data/index.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/data/index.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/data/posts.json create mode 100644 staff/eduardo-sanchez/socialcode/api_/data/users.json create mode 100644 staff/eduardo-sanchez/socialcode/api_/index.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/authenticateUser.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/authenticateUser.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/createPost.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/createPost.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/deletePost.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/deletePost.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/getAllPosts.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/getAllPosts.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/getUserName.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/getUserName.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/index.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/registerUser.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/logic/registerUser.test.js create mode 100644 staff/eduardo-sanchez/socialcode/api_/package-lock.json create mode 100644 staff/eduardo-sanchez/socialcode/api_/package.json diff --git a/staff/eduardo-sanchez/socialcode/api/data/deletePost-Orig.js b/staff/eduardo-sanchez/socialcode/api/data/deletePost-Orig.js new file mode 100644 index 000000000..c9f2a655a --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/deletePost-Orig.js @@ -0,0 +1,36 @@ +import fs from 'fs' +import { SystemError } from 'com/errors.js' + +const deletePost = (condition, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const posts = JSON.parse(json) + + const index = posts.findIndex(condition) + + if (index > -1) { + posts.splice(index, 1) + + const newJson = JSON.stringify(posts) + + fs.writeFile('./data/posts.json', newJson, error => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + callback(null) + }) + } else callback(null) + }) +} + +export default deletePost \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/deletePost.js b/staff/eduardo-sanchez/socialcode/api/data/deletePost.js new file mode 100644 index 000000000..7dbf6e34f --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/deletePost.js @@ -0,0 +1,36 @@ +import fs from 'fs'; +import { SystemError } from 'com/errors.js'; // Asegúrate de que la ruta sea correcta + +const deletePost = (condition, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)); + return; + } + + if (!json) json = '[]'; + + const posts = JSON.parse(json); + + const index = posts.findIndex(condition); + + if (index > -1) { + const deletedPost = posts.splice(index, 1)[0]; // Elimina y guarda el post eliminado + + const newJson = JSON.stringify(posts, null, 2); // Indentación de 2 espacios para legibilidad + + fs.writeFile('./data/posts.json', newJson, error => { + if (error) { + callback(new SystemError(error.message)); + return; + } + + callback(null, deletedPost); // Llama al callback con el post eliminado + }); + } else { + callback(null, null); // Llama al callback con null si no se encontró ningún post para eliminar + } + }); +} + +export default deletePost; diff --git a/staff/eduardo-sanchez/socialcode/api/data/deletePost.test.js b/staff/eduardo-sanchez/socialcode/api/data/deletePost.test.js new file mode 100644 index 000000000..e1a2f3a5b --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/deletePost.test.js @@ -0,0 +1,28 @@ +// import data from './index.js' + +// data.deletePost(post => post.title === 'smile 2', error => { +// if (error) { +// console.error(error) + +// return +// } + +// console.log('post deleted') +// }) + + + +import data from "./index.js" + +data.deletePost(post => post.title === "smile 2", (error, deletedPost) => { + if (error) { + console.error(error) + } + + if (!deletedPost) { + console.error("Post not found") + } else { + console.log(`Post with title: ${deletedPost.title} deleted`) + } +}) + diff --git a/staff/eduardo-sanchez/socialcode/api/data/findOnePost.js b/staff/eduardo-sanchez/socialcode/api/data/findOnePost.js new file mode 100644 index 000000000..6f855c466 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/findOnePost.js @@ -0,0 +1,22 @@ +import fs from 'fs' +import { SystemError } from 'com/errors.js' + +const findOnePost = (condition, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const posts = JSON.parse(json) + + const foundPost = posts.find(condition) + + callback(null, foundPost) + }) +} + +export default findOnePost \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/findOnePost.test.js b/staff/eduardo-sanchez/socialcode/api/data/findOnePost.test.js new file mode 100644 index 000000000..ca2c37aa0 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/findOnePost.test.js @@ -0,0 +1,15 @@ +import data from './index.js' + +data.findOnePost(post => post.date.includes('T15'), (error, post) => { + if (error) { + console.error(error) + + return + } + + if (!post) { + console.error("Post not found"); + } else { + console.log(post); + } +}) diff --git a/staff/eduardo-sanchez/socialcode/api/data/findPosts.js b/staff/eduardo-sanchez/socialcode/api/data/findPosts.js new file mode 100644 index 000000000..18144bd0f --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/findPosts.js @@ -0,0 +1,22 @@ +import fs from 'fs' +import { SystemError } from 'com/errors.js' + +const findPosts = (condition, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const posts = JSON.parse(json) + + const filtered = posts.filter(condition) + + callback(null, filtered) + }) +} + +export default findPosts diff --git a/staff/eduardo-sanchez/socialcode/api/data/findPosts.test.js b/staff/eduardo-sanchez/socialcode/api/data/findPosts.test.js new file mode 100644 index 000000000..523f23428 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/findPosts.test.js @@ -0,0 +1,29 @@ +import data from "./index.js" + +data.findPosts(post => post.date.includes('T15'), (error, postsFound) => { + if (error) { + console.error(error) + + return + } + + if (!postsFound || postsFound.length === 0) { + console.error("Posts or Post not found") + } else { + console.log('Posts or Post with search details found') + } + + console.log(postsFound) +}) + +//data.findPosts(post => post.title && post.title.includes("L"), (error, posts) => { + +// data.findPosts(post => post.date.includes('T1Z'), (error, posts) => { +// if (error) { +// console.error(error) + +// return +// } + +// console.log(posts) +// }) diff --git a/staff/eduardo-sanchez/socialcode/api/data/findUser.js b/staff/eduardo-sanchez/socialcode/api/data/findUser.js new file mode 100644 index 000000000..5f05f0797 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/findUser.js @@ -0,0 +1,22 @@ +import fs from 'fs' +import { SystemError } from 'com/errors.js' + +const findUser = (condition, callback) => { + fs.readFile('./data/users.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const users = JSON.parse(json) + + const user = users.find(condition) + + callback(null, user) + }) +} + +export default findUser \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/findUser.test.js b/staff/eduardo-sanchez/socialcode/api/data/findUser.test.js new file mode 100644 index 000000000..4b8b40c2c --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/findUser.test.js @@ -0,0 +1,11 @@ +import data from './index.js' + +data.findUser(user => user.surname === 'Grillo', (error, user) => { + if (error) { + console.error(error) + + return + } + + console.log(user) +}) \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/index.js b/staff/eduardo-sanchez/socialcode/api/data/index.js index 7e738a0f0..c997863ac 100644 --- a/staff/eduardo-sanchez/socialcode/api/data/index.js +++ b/staff/eduardo-sanchez/socialcode/api/data/index.js @@ -1,150 +1,19 @@ -import fs from 'fs' -import { SystemError } from 'com/errors.js' -const data = {} - -data.findUser = (condition, callback) => { - fs.readFile('./data/users.json', 'utf8', (error, json) => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - if (!json) json = '[]' - - const users = JSON.parse(json) - - const user = users.find(condition) - - callback(null, user) - }) -} - -data.insertUser = (user, callback) => { - fs.readFile('./data/users.json', 'utf8', (error, json) => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - if (!json) json = '[]' - - const users = JSON.parse(json) - - users.push(user) - - const newJson = JSON.stringify(users) - - fs.writeFile('./data/users.json', newJson, error => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - callback(null) - }) - }) -} - -data.findPosts = (condition, callback) => { - fs.readFile('./data/posts.json', 'utf8', (error, json) => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - if (!json) json = '[]' - - const posts = JSON.parse(json) - - const filtered = posts.filter(condition) - - callback(null, filtered) - }) -} - -data.findPost = (condition, callback) => { - fs.readFile('./data/posts.json', 'utf8', (error, json) => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - if (!json) json = '[]' - - const posts = JSON.parse(json) - - const post = posts.find(condition) - - callback(null, post) - }) -} - -data.insertPost = (post, callback) => { - fs.readFile('./data/posts.json', 'utf8', (error, json) => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - if (!json) json = '[]' - - const posts = JSON.parse(json) - - post.id = `${Math.random().toString().slice(2)}-${Date.now()}` - - posts.push(post) - - const newJson = JSON.stringify(posts) - - fs.writeFile('./data/posts.json', newJson, error => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - callback(null) - }) - }) -} - -data.deletePost = (condition, callback) => { - fs.readFile('./data/posts.json', 'utf8', (error, json) => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - if (!json) json = '[]' - - const posts = JSON.parse(json) - - const index = posts.findIndex(condition) - - if (index > -1) { - posts.splice(index, 1) - - const newJson = JSON.stringify(posts) - - fs.writeFile('./data/posts.json', newJson, error => { - if (error) { - callback(new SystemError(error.message)) - - return - } - - callback(null) - }) - } else callback(null) - }) +import findUser from './findUser.js' +import insertUser from './insertUser.js' +import findPosts from './findPosts.js' +import findOnePost from './findOnePost.js' +import insertPost from './insertPost.js' +import deletePost from './deletePost.js' + +const data = { + findUser, + insertUser, + + findPosts, + findOnePost, + insertPost, + deletePost } export default data \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/insertPost.js b/staff/eduardo-sanchez/socialcode/api/data/insertPost.js new file mode 100644 index 000000000..e3583fabd --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/insertPost.js @@ -0,0 +1,34 @@ +import fs from 'fs' +import { SystemError } from 'com/errors.js' + +const insertPost = (post, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const posts = JSON.parse(json) + + post.id = `${Math.random().toString().slice(2)}-${Date.now()}` + + posts.push(post) + + const newJson = JSON.stringify(posts) + + fs.writeFile('./data/posts.json', newJson, error => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + callback(null) + }) + }) +} + +export default insertPost \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/insertPost.test.js b/staff/eduardo-sanchez/socialcode/api/data/insertPost.test.js new file mode 100644 index 000000000..d69599d77 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/insertPost.test.js @@ -0,0 +1,16 @@ +import data from './index.js' + +data.insertPost({ + author: 'jameshook', + title: 'smile 2', + image: 'https://m.media-amazon.com/images/I/41xsPjrM-pL._AC_UF350,350_QL50_.jpg', description: 'hi 2', + date: new Date().toISOString() +}, error => { + if (error) { + console.error(error) + + return + } + + console.log('post inserted') +}) diff --git a/staff/eduardo-sanchez/socialcode/api/data/insertUser-Orig.js b/staff/eduardo-sanchez/socialcode/api/data/insertUser-Orig.js new file mode 100644 index 000000000..1776276c6 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/insertUser-Orig.js @@ -0,0 +1,32 @@ +import fs from 'fs' +import { SystemError } from 'com/errors.js' + +const insertUser = (user, callback) => { + fs.readFile('./data/users.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const users = JSON.parse(json) + + users.push(user) + + const newJson = JSON.stringify(users) + + fs.writeFile('./data/users.json', newJson, error => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + callback(null) + }) + }) +} + +export default insertUser \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/insertUser.js b/staff/eduardo-sanchez/socialcode/api/data/insertUser.js new file mode 100644 index 000000000..536acdfc3 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/insertUser.js @@ -0,0 +1,48 @@ +import fs from 'fs'; +import bcrypt from 'bcryptjs'; +import { SystemError } from 'com/errors.js'; // Asegúrate de que la ruta es correcta + +const insertUser = (user, callback) => { + fs.readFile('./data/users.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)); + return; + } + + if (!json) json = '[]'; + + const users = JSON.parse(json); + + const userExists = users.some(existingUser => + existingUser.username === user.username || existingUser.email === user.email + ); + + if (userExists) { + callback(new SystemError('User already exists')); + return; + } + + bcrypt.hash(user.password, 10, (err, hash) => { + if (err) { + callback(new SystemError(err.message)); + return; + } + + user.password = hash; + users.push(user); + + const newJson = JSON.stringify(users); + + fs.writeFile('./data/users.json', newJson, error => { + if (error) { + callback(new SystemError(error.message)); + return; + } + + callback(null); + }); + }); + }); +} + +export default insertUser; diff --git a/staff/eduardo-sanchez/socialcode/api/data/insertUser.test.js b/staff/eduardo-sanchez/socialcode/api/data/insertUser.test.js new file mode 100644 index 000000000..b6f0412c0 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api/data/insertUser.test.js @@ -0,0 +1,11 @@ +import data from "./index.js" + +data.insertUser({ name: 'James', surname: 'Hook', email: 'james@hook.com', username: 'jameshook', password: '123123123' }, error => { + if (error) { + console.error(error) + + return + } + + console.log('user inserted') +}) \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/posts.json b/staff/eduardo-sanchez/socialcode/api/data/posts.json index b5587163f..65009e85f 100644 --- a/staff/eduardo-sanchez/socialcode/api/data/posts.json +++ b/staff/eduardo-sanchez/socialcode/api/data/posts.json @@ -1 +1,234 @@ -[{"author":"pepitogrillo","title":"blah","image":"https://m.media-amazon.com/images/I/41xsPjrM-pL._AC_UF350,350_QL50_.jpg","description":"blah blah","id":"5879244716997389-1716667549269","date":"2024-05-25T20:05:49.269Z"},{"id":"5424401351689265-1716995937318","author":"WendyD","title":"asfaF","image":"https://media.giphy.com/media/xTiTntKyFNFbCNuqkw/giphy.gif?cid=790b76117ksklq64slgwdawn5cmtm14enobheew3nkecwdq1&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"ASAFA","date":"2024-05-29T15:18:57.318Z"},{"author":"peterpan","title":"hello world","image":"https://miro.medium.com/v2/resize:fit:1024/1*OohqW5DGh9CQS4hLY5FXzA.png","description":"console.log(\"hello world\")","date":"2024-05-30T13:46:33.345Z","id":"2575794271140359-1717076793345"},{"author":"peterpan","title":"blah","image":"https://upload.wikimedia.org/wikipedia/commons/1/1d/Blah_Blah_Blah.jpg","description":"blah blah","date":"2024-05-30T14:07:06.222Z","id":"03238060139373644-1717078026222"},{"author":"peterpan","title":"i love js","image":"https://images-na.ssl-images-amazon.com/images/I/61VmREcLaFL._SLDPMOBCAROUSELAUTOCROP288221_MCnd_AC_SR462,693_.jpg","description":"t-shirt","date":"2024-05-30T15:07:38.101Z","id":"7052022051791447-1717081658101"},{"author":"ManoloC","title":"i love debugging","image":"https://ih1.redbubble.net/image.5079675350.2246/gptr,1400x,front,black-c,188,133,1000,1000-bg,f8f8f8.jpg","description":"otra tshirt","date":"2024-05-30T15:12:22.193Z","id":"3242603140750757-1717081942193"},{"author":"peterpan","title":"I hate onions","image":"https://res.cloudinary.com/teepublic/image/private/s--jk8hOZj1--/t_Resized%20Artwork/c_crop,x_10,y_10/c_fit,h_563/c_crop,g_north_west,h_626,w_470,x_-40,y_-15/g_north_west,u_upload:v1462829018:production:blanks:ekerz3afkzxin2pgqj8h,x_-435,y_-340/b_rgb:eeeeee/c_limit,f_auto,h_630,q_auto:good:420,w_630/v1704062586/production/designs/55814456_0.jpg","description":"camiseta","date":"2024-05-30T15:19:04.125Z","id":"4007381802005925-1717082344121"},{"author":"pepitogrillo","title":"this is me","image":"https://pastaypizzagrossi.com/wp-content/uploads/2015/11/pepito.png","description":"PepitoG","date":"2024-06-03T15:37:09.141Z","id":"7816694399029667-1717429029143"},{"author":"PabloP","title":"yo","image":"https://imgs.search.brave.com/shWZquMWkPDaIeX0KktOS6CA0nC8DjMZ7f8UNHr3FIc/rs:fit:500:0:0/g:ce/aHR0cHM6Ly9oaXBz/LmhlYXJzdGFwcHMu/Y29tL2htZy1wcm9k/L2ltYWdlcy9hdXRv/cnJldHRhcm8tMTkw/Ny0xNjU3ODA0Mzg5/LmpwZWc_Y3JvcD0x/eHc6MXhoO2NlbnRl/cix0b3AmcmVzaXpl/PTk4MDoq","description":"my portrait","date":"2024-06-03T16:49:06.088Z","id":"6226364135019973-1717433346091"},{"author":"peterpan","title":"NBA","image":"https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHJla2VldzRxODB3M25lZmw4eHo4aXBnb2dnOGZkNjR0aHAxZGw2MCZlcD12MV9naWZzX3RyZW5kaW5nJmN0PWc/q45TMknC4xNUCfZt6H/giphy.gif","description":"PlayOffs","date":"2024-06-05T14:54:30.056Z","id":"8142909801569895-1717599270057"},{"author":"WendyD","title":"dancing","image":"https://media.giphy.com/media/iibH5ymW6LFvSIVyUc/giphy.gif?cid=790b76118rekeew4q80w3nefl8xz8ipgogg8fd64thp1dl60&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"girl dancing","date":"2024-06-05T16:59:52.426Z","id":"9678571314947659-1717606792429"},{"author":"peterpan","title":"thursday","image":"https://media.giphy.com/media/H3NC55FLtoF3RXM3eL/giphy.gif?cid=790b7611yhopdjk154taitnd087agc4kk9f1mv61gmkvlv4l&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"hege","date":"2024-06-13T17:37:30.738Z","id":"15869690379310386-1718300250740"},{"author":"peterpan","title":"carrey","image":"https://media.giphy.com/media/dRvEZLV0ORAmHT1L5u/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"jim","date":"2024-06-17T09:06:47.560Z","id":"35807982447313225-1718615207560"},{"author":"peterpan","title":"dfhdfhz","image":"https://media.giphy.com/media/UuB5lh1bL1Dl6svihe/giphy.gif?cid=82a1493bljazeirf80bswzzbztripbnc5hfph6gll89r3spz&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"hugs","date":"2024-06-17T11:31:15.209Z","id":"27637147804292184-1718623875210"},{"author":"peterpan","title":"vaqueroooo","image":"https://media.giphy.com/media/SAUOBJogCbegrukfwR/giphy.gif?cid=82a1493b1bk1hxb7r6ubjt02jfxyvwxpt4sqx0x3j3h0zc03&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"yayyyy!","date":"2024-06-17T11:49:05.188Z","id":"381087757154702-1718624945188"},{"author":"ManoloC","title":"ghjkgh","image":"https://media.giphy.com/media/n1rwdMK9xlxxNNMyQo/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"dfhdzfh","date":"2024-06-18T14:08:39.919Z","id":"9633525110445467-1718719719920"},{"author":"pepitogrillo","title":"jeje","image":"https://media.giphy.com/media/Z21HJj2kz9uBG/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"kiss","date":"2024-06-18T14:40:47.925Z","id":"24161165284086827-1718721647927"},{"author":"manzana","title":"asd","image":"https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExdXc4OWU0ZHBvNHN2YWk3cTZzdWxoNHU3eWVhdWRxaXBzZTBpOGQybyZlcD12MV9naWZzX3RyZW5kaW5nJmN0PWc/TSHnt3RWiyHMFQfEfb/giphy.gif","description":"yeyyy","date":"2024-06-19T14:07:26.245Z","id":"9557888858059542-1718806046245"},{"author":"manzana","title":"sdfsd","image":"https://media.giphy.com/media/n1rwdMK9xlxxNNMyQo/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"sda","date":"2024-06-19T14:31:27.502Z","id":"7817673189885932-1718807487503"},{"author":"peterpan","title":"gvhghj","image":"https://media.giphy.com/media/Ut8FZWMUJW0bv9D4yp/giphy.gif?cid=82a1493bovf54f44fmw2x87b67hna5ob4q1k2xu3o9bjn088&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"fhddf","date":"2024-06-19T14:50:12.739Z","id":"21922868041727006-1718808612739"},{"author":"pepitogrillo","title":"blah","image":"https://upload.wikimedia.org/wikipedia/commons/1/1d/Blah_Blah_Blah.jpg","description":"blah blah","date":"2024-06-19T14:58:34.390Z","id":"7876550578905213-1718809114390"},{"author":"dana","title":"yo","image":"https://media.giphy.com/media/MtsBHd0UsiH7t6twq0/giphy.gif?cid=ecf05e47lglfhzk0hbmna8m51kdi2kevqjt5ek7z0fbavxxc&ep=v1_gifs_search&rid=giphy.gif&ct=g","description":"uummmm","date":"2024-06-20T10:06:36.852Z","id":"020361918299558024-1718877996853"},{"author":"dana","title":"otra","image":"https://media.giphy.com/media/hwFK2j1eRhdb907HsP/giphy.gif?cid=ecf05e47zprrxyc9uxhqp072uvzquh5chdvbr4arp89n2kzj&ep=v1_gifs_search&rid=giphy.gif&ct=g","description":"kiss","date":"2024-06-20T10:21:40.696Z","id":"10717352530499946-1718878900697"},{"author":"manzana","title":"yo corriendo","image":"https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExOWF4a2RqYXM4cWNsZnc5N2E2Ymtld3dyc3hzYWZwdGpsamF3a3BnaSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/26xBPapqZgN5M1KrC/giphy.gif","description":"aaahhhhhhhh","date":"2024-06-20T10:22:44.327Z","id":"8613226125715236-1718878964328"},{"author":"banana","title":"loqsea","image":"https://media.giphy.com/media/gOxwYtDuSzty5mK5fz/giphy.gif?cid=790b7611zp7uyzpga8c8lslbkiczzs214mmmzi9x7htq0jee&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"no se","date":"2024-06-20T14:44:14.343Z","id":"9947879829383515-1718894654345"},{"author":"banana","title":"estesoyyo","image":"https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExd2F3OXQ0cXRpM24xZ2I2enJwdGtveGQ0YW1zOXZ3bjcyMml1anpwaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/2vSk4f18Fyw2f26G32/giphy.gif","description":"buscando hormigas","date":"2024-06-20T14:45:44.496Z","id":"22431576898690864-1718894744497"},{"author":"manzana","title":"otra apple","image":"https://media.giphy.com/media/i6JLRbk4f2gIU/giphy.gif?cid=790b7611k7lrszopgcy29v2keupnx3rax7vzuljrbs0dhcrs&ep=v1_gifs_search&rid=giphy.gif&ct=g","description":"eat it","date":"2024-06-20T15:50:06.012Z","id":"03263413950129945-1718898606013"},{"author":"dana","title":"besoos","image":"https://media.giphy.com/media/25XO1esvlqDIs/giphy.gif?cid=790b7611c5y2wb9yp57mchenwrdhb1g2mnpqc2fo7qo7mgrv&ep=v1_gifs_search&rid=giphy.gif&ct=g","description":"muahh","date":"2024-06-23T20:07:14.877Z","id":"204864289519759-1719173234878"}] \ No newline at end of file +[ + { + "author": "pepitogrillo", + "title": "blah", + "image": "https://m.media-amazon.com/images/I/41xsPjrM-pL._AC_UF350,350_QL50_.jpg", + "description": "blah blah", + "id": "5879244716997389-1716667549269", + "date": "2024-05-25T20:05:49.269Z" + }, + { + "id": "5424401351689265-1716995937318", + "author": "WendyD", + "title": "asfaF", + "image": "https://media.giphy.com/media/xTiTntKyFNFbCNuqkw/giphy.gif?cid=790b76117ksklq64slgwdawn5cmtm14enobheew3nkecwdq1&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "ASAFA", + "date": "2024-05-29T15:18:57.318Z" + }, + { + "author": "peterpan", + "title": "hello world", + "image": "https://miro.medium.com/v2/resize:fit:1024/1*OohqW5DGh9CQS4hLY5FXzA.png", + "description": "console.log(\"hello world\")", + "date": "2024-05-30T13:46:33.345Z", + "id": "2575794271140359-1717076793345" + }, + { + "author": "peterpan", + "title": "blah", + "image": "https://upload.wikimedia.org/wikipedia/commons/1/1d/Blah_Blah_Blah.jpg", + "description": "blah blah", + "date": "2024-05-30T14:07:06.222Z", + "id": "03238060139373644-1717078026222" + }, + { + "author": "peterpan", + "title": "i love js", + "image": "https://images-na.ssl-images-amazon.com/images/I/61VmREcLaFL._SLDPMOBCAROUSELAUTOCROP288221_MCnd_AC_SR462,693_.jpg", + "description": "t-shirt", + "date": "2024-05-30T15:07:38.101Z", + "id": "7052022051791447-1717081658101" + }, + { + "author": "ManoloC", + "title": "i love debugging", + "image": "https://ih1.redbubble.net/image.5079675350.2246/gptr,1400x,front,black-c,188,133,1000,1000-bg,f8f8f8.jpg", + "description": "otra tshirt", + "date": "2024-05-30T15:12:22.193Z", + "id": "3242603140750757-1717081942193" + }, + { + "author": "peterpan", + "title": "I hate onions", + "image": "https://res.cloudinary.com/teepublic/image/private/s--jk8hOZj1--/t_Resized%20Artwork/c_crop,x_10,y_10/c_fit,h_563/c_crop,g_north_west,h_626,w_470,x_-40,y_-15/g_north_west,u_upload:v1462829018:production:blanks:ekerz3afkzxin2pgqj8h,x_-435,y_-340/b_rgb:eeeeee/c_limit,f_auto,h_630,q_auto:good:420,w_630/v1704062586/production/designs/55814456_0.jpg", + "description": "camiseta", + "date": "2024-05-30T15:19:04.125Z", + "id": "4007381802005925-1717082344121" + }, + { + "author": "pepitogrillo", + "title": "this is me", + "image": "https://pastaypizzagrossi.com/wp-content/uploads/2015/11/pepito.png", + "description": "PepitoG", + "date": "2024-06-03T15:37:09.141Z", + "id": "7816694399029667-1717429029143" + }, + { + "author": "PabloP", + "title": "yo", + "image": "https://imgs.search.brave.com/shWZquMWkPDaIeX0KktOS6CA0nC8DjMZ7f8UNHr3FIc/rs:fit:500:0:0/g:ce/aHR0cHM6Ly9oaXBz/LmhlYXJzdGFwcHMu/Y29tL2htZy1wcm9k/L2ltYWdlcy9hdXRv/cnJldHRhcm8tMTkw/Ny0xNjU3ODA0Mzg5/LmpwZWc_Y3JvcD0x/eHc6MXhoO2NlbnRl/cix0b3AmcmVzaXpl/PTk4MDoq", + "description": "my portrait", + "date": "2024-06-03T16:49:06.088Z", + "id": "6226364135019973-1717433346091" + }, + { + "author": "peterpan", + "title": "NBA", + "image": "https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHJla2VldzRxODB3M25lZmw4eHo4aXBnb2dnOGZkNjR0aHAxZGw2MCZlcD12MV9naWZzX3RyZW5kaW5nJmN0PWc/q45TMknC4xNUCfZt6H/giphy.gif", + "description": "PlayOffs", + "date": "2024-06-05T14:54:30.056Z", + "id": "8142909801569895-1717599270057" + }, + { + "author": "WendyD", + "title": "dancing", + "image": "https://media.giphy.com/media/iibH5ymW6LFvSIVyUc/giphy.gif?cid=790b76118rekeew4q80w3nefl8xz8ipgogg8fd64thp1dl60&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "girl dancing", + "date": "2024-06-05T16:59:52.426Z", + "id": "9678571314947659-1717606792429" + }, + { + "author": "peterpan", + "title": "thursday", + "image": "https://media.giphy.com/media/H3NC55FLtoF3RXM3eL/giphy.gif?cid=790b7611yhopdjk154taitnd087agc4kk9f1mv61gmkvlv4l&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "hege", + "date": "2024-06-13T17:37:30.738Z", + "id": "15869690379310386-1718300250740" + }, + { + "author": "peterpan", + "title": "carrey", + "image": "https://media.giphy.com/media/dRvEZLV0ORAmHT1L5u/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "jim", + "date": "2024-06-17T09:06:47.560Z", + "id": "35807982447313225-1718615207560" + }, + { + "author": "peterpan", + "title": "dfhdfhz", + "image": "https://media.giphy.com/media/UuB5lh1bL1Dl6svihe/giphy.gif?cid=82a1493bljazeirf80bswzzbztripbnc5hfph6gll89r3spz&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "hugs", + "date": "2024-06-17T11:31:15.209Z", + "id": "27637147804292184-1718623875210" + }, + { + "author": "peterpan", + "title": "vaqueroooo", + "image": "https://media.giphy.com/media/SAUOBJogCbegrukfwR/giphy.gif?cid=82a1493b1bk1hxb7r6ubjt02jfxyvwxpt4sqx0x3j3h0zc03&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "yayyyy!", + "date": "2024-06-17T11:49:05.188Z", + "id": "381087757154702-1718624945188" + }, + { + "author": "ManoloC", + "title": "ghjkgh", + "image": "https://media.giphy.com/media/n1rwdMK9xlxxNNMyQo/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "dfhdzfh", + "date": "2024-06-18T14:08:39.919Z", + "id": "9633525110445467-1718719719920" + }, + { + "author": "pepitogrillo", + "title": "jeje", + "image": "https://media.giphy.com/media/Z21HJj2kz9uBG/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "kiss", + "date": "2024-06-18T14:40:47.925Z", + "id": "24161165284086827-1718721647927" + }, + { + "author": "manzana", + "title": "asd", + "image": "https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExdXc4OWU0ZHBvNHN2YWk3cTZzdWxoNHU3eWVhdWRxaXBzZTBpOGQybyZlcD12MV9naWZzX3RyZW5kaW5nJmN0PWc/TSHnt3RWiyHMFQfEfb/giphy.gif", + "description": "yeyyy", + "date": "2024-06-19T14:07:26.245Z", + "id": "9557888858059542-1718806046245" + }, + { + "author": "manzana", + "title": "sdfsd", + "image": "https://media.giphy.com/media/n1rwdMK9xlxxNNMyQo/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "sda", + "date": "2024-06-19T14:31:27.502Z", + "id": "7817673189885932-1718807487503" + }, + { + "author": "peterpan", + "title": "gvhghj", + "image": "https://media.giphy.com/media/Ut8FZWMUJW0bv9D4yp/giphy.gif?cid=82a1493bovf54f44fmw2x87b67hna5ob4q1k2xu3o9bjn088&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "fhddf", + "date": "2024-06-19T14:50:12.739Z", + "id": "21922868041727006-1718808612739" + }, + { + "author": "pepitogrillo", + "title": "blah", + "image": "https://upload.wikimedia.org/wikipedia/commons/1/1d/Blah_Blah_Blah.jpg", + "description": "blah blah", + "date": "2024-06-19T14:58:34.390Z", + "id": "7876550578905213-1718809114390" + }, + { + "author": "dana", + "title": "yo", + "image": "https://media.giphy.com/media/MtsBHd0UsiH7t6twq0/giphy.gif?cid=ecf05e47lglfhzk0hbmna8m51kdi2kevqjt5ek7z0fbavxxc&ep=v1_gifs_search&rid=giphy.gif&ct=g", + "description": "uummmm", + "date": "2024-06-20T10:06:36.852Z", + "id": "020361918299558024-1718877996853" + }, + { + "author": "dana", + "title": "otra", + "image": "https://media.giphy.com/media/hwFK2j1eRhdb907HsP/giphy.gif?cid=ecf05e47zprrxyc9uxhqp072uvzquh5chdvbr4arp89n2kzj&ep=v1_gifs_search&rid=giphy.gif&ct=g", + "description": "kiss", + "date": "2024-06-20T10:21:40.696Z", + "id": "10717352530499946-1718878900697" + }, + { + "author": "manzana", + "title": "yo corriendo", + "image": "https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExOWF4a2RqYXM4cWNsZnc5N2E2Ymtld3dyc3hzYWZwdGpsamF3a3BnaSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/26xBPapqZgN5M1KrC/giphy.gif", + "description": "aaahhhhhhhh", + "date": "2024-06-20T10:22:44.327Z", + "id": "8613226125715236-1718878964328" + }, + { + "author": "banana", + "title": "loqsea", + "image": "https://media.giphy.com/media/gOxwYtDuSzty5mK5fz/giphy.gif?cid=790b7611zp7uyzpga8c8lslbkiczzs214mmmzi9x7htq0jee&ep=v1_gifs_trending&rid=giphy.gif&ct=g", + "description": "no se", + "date": "2024-06-20T14:44:14.343Z", + "id": "9947879829383515-1718894654345" + }, + { + "author": "banana", + "title": "estesoyyo", + "image": "https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExd2F3OXQ0cXRpM24xZ2I2enJwdGtveGQ0YW1zOXZ3bjcyMml1anpwaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/2vSk4f18Fyw2f26G32/giphy.gif", + "description": "buscando hormigas", + "date": "2024-06-20T14:45:44.496Z", + "id": "22431576898690864-1718894744497" + }, + { + "author": "manzana", + "title": "otra apple", + "image": "https://media.giphy.com/media/i6JLRbk4f2gIU/giphy.gif?cid=790b7611k7lrszopgcy29v2keupnx3rax7vzuljrbs0dhcrs&ep=v1_gifs_search&rid=giphy.gif&ct=g", + "description": "eat it", + "date": "2024-06-20T15:50:06.012Z", + "id": "03263413950129945-1718898606013" + }, + { + "author": "dana", + "title": "besoos", + "image": "https://media.giphy.com/media/25XO1esvlqDIs/giphy.gif?cid=790b7611c5y2wb9yp57mchenwrdhb1g2mnpqc2fo7qo7mgrv&ep=v1_gifs_search&rid=giphy.gif&ct=g", + "description": "muahh", + "date": "2024-06-23T20:07:14.877Z", + "id": "204864289519759-1719173234878" + }, + { + "author": "jameshook", + "title": "smile 2", + "image": "https://m.media-amazon.com/images/I/41xsPjrM-pL._AC_UF350,350_QL50_.jpg", + "description": "hi 2", + "date": "2024-06-24T19:54:40.140Z", + "id": "24649389543661626-1719258880141" + } +] \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api/data/users.json b/staff/eduardo-sanchez/socialcode/api/data/users.json index 1b383841f..4ed865697 100644 --- a/staff/eduardo-sanchez/socialcode/api/data/users.json +++ b/staff/eduardo-sanchez/socialcode/api/data/users.json @@ -54,5 +54,12 @@ "email": "pablo@picasso.com", "username": "PabloP", "password": "$2a$08$UFSFpsfswc.jmgZtLVTLI.PXz0eNMrQW6DI/y/jNIdif2q8C2b4Te" + }, + { + "name": "James", + "surname": "Hook", + "email": "james@hook.com", + "username": "jameshook", + "password": "$2a$10$als5ALhJ0eaUX5cgfD.EFOuPZAYu1AmmZY76aNWn5ZHP6/ty1XwEq" } ] \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/.env b/staff/eduardo-sanchez/socialcode/api_/.env new file mode 100644 index 000000000..9316658a1 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/.env @@ -0,0 +1,3 @@ +PORT = 9010 + +JWT_SECRET = ManoloC & PedroP are friends \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/.gitignore b/staff/eduardo-sanchez/socialcode/api_/.gitignore new file mode 100644 index 000000000..8f7b39f43 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/.gitignore @@ -0,0 +1,2 @@ +node_modules +!.env \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/README.md b/staff/eduardo-sanchez/socialcode/api_/README.md new file mode 100644 index 000000000..e6ffacfca --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/README.md @@ -0,0 +1,61 @@ +- list users + +```sh +🐖 curl http://localhost:8080/users -v +``` + +- register user + +```sh +🐖 curl -X POST http://localhost:8080/users -H "Content-Type: application/json" -d '{"name":"Pepito","surname":"Grillo","email":"pepito@grillo.com","username":"pepitogrillo","password":"123123123","passwordRepeat":"123123123"}' -v +``` + +- authenticate user + +```sh +🐖 curl -X POST http://localhost:8080/users/auth -H "Content-Type: application/json" -d '{"username":"pepitogrillo","password":"123123123"}' -v +``` + +- get user name + +```sh +🐖 curl http://localhost:8080/users/pepitogrillo -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJwZXBpdG9ncmlsbG8iLCJpYXQiOjE3MTg3OTg5NjgsImV4cCI6MTcxODgwMjU2OH0.aX_xV3VSpHrbDqznlPfAORLCCEQlnxM-Zt8ubmStzA4" -v + +🐖 curl http://localhost:8080/users/pepitogrillo -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJwZXRlcnBhbiIsImlhdCI6MTcxODc5ODk2OCwiZXhwIjoxNzE4ODAyNTY4fQ.aX_xV3VSpHrbDqznlPfAORLCCEQlnxM-Zt8ubmStzA4" -v + +/////////////////////////////////////////////////////////////////////// + +🐖 curl http://localhost:8080/users/manzana -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJwZXBpdG9ncmlsbG8iLCJpYXQiOjE3MTg4MDE2MDAsImV4cCI6MTcxODgwNTIwMH0.sGk2sd-sR5oF5xZVyBkxIl3surLx4bkuq5GTMxptp0Y" -v + +🐖 curl http://localhost:8080/users/manzana -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtYW56YW5hIiwiaWF0IjoxNzE4ODAxNjAwLCJleHAiOjE3MTg4MDUyMDB9.sGk2sd-sR5oF5xZVyBkxIl3surLx4bkuq5GTMxptp0Y" -v +``` + +- get all posts + +```sh +🐖 curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJwZXBpdG9ncmlsbG8iLCJpYXQiOjE3MTg4MTE5MTgsImV4cCI6MTcxODgxNTUxOH0.pbiutUd6MogOdsPE8YvLVigidyuAVQEPhegaj9Ena4w" http://localhost:8080/posts -v + + +🐖 curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJwZXBpdG9ncmlsbG8iLCJpYXQiOjE3MTg3OTg5NjgsImV4cCI6MTcxODgwMjU2OH0.aX_xV3VSpHrbDqznlPfAORLCCEQlnxM-Zt8ubmStzA4" http://localhost:8080/posts -v + + +``` + +- create post + +```sh +🐖 curl -X POST http://localhost:8080/posts -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJwZXBpdG9ncmlsbG8iLCJpYXQiOjE3MTg4MDkwODEsImV4cCI6MTcxODgxMjY4MX0.MBrSi-L8rPKH-E0EzIW268dMbb0AsEBnaPYLEzhoR78" -H "Content-Type: application/json" -d '{"title":"blah","image":"https://upload.wikimedia.org/wikipedia/commons/1/1d/Blah_Blah_Blah.jpg","description":"blah blah"}' -v +``` + +- delete post + +```sh +🐖 curl -X DELETE http://localhost:8080/posts/4007381802005925-1717082344121 -H "Authorization: Basic peterpan" -v +``` + +- comprobacion acceso cabeceras CORS +Cuando un navegador realiza una solicitud HTTP a un servidor en un dominio diferente, envía una solicitud preflight (de verificación previa) utilizando el método OPTIONS. Esta solicitud verifica si el servidor permite la solicitud real. + +```sh +🐖 curl -X OPTIONS http://localhost:8080/users/auth -v +``` \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/data/index.js b/staff/eduardo-sanchez/socialcode/api_/data/index.js new file mode 100644 index 000000000..7e738a0f0 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/data/index.js @@ -0,0 +1,150 @@ +import fs from 'fs' +import { SystemError } from 'com/errors.js' + +const data = {} + +data.findUser = (condition, callback) => { + fs.readFile('./data/users.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const users = JSON.parse(json) + + const user = users.find(condition) + + callback(null, user) + }) +} + +data.insertUser = (user, callback) => { + fs.readFile('./data/users.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const users = JSON.parse(json) + + users.push(user) + + const newJson = JSON.stringify(users) + + fs.writeFile('./data/users.json', newJson, error => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + callback(null) + }) + }) +} + +data.findPosts = (condition, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const posts = JSON.parse(json) + + const filtered = posts.filter(condition) + + callback(null, filtered) + }) +} + +data.findPost = (condition, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const posts = JSON.parse(json) + + const post = posts.find(condition) + + callback(null, post) + }) +} + +data.insertPost = (post, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const posts = JSON.parse(json) + + post.id = `${Math.random().toString().slice(2)}-${Date.now()}` + + posts.push(post) + + const newJson = JSON.stringify(posts) + + fs.writeFile('./data/posts.json', newJson, error => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + callback(null) + }) + }) +} + +data.deletePost = (condition, callback) => { + fs.readFile('./data/posts.json', 'utf8', (error, json) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!json) json = '[]' + + const posts = JSON.parse(json) + + const index = posts.findIndex(condition) + + if (index > -1) { + posts.splice(index, 1) + + const newJson = JSON.stringify(posts) + + fs.writeFile('./data/posts.json', newJson, error => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + callback(null) + }) + } else callback(null) + }) +} + +export default data \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/data/index.test.js b/staff/eduardo-sanchez/socialcode/api_/data/index.test.js new file mode 100644 index 000000000..78114d7db --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/data/index.test.js @@ -0,0 +1,56 @@ +import data from './index.js' + +// data.findUser(user => user.surname === 'Grillo', (error, user) => { +// if (error) { +// console.error(error) + +// return +// } + +// console.log(user) +// }) + +// data.insertUser({ name: 'James', surname: 'Hook', email: 'james@hook.com', username: 'jameshook', password: '123123123' }, error => { +// if (error) { +// console.error(error) + +// return +// } + +// console.log('user inserted') +// }) + +// data.findPosts(post => post.date.includes('T19'), (error, posts) => { +// if (error) { +// console.error(error) + +// return +// } + +// console.log(posts) +// }) + +// data.insertPost({ +// author: 'jameshook', +// title: 'smile 2', +// image: 'https://m.media-amazon.com/images/I/41xsPjrM-pL._AC_UF350,350_QL50_.jpg', description: 'hi 2', +// date: new Date().toISOString() +// }, error => { +// if (error) { +// console.error(error) + +// return +// } + +// console.log('post inserted') +// }) + +data.deletePost(post => post.title === 'smile 2', error => { + if (error) { + console.error(error) + + return + } + + console.log('post deleted') +}) \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/data/posts.json b/staff/eduardo-sanchez/socialcode/api_/data/posts.json new file mode 100644 index 000000000..b5587163f --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/data/posts.json @@ -0,0 +1 @@ +[{"author":"pepitogrillo","title":"blah","image":"https://m.media-amazon.com/images/I/41xsPjrM-pL._AC_UF350,350_QL50_.jpg","description":"blah blah","id":"5879244716997389-1716667549269","date":"2024-05-25T20:05:49.269Z"},{"id":"5424401351689265-1716995937318","author":"WendyD","title":"asfaF","image":"https://media.giphy.com/media/xTiTntKyFNFbCNuqkw/giphy.gif?cid=790b76117ksklq64slgwdawn5cmtm14enobheew3nkecwdq1&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"ASAFA","date":"2024-05-29T15:18:57.318Z"},{"author":"peterpan","title":"hello world","image":"https://miro.medium.com/v2/resize:fit:1024/1*OohqW5DGh9CQS4hLY5FXzA.png","description":"console.log(\"hello world\")","date":"2024-05-30T13:46:33.345Z","id":"2575794271140359-1717076793345"},{"author":"peterpan","title":"blah","image":"https://upload.wikimedia.org/wikipedia/commons/1/1d/Blah_Blah_Blah.jpg","description":"blah blah","date":"2024-05-30T14:07:06.222Z","id":"03238060139373644-1717078026222"},{"author":"peterpan","title":"i love js","image":"https://images-na.ssl-images-amazon.com/images/I/61VmREcLaFL._SLDPMOBCAROUSELAUTOCROP288221_MCnd_AC_SR462,693_.jpg","description":"t-shirt","date":"2024-05-30T15:07:38.101Z","id":"7052022051791447-1717081658101"},{"author":"ManoloC","title":"i love debugging","image":"https://ih1.redbubble.net/image.5079675350.2246/gptr,1400x,front,black-c,188,133,1000,1000-bg,f8f8f8.jpg","description":"otra tshirt","date":"2024-05-30T15:12:22.193Z","id":"3242603140750757-1717081942193"},{"author":"peterpan","title":"I hate onions","image":"https://res.cloudinary.com/teepublic/image/private/s--jk8hOZj1--/t_Resized%20Artwork/c_crop,x_10,y_10/c_fit,h_563/c_crop,g_north_west,h_626,w_470,x_-40,y_-15/g_north_west,u_upload:v1462829018:production:blanks:ekerz3afkzxin2pgqj8h,x_-435,y_-340/b_rgb:eeeeee/c_limit,f_auto,h_630,q_auto:good:420,w_630/v1704062586/production/designs/55814456_0.jpg","description":"camiseta","date":"2024-05-30T15:19:04.125Z","id":"4007381802005925-1717082344121"},{"author":"pepitogrillo","title":"this is me","image":"https://pastaypizzagrossi.com/wp-content/uploads/2015/11/pepito.png","description":"PepitoG","date":"2024-06-03T15:37:09.141Z","id":"7816694399029667-1717429029143"},{"author":"PabloP","title":"yo","image":"https://imgs.search.brave.com/shWZquMWkPDaIeX0KktOS6CA0nC8DjMZ7f8UNHr3FIc/rs:fit:500:0:0/g:ce/aHR0cHM6Ly9oaXBz/LmhlYXJzdGFwcHMu/Y29tL2htZy1wcm9k/L2ltYWdlcy9hdXRv/cnJldHRhcm8tMTkw/Ny0xNjU3ODA0Mzg5/LmpwZWc_Y3JvcD0x/eHc6MXhoO2NlbnRl/cix0b3AmcmVzaXpl/PTk4MDoq","description":"my portrait","date":"2024-06-03T16:49:06.088Z","id":"6226364135019973-1717433346091"},{"author":"peterpan","title":"NBA","image":"https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHJla2VldzRxODB3M25lZmw4eHo4aXBnb2dnOGZkNjR0aHAxZGw2MCZlcD12MV9naWZzX3RyZW5kaW5nJmN0PWc/q45TMknC4xNUCfZt6H/giphy.gif","description":"PlayOffs","date":"2024-06-05T14:54:30.056Z","id":"8142909801569895-1717599270057"},{"author":"WendyD","title":"dancing","image":"https://media.giphy.com/media/iibH5ymW6LFvSIVyUc/giphy.gif?cid=790b76118rekeew4q80w3nefl8xz8ipgogg8fd64thp1dl60&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"girl dancing","date":"2024-06-05T16:59:52.426Z","id":"9678571314947659-1717606792429"},{"author":"peterpan","title":"thursday","image":"https://media.giphy.com/media/H3NC55FLtoF3RXM3eL/giphy.gif?cid=790b7611yhopdjk154taitnd087agc4kk9f1mv61gmkvlv4l&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"hege","date":"2024-06-13T17:37:30.738Z","id":"15869690379310386-1718300250740"},{"author":"peterpan","title":"carrey","image":"https://media.giphy.com/media/dRvEZLV0ORAmHT1L5u/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"jim","date":"2024-06-17T09:06:47.560Z","id":"35807982447313225-1718615207560"},{"author":"peterpan","title":"dfhdfhz","image":"https://media.giphy.com/media/UuB5lh1bL1Dl6svihe/giphy.gif?cid=82a1493bljazeirf80bswzzbztripbnc5hfph6gll89r3spz&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"hugs","date":"2024-06-17T11:31:15.209Z","id":"27637147804292184-1718623875210"},{"author":"peterpan","title":"vaqueroooo","image":"https://media.giphy.com/media/SAUOBJogCbegrukfwR/giphy.gif?cid=82a1493b1bk1hxb7r6ubjt02jfxyvwxpt4sqx0x3j3h0zc03&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"yayyyy!","date":"2024-06-17T11:49:05.188Z","id":"381087757154702-1718624945188"},{"author":"ManoloC","title":"ghjkgh","image":"https://media.giphy.com/media/n1rwdMK9xlxxNNMyQo/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"dfhdzfh","date":"2024-06-18T14:08:39.919Z","id":"9633525110445467-1718719719920"},{"author":"pepitogrillo","title":"jeje","image":"https://media.giphy.com/media/Z21HJj2kz9uBG/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"kiss","date":"2024-06-18T14:40:47.925Z","id":"24161165284086827-1718721647927"},{"author":"manzana","title":"asd","image":"https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExdXc4OWU0ZHBvNHN2YWk3cTZzdWxoNHU3eWVhdWRxaXBzZTBpOGQybyZlcD12MV9naWZzX3RyZW5kaW5nJmN0PWc/TSHnt3RWiyHMFQfEfb/giphy.gif","description":"yeyyy","date":"2024-06-19T14:07:26.245Z","id":"9557888858059542-1718806046245"},{"author":"manzana","title":"sdfsd","image":"https://media.giphy.com/media/n1rwdMK9xlxxNNMyQo/giphy.gif?cid=790b7611uw89e4dpo4svai7q6sulh4u7yeaudqipse0i8d2o&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"sda","date":"2024-06-19T14:31:27.502Z","id":"7817673189885932-1718807487503"},{"author":"peterpan","title":"gvhghj","image":"https://media.giphy.com/media/Ut8FZWMUJW0bv9D4yp/giphy.gif?cid=82a1493bovf54f44fmw2x87b67hna5ob4q1k2xu3o9bjn088&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"fhddf","date":"2024-06-19T14:50:12.739Z","id":"21922868041727006-1718808612739"},{"author":"pepitogrillo","title":"blah","image":"https://upload.wikimedia.org/wikipedia/commons/1/1d/Blah_Blah_Blah.jpg","description":"blah blah","date":"2024-06-19T14:58:34.390Z","id":"7876550578905213-1718809114390"},{"author":"dana","title":"yo","image":"https://media.giphy.com/media/MtsBHd0UsiH7t6twq0/giphy.gif?cid=ecf05e47lglfhzk0hbmna8m51kdi2kevqjt5ek7z0fbavxxc&ep=v1_gifs_search&rid=giphy.gif&ct=g","description":"uummmm","date":"2024-06-20T10:06:36.852Z","id":"020361918299558024-1718877996853"},{"author":"dana","title":"otra","image":"https://media.giphy.com/media/hwFK2j1eRhdb907HsP/giphy.gif?cid=ecf05e47zprrxyc9uxhqp072uvzquh5chdvbr4arp89n2kzj&ep=v1_gifs_search&rid=giphy.gif&ct=g","description":"kiss","date":"2024-06-20T10:21:40.696Z","id":"10717352530499946-1718878900697"},{"author":"manzana","title":"yo corriendo","image":"https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExOWF4a2RqYXM4cWNsZnc5N2E2Ymtld3dyc3hzYWZwdGpsamF3a3BnaSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/26xBPapqZgN5M1KrC/giphy.gif","description":"aaahhhhhhhh","date":"2024-06-20T10:22:44.327Z","id":"8613226125715236-1718878964328"},{"author":"banana","title":"loqsea","image":"https://media.giphy.com/media/gOxwYtDuSzty5mK5fz/giphy.gif?cid=790b7611zp7uyzpga8c8lslbkiczzs214mmmzi9x7htq0jee&ep=v1_gifs_trending&rid=giphy.gif&ct=g","description":"no se","date":"2024-06-20T14:44:14.343Z","id":"9947879829383515-1718894654345"},{"author":"banana","title":"estesoyyo","image":"https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExd2F3OXQ0cXRpM24xZ2I2enJwdGtveGQ0YW1zOXZ3bjcyMml1anpwaCZlcD12MV9naWZzX3NlYXJjaCZjdD1n/2vSk4f18Fyw2f26G32/giphy.gif","description":"buscando hormigas","date":"2024-06-20T14:45:44.496Z","id":"22431576898690864-1718894744497"},{"author":"manzana","title":"otra apple","image":"https://media.giphy.com/media/i6JLRbk4f2gIU/giphy.gif?cid=790b7611k7lrszopgcy29v2keupnx3rax7vzuljrbs0dhcrs&ep=v1_gifs_search&rid=giphy.gif&ct=g","description":"eat it","date":"2024-06-20T15:50:06.012Z","id":"03263413950129945-1718898606013"},{"author":"dana","title":"besoos","image":"https://media.giphy.com/media/25XO1esvlqDIs/giphy.gif?cid=790b7611c5y2wb9yp57mchenwrdhb1g2mnpqc2fo7qo7mgrv&ep=v1_gifs_search&rid=giphy.gif&ct=g","description":"muahh","date":"2024-06-23T20:07:14.877Z","id":"204864289519759-1719173234878"}] \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/data/users.json b/staff/eduardo-sanchez/socialcode/api_/data/users.json new file mode 100644 index 000000000..1b383841f --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/data/users.json @@ -0,0 +1,58 @@ +[ + { + "name": "Pepito", + "surname": "Grillo", + "email": "pepito@grillo.com", + "username": "pepitogrillo", + "password": "$2a$08$RJcBUUN.niT1SIbu4tygGOW/gkUcCh9fm8kR0op26IE.AUv/II8Z2" + }, + { + "name": "manolo", + "surname": "cabezabolo", + "email": "manolo@cabezabolo.com", + "username": "ManoloC", + "password": "$2a$08$UFSFpsfswc.jmgZtLVTLI.PXz0eNMrQW6DI/y/jNIdif2q8C2b4Te" + }, + { + "name": "Man", + "surname": "Zana", + "email": "man@zana.com", + "username": "manzana", + "password": "$2a$08$RJcBUUN.niT1SIbu4tygGOW/gkUcCh9fm8kR0op26IE.AUv/II8Z2" + }, + { + "name": "Da", + "surname": "Na", + "email": "da@na.com", + "username": "dana", + "password": "$2a$08$UFSFpsfswc.jmgZtLVTLI.PXz0eNMrQW6DI/y/jNIdif2q8C2b4Te" + }, + { + "name": "Ba", + "surname": "Nana", + "email": "ba@nana.com", + "username": "banana", + "password": "$2a$08$rOaceeB8Dk6WFfe8ZDr.cOp.yPPPp3G37u28W.bEccATk49gOYtRS" + }, + { + "name": "Peter", + "surname": "Pan", + "email": "peter@pan.com", + "username": "peterpan", + "password": "$2a$08$RJcBUUN.niT1SIbu4tygGOW/gkUcCh9fm8kR0op26IE.AUv/II8Z2" + }, + { + "name": "Wendy", + "surname": "Darling", + "email": "wendy@darling.com", + "username": "wendydarling", + "password": "$2a$08$rOaceeB8Dk6WFfe8ZDr.cOp.yPPPp3G37u28W.bEccATk49gOYtRS" + }, + { + "name": "Pablo", + "surname": "Picasso", + "email": "pablo@picasso.com", + "username": "PabloP", + "password": "$2a$08$UFSFpsfswc.jmgZtLVTLI.PXz0eNMrQW6DI/y/jNIdif2q8C2b4Te" + } +] \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/index.js b/staff/eduardo-sanchez/socialcode/api_/index.js new file mode 100644 index 000000000..31964d589 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/index.js @@ -0,0 +1,160 @@ +import 'dotenv/config' +import express from 'express' +import logic from './logic/index.js' +import cors from 'cors' +import jwt from 'jsonwebtoken' +import { SystemError } from 'com/errors.js' + +const { PORT, JWT_SECRET } = process.env + +const { JsonWebTokenError, TokenExpiredError } = jwt + +const api = express() + +api.use(express.static('public')) + +api.use(cors()) + +api.get('/', (req, res) => res.send('Hello, World!')) + +const jsonBodyParser = express.json({ strict: true, type: 'application/json' }) + +api.post('/users', jsonBodyParser, (req, res) => { + const { name, surname, email, username, password, passwordRepeat } = req.body + + try { + logic.registerUser(name, surname, email, username, password, passwordRepeat, error => { + if (error) { + res.status(500).json({ error: error.constructor.name, message: error.message }) + + return + } + + res.status(201).send() + }) + } catch (error) { + res.status(500).json({ error: error.constructor.name, message: error.message }) + } +}) + + + +api.post('/users/auth', jsonBodyParser, (req, res) => { + const { username, password } = req.body + + try { + logic.authenticateUser(username, password, error => { + if (error) { + res.status(500).json({ error: error.constructor.name, message: error.message }) + + return + } + + const token = jwt.sign({ sub: username }, JWT_SECRET, { expiresIn: '1h' }) + + res.json(token) + }) + } catch (error) { + res.status(500).json({ error: error.constructor.name, message: error.message }) + } +}) + +api.get('/users/:targetUsername', (req, res) => { + try { + const token = req.headers.authorization.slice(7) + + const { sub: username } = jwt.verify(token, JWT_SECRET) + + const { targetUsername } = req.params + + logic.getUserName(username, targetUsername, (error, name) => { + if (error) { + res.status(500).json({ error: error.constructor.name, message: error.message }) + + return + } + + res.json(name) + }) + } catch (error) { + if (error instanceof JsonWebTokenError || error instanceof TokenExpiredError) + res.status(500).json({ error: SystemError.name, message: error.message }) + else + res.status(500).json({ error: error.constructor.name, message: error.message }) + } +}) + +api.get('/posts', (req, res) => { + try { + const token = req.headers.authorization.slice(7) + + const { sub: username } = jwt.verify(token, JWT_SECRET) + + logic.getAllPosts(username, (error, posts) => { + if (error) { + res.status(500).json({ error: error.constructor.name, message: error.message }) + + return + } + + res.json(posts) + }) + } catch (error) { + if (error instanceof JsonWebTokenError || error instanceof TokenExpiredError) + res.status(500).json({ error: SystemError.name, message: error.message }) + else + res.status(500).json({ error: error.constructor.name, message: error.message }) + } +}) + +api.post('/posts', jsonBodyParser, (req, res) => { + try { + const token = req.headers.authorization.slice(7) + + const { sub: username } = jwt.verify(token, JWT_SECRET) + + const { title, image, description } = req.body + + logic.createPost(username, title, image, description, error => { + if (error) { + res.status(500).json({ error: error.constructor.name, message: error.message }) + + return + } + + res.status(201).send() + }) + } catch (error) { + if (error instanceof JsonWebTokenError || error instanceof TokenExpiredError) + res.status(500).json({ error: SystemError.name, message: error.message }) + else + res.status(500).json({ error: error.constructor.name, message: error.message }) + } +}) + +api.delete('/posts/:postId', (req, res) => { + try { + const token = req.headers.authorization.slice(7) + + const { sub: username } = jwt.verify(token, JWT_SECRET) + + const { postId } = req.params + + logic.deletePost(username, postId, error => { + if (error) { + res.status(500).json({ error: error.constructor.name, message: error.message }) + + return + } + + res.status(204).send() + }) + } catch (error) { + if (error instanceof JsonWebTokenError || error instanceof TokenExpiredError) + res.status(500).json({ error: SystemError.name, message: error.message }) + else + res.status(500).json({ error: error.constructor.name, message: error.message }) + } +}) + +api.listen(PORT, () => console.log(`API running on PORT ${PORT}`)) \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/authenticateUser.js b/staff/eduardo-sanchez/socialcode/api_/logic/authenticateUser.js new file mode 100644 index 000000000..46c1f70e5 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/authenticateUser.js @@ -0,0 +1,42 @@ +import data from '../data/index.js' +import { MatchError } from 'com/errors.js' +import validate from 'com/validate.js' +import bcrypt from 'bcryptjs' + +const authenticateUser = (username, password, callback) => { + validate.username(username) + validate.password(password) + validate.callback(callback) + + data.findUser(user => user.username === username, (error, user) => { + if (error) { + callback(error) + + return + } + + if (!user) { + callback(new MatchError('user not found')) + + return + } + + bcrypt.compare(password, user.password, (error, match) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + if (!match) { + callback(new MatchError('wrong password')) + + return + } + + callback(null) + }) + }) +} + +export default authenticateUser \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/authenticateUser.test.js b/staff/eduardo-sanchez/socialcode/api_/logic/authenticateUser.test.js new file mode 100644 index 000000000..81d434a99 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/authenticateUser.test.js @@ -0,0 +1,16 @@ +import logic from './index.js' + +try { + logic.authenticateUser('peterpan', '123123123', error => { + // logic.authenticateUser('dana', 'Hola1234', error => { + if (error) { + console.error(error) + + return + } + + console.log('user authenticated') + }) +} catch (error) { + console.error(error) +} diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/createPost.js b/staff/eduardo-sanchez/socialcode/api_/logic/createPost.js new file mode 100644 index 000000000..ee7a782c8 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/createPost.js @@ -0,0 +1,45 @@ +import data from '../data/index.js' +import { MatchError } from 'com/errors.js' +import validate from 'com/validate.js' + +const createPost = (username, title, image, description, callback) => { + validate.username(username) + validate.text(title, 'title', 50) + validate.url(image, 'image') + validate.text(description, 'description', 200) + validate.callback(callback) + + data.findUser(user => user.username === username, (error, user) => { + if (error) { + callback(error) + + return + } + + if (!user) { + callback(new MatchError('user not found')) + + return + } + + const post = { + author: username, + title, + image, + description, + date: new Date().toISOString() + } + + data.insertPost(post, error => { + if (error) { + callback(error) + + return + } + + callback(null) + }) + }) +} + +export default createPost \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/createPost.test.js b/staff/eduardo-sanchez/socialcode/api_/logic/createPost.test.js new file mode 100644 index 000000000..2d643804e --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/createPost.test.js @@ -0,0 +1,15 @@ +import logic from './index.js' + +try { + logic.createPost('peterpan', 'hello world', 'https://miro.medium.com/v2/resize:fit:1024/1*OohqW5DGh9CQS4hLY5FXzA.png', 'console.log("hello world")', error => { + if (error) { + console.error(error) + + return + } + + console.log('post created') + }) +} catch (error) { + console.error(error) +} \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/deletePost.js b/staff/eduardo-sanchez/socialcode/api_/logic/deletePost.js new file mode 100644 index 000000000..13351238f --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/deletePost.js @@ -0,0 +1,55 @@ +import data from '../data/index.js' +import { MatchError } from 'com/errors.js' +import validate from 'com/validate.js' + +const deletePost = (username, postId, callback) => { + validate.username(username) + validate.id(postId, 'postId') + validate.callback(callback) + + data.findUser(user => user.username === username, (error, user) => { + if (error) { + callback(error) + + return + } + + if (!user) { + callback(new MatchError('user not found')) + + return + } + + data.findPost(post => post.id === postId, (error, post) => { + if (error) { + callback(error) + + return + } + + if (!post) { + callback(new MatchError('post not found')) + + return + } + + if (post.author !== username) { + callback(new MatchError('post author does not match user')) + + return + } + + data.deletePost(post => post.id === postId, error => { + if (error) { + callback(error) + + return + } + + callback(null) + }) + }) + }) +} + +export default deletePost \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/deletePost.test.js b/staff/eduardo-sanchez/socialcode/api_/logic/deletePost.test.js new file mode 100644 index 000000000..4b5025cb1 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/deletePost.test.js @@ -0,0 +1,15 @@ +import logic from './index.js' + +try { + logic.deletePost('peterpan', '17164141890669127-1718895026735', error => { + if (error) { + console.error(error) + + return + } + + console.log('post deleted') + }) +} catch (error) { + console.error(error) +} \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/getAllPosts.js b/staff/eduardo-sanchez/socialcode/api_/logic/getAllPosts.js new file mode 100644 index 000000000..b78308854 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/getAllPosts.js @@ -0,0 +1,34 @@ +import data from '../data/index.js' +import { MatchError } from 'com/errors.js' +import validate from 'com/validate.js' + +const getAllPosts = (username, callback) => { + validate.username(username) + validate.callback(callback) + + data.findUser(user => user.username === username, (error, user) => { + if (error) { + callback(error) + + return + } + + if (!user) { + callback(new MatchError('user not found')) + + return + } + + data.findPosts(() => true, (error, posts) => { + if (error) { + callback(error) + + return + } + + callback(null, posts.reverse()) + }) + }) +} + +export default getAllPosts \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/getAllPosts.test.js b/staff/eduardo-sanchez/socialcode/api_/logic/getAllPosts.test.js new file mode 100644 index 000000000..b24eeea4c --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/getAllPosts.test.js @@ -0,0 +1,15 @@ +import logic from './index.js' + +try { + logic.getAllPosts('pepitogrillo', (error, posts) => { + if (error) { + console.error(error) + + return + } + + console.log('posts retrieved', posts) + }) +} catch (error) { + console.error(error) +} \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/getUserName.js b/staff/eduardo-sanchez/socialcode/api_/logic/getUserName.js new file mode 100644 index 000000000..717af7db8 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/getUserName.js @@ -0,0 +1,41 @@ +import data from '../data/index.js' +import { MatchError } from 'com/errors.js' +import validate from 'com/validate.js' + +const getUserName = (username, targetUsername, callback) => { + validate.username(username) + validate.username(targetUsername, 'targetUsername') + validate.callback(callback) + + data.findUser(user => user.username === username, (error, user) => { + if (error) { + callback(error) + + return + } + + if (!user) { + callback(new MatchError('user not found')) + + return + } + + data.findUser(user => user.username === targetUsername, (error, targetUser) => { + if (error) { + callback(error) + + return + } + + if (!targetUser) { + callback(new MatchError('targetUser not found')) + + return + } + + callback(null, targetUser.name) + }) + }) +} + +export default getUserName \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/getUserName.test.js b/staff/eduardo-sanchez/socialcode/api_/logic/getUserName.test.js new file mode 100644 index 000000000..8faf67a46 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/getUserName.test.js @@ -0,0 +1,15 @@ +import logic from './index.js' + +try { + logic.getUserName('peterpan', 'pepitogrillo', (error, name) => { + if (error) { + console.error(error) + + return + } + + console.log('user name retrieved', name) + }) +} catch (error) { + console.error(error) +} \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/index.js b/staff/eduardo-sanchez/socialcode/api_/logic/index.js new file mode 100644 index 000000000..fa232ce49 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/index.js @@ -0,0 +1,19 @@ +import registerUser from './registerUser.js' +import authenticateUser from './authenticateUser.js' +import getUserName from './getUserName.js' + +import getAllPosts from './getAllPosts.js' +import createPost from './createPost.js' +import deletePost from './deletePost.js' + +const logic = { + registerUser, + authenticateUser, + getUserName, + + getAllPosts, + createPost, + deletePost +} + +export default logic \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/registerUser.js b/staff/eduardo-sanchez/socialcode/api_/logic/registerUser.js new file mode 100644 index 000000000..397651df9 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/registerUser.js @@ -0,0 +1,58 @@ +import data from '../data/index.js' +import { DuplicityError, SystemError } from 'com/errors.js' +import validate from 'com/validate.js' +import bcrypt from 'bcryptjs' + +const registerUser = (name, surname, email, username, password, passwordRepeat, callback) => { + validate.name(name) + validate.name(surname, 'surname') + validate.email(email) + validate.username(username) + validate.password(password) + validate.passwordsMatch(password, passwordRepeat) + validate.callback(callback) + + data.findUser(user => user.email === email || user.username === username, (error, user) => { + if (error) { + callback(error) + + return + } + + if (user) { + callback(new DuplicityError('user already exists')) + + return + } + + bcrypt.hash(password, 8, (error, hash) => { + if (error) { + callback(new SystemError(error.message)) + + return + } + + const newUser = { + name: name, + surname: surname, + email: email, + username: username, + password: hash + } + + data.insertUser(newUser, error => { + if (error) { + callback(error) + + return + } + + callback(null) + + }) + + }) + }) +} + +export default registerUser \ No newline at end of file diff --git a/staff/eduardo-sanchez/socialcode/api_/logic/registerUser.test.js b/staff/eduardo-sanchez/socialcode/api_/logic/registerUser.test.js new file mode 100644 index 000000000..7779f73f7 --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/logic/registerUser.test.js @@ -0,0 +1,19 @@ +import logic from './index.js' + +try { + // logic.registerUser('Peter', 'Pan', 'peter@pan.com', 'peterpan', '123123123', '123123123', error => { + + // logic.registerUser('Wendy', 'Darling', 'wendy@darling.com', 'wendydarling', '123123123', '123123123', error => { + + logic.registerUser('Pablo', 'Picasso', 'pablo@picasso.com', 'PabloP', 'Hola1234', 'Hola1234', error => { + if (error) { + console.error(error) + + return + } + + console.log('user registered') + }) +} catch (error) { + console.error(error) +} diff --git a/staff/eduardo-sanchez/socialcode/api_/package-lock.json b/staff/eduardo-sanchez/socialcode/api_/package-lock.json new file mode 100644 index 000000000..dbc9ee0ab --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/package-lock.json @@ -0,0 +1,847 @@ +{ + "name": "api", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "api", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "bcryptjs": "^2.4.3", + "com": "file:../com", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.19.2", + "jsonwebtoken": "^9.0.2" + } + }, + "../com": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/com": { + "resolved": "../com", + "link": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/staff/eduardo-sanchez/socialcode/api_/package.json b/staff/eduardo-sanchez/socialcode/api_/package.json new file mode 100644 index 000000000..f05ebd53d --- /dev/null +++ b/staff/eduardo-sanchez/socialcode/api_/package.json @@ -0,0 +1,23 @@ +{ + "name": "api", + "version": "1.0.0", + "description": "", + "type": "module", + "main": "index.js", + "scripts": { + "start": "node .", + "inspect": "node --inspect-brk .", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "bcryptjs": "^2.4.3", + "com": "file:../com", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.19.2", + "jsonwebtoken": "^9.0.2" + } +}