-
Notifications
You must be signed in to change notification settings - Fork 53
feat(session-05): complete project with mongodb integration #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
NiverMtz
wants to merge
62
commits into
gus-code:node/niver.martinez
Choose a base branch
from
NiverMtz:node/niver.martinez
base: node/niver.martinez
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
62 commits
Select commit
Hold shift + click to select a range
ab5d158
feat(api): add crud operations for category
gus-code 4f3b735
feat(api): add router
gus-code 1ed6633
feat(api): refactor crud operations to new file
gus-code 41fcc8f
refactor(api): move logic from route to controller
gus-code 8c5d449
Merge branch 'node/template' into node/session-01
gus-code 024c94e
Merge branch 'node/session-01' into node/session-02
gus-code b801647
chore(api): remove .gitkeep from controllers
gus-code 081c58a
feat(api): create user model
gus-code 26140e1
feat(api): create auth controller
gus-code 18cc352
feat(api): create auth route
gus-code 505f334
feat(api): add route to main file
gus-code d67968b
feat(api): add basic configuration
gus-code 5e198de
Merge branch 'node/session-00' into node/session-01
gus-code 0d88039
Merge branch 'node/session-01' into node/session-02
gus-code 3489c85
Merge branch 'node/session-02' into node/session-03
gus-code a06be55
Merge branch 'node/template' into node/session-00
gus-code 59aadea
Merge branch 'node/session-00' into node/session-01
gus-code 842cf0d
Merge branch 'node/session-01' into node/session-02
gus-code 19adf89
Merge branch 'node/session-02' into node/session-03
gus-code 7c1b48f
feat(api): add verify token middleware
gus-code 7735cec
Merge branch 'node/template' into node/session-00
gus-code d329c84
fix(api): relocate cors config
gus-code 65ac083
fix(api): cors issue for local development
gus-code 400c5b4
Merge branch 'node/session-00' into node/session-01
gus-code 0e0a99d
Merge branch 'node/session-01' into node/session-02
gus-code 54350d8
Merge branch 'node/session-02' into node/session-03
gus-code 0aec367
feat(api): add error handler middleware
gus-code ca4222e
chore(api): remove .gitkeep file from config
gus-code 3f6aa24
Merge branch 'node/session-00' into node/session-01
gus-code fe8d8ec
Merge branch 'node/session-01' into node/session-02
gus-code e67a741
Merge branch 'node/session-02' into node/session-03
gus-code bc2077c
Merge branch 'node/session-03' into node/session-04
gus-code 05c4fbd
feat(api): add connection to MongoDB
gus-code 837ac4c
feat(api): create category model
gus-code 2eec543
refactor(api): update required property in model
gus-code 78a1a00
refactor(api): connect controller with model
gus-code d8a9e9b
Merge branch 'node/template' into node/session-00
gus-code e2ab88b
Merge branch 'node/session-00' into node/session-01
gus-code 4e2e2b7
chore(api): add session 01 challenges
gus-code 86384c8
Merge branch 'node/session-01' into node/session-02
gus-code bedf059
chore(api): add session 02 challenges
gus-code 540d70c
Merge branch 'node/session-02' into node/session-03
gus-code ee6fae4
chore(api): add session 03 challenges
gus-code 1feb2d8
Merge branch 'node/session-03' into node/session-04
gus-code 072672f
chore(api): add session 04 challenges
gus-code 90fa78a
Merge branch 'node/session-04' into node/session-05
gus-code 230782f
chore(api): add session 05 challenges
gus-code 901ea24
fix(api): refactor getCategory for future use
gus-code 2dadc90
Merge branch 'node/session-01' into node/session-02
gus-code 33a0024
Merge branch 'node/session-02' into node/session-03
gus-code e08e0be
Merge branch 'node/session-03' into node/session-04
gus-code 1d0c662
refactor(api): update findByIdAndUpdate options
gus-code a1d7341
Merge branch 'node/template' into node/session-00
gus-code 98c49b0
Merge branch 'node/session-00' into node/session-01
gus-code 1498260
Merge branch 'node/session-01' into node/session-02
gus-code 3fca0e2
Merge branch 'node/session-02' into node/session-03
gus-code 5eb29eb
fix(api): add message to 409 error in auth register
gus-code 38ed6d0
Merge branch 'node/session-03' into node/session-04
gus-code 0e64cad
Merge branch 'node/session-04' into node/session-05
gus-code fb234cb
feat(session-01): create posts routes
NiverMtz 145f5f8
feat(session-02): refact router for controllers modularization
NiverMtz cde7597
feat(session-05): mongodb integration
NiverMtz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| ACCESS_TOKEN_SECRET=[YOUR_ACCESS_TOKEN_SECRET_HERE] | ||
| REFRESH_TOKEN_SECRET=[YOUR_REFRESH_TOKEN_SECRET_HERE] | ||
| MONGO_URL=[YOUR_MONGO_CONNECTION_STRING_HERE] | ||
| ACCESS_TOKEN_SECRET=62f7814ecb7bd8eed882d0c25403dd0b390dc07673ba3798ed22fc6db3e480750b8f9f6ee845e9e138c7047ecfd7d13c95d081821c1dd85333b53cedac0c7b24 | ||
| REFRESH_TOKEN_SECRET=3bcad700ce9c447d3fd5f1af746d5b597ed01ddb6884693ed38a2c7913b2bf3dd69b6c1e974a6d1760c076b55b6ff0c3d92b218faac728e3db31d0474b6888e0 | ||
| MONGO_URL=mongodb+srv://nivermartinez96:tSzduB9XoRg2oq1P@cluster0.bhfou.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| const allowedOrigins = ['http://localhost:4200', 'http://localhost:3000']; | ||
|
|
||
| export const corsOptions = { | ||
| origin: (origin, callback) => { | ||
| // Note: origin will be undefined from same route in local development | ||
| if (allowedOrigins.indexOf(origin) !== -1 || !origin) { | ||
| callback(null, true); | ||
| } else { | ||
| callback(new Error('Not allowed by CORS')); | ||
| } | ||
| }, | ||
| optionsSuccessStatus: 200 | ||
| }; | ||
|
|
||
| export default { corsOptions }; |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| import bcrypt from 'bcrypt'; | ||
| import jwt from 'jsonwebtoken'; | ||
|
|
||
| import { User } from '../models/user'; | ||
|
|
||
| const users: User[] = []; | ||
|
|
||
| const register = async (req, res) => { | ||
| const { username, password } = req.body; | ||
|
|
||
| // Check that we have the correct payload | ||
| if (!username || !password) { | ||
| return res.status(400).json({ | ||
| message: 'Username and password are required' | ||
| }); | ||
| } | ||
|
|
||
| // Check that we don't have duplicates | ||
| const duplicate = users.find((u) => u.username === username); | ||
| if (duplicate) { | ||
| return res.status(409).json({ message: 'User already exist' }); | ||
| } | ||
|
|
||
| try { | ||
| // Encrypt the password | ||
| const hashedPassword = await bcrypt.hash(password, 10); | ||
|
|
||
| // Store new user | ||
| users.push({ username, password: hashedPassword }); | ||
|
|
||
| res.status(201).json({ message: 'User registered successfully' }); | ||
| } catch (e) { | ||
| res.status(500).json({ message: e.message }); | ||
| } | ||
| }; | ||
|
|
||
| const login = async (req, res) => { | ||
| const { username, password } = req.body; | ||
|
|
||
| // Check that we have the correct payload | ||
| if (!username || !password) { | ||
| return res.status(400).json({ | ||
| message: 'Username and password are required' | ||
| }); | ||
| } | ||
|
|
||
| // Retrieve user | ||
| const user = users.find((u) => u.username === username); | ||
|
|
||
| // Check if we found the user and the password matches | ||
| if (!user || !(await bcrypt.compare(password, user.password))) { | ||
| return res.status(401).json({ message: 'Invalid credentials' }); | ||
| } | ||
|
|
||
| // Generate access token and refresh token | ||
| const accessToken = jwt.sign({ username }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '15m' }); | ||
| const refreshToken = jwt.sign({ username }, process.env.REFRESH_TOKEN_SECRET, { expiresIn: '7d' }); | ||
|
|
||
| // Save refresh token | ||
| res.cookie('refreshToken', refreshToken, { | ||
| httpOnly: true, | ||
| maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days in milliseconds | ||
| }); | ||
|
|
||
| res.json({ accessToken }); | ||
| }; | ||
|
|
||
| const refresh = (req, res) => { | ||
| // Get refresh token from cookies | ||
| const refreshToken = req.cookies.refreshToken; | ||
|
|
||
| if (!refreshToken) { | ||
| return res.status(401).json({ message: 'Unauthorized' }); | ||
| } | ||
|
|
||
| jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET, (err, { username }) => { | ||
| if (err) { | ||
| // Invalid token | ||
| return res.status(403).json({ message: 'Forbidden' }); | ||
| } | ||
|
|
||
| const accessToken = jwt.sign({ username }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '15m' }); | ||
| res.json({ accessToken }); | ||
| }); | ||
| }; | ||
|
|
||
| const logout = (req, res) => { | ||
| res.clearCookie('refreshToken'); | ||
| res.json({ message: 'Logged out successfully' }); | ||
| }; | ||
|
|
||
| export default { | ||
| register, | ||
| login, | ||
| refresh, | ||
| logout | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| import Category from '../models/category'; | ||
|
|
||
| // Get all categories | ||
| const getCategories = async (req, res) => { | ||
| try { | ||
| const categories = await Category.find(); | ||
| // Return all the categories with a 200 status code | ||
| res.status(200).json(categories); | ||
| } catch (error) { | ||
| const { message } = error; | ||
| res.status(500).json({ message }); | ||
| } | ||
| }; | ||
|
|
||
| // Get category by id | ||
| const getCategoryById = async (req, res) => { | ||
| // Retrieve the id from the route params | ||
| const { id } = req.params; | ||
|
|
||
| try { | ||
| // Check if we have a category with that id | ||
| const category = await Category.findById(id); | ||
|
|
||
| if (!category) { | ||
| // If we don't find the category return a 404 status code with a message | ||
| return res.status(404).json({ message: 'Category not found' }); | ||
| // Note: Remember that json method doesn't interrupt the workflow | ||
| // therefore is important to add a "return" to break the process | ||
| } | ||
| // Return the category with a 200 status code | ||
| res.status(200).json(category); | ||
| } catch (error) { | ||
| const { message } = error; | ||
| res.status(500).json({ message }); | ||
| } | ||
| }; | ||
|
|
||
| // Create category | ||
| const createCategory = async (req, res) => { | ||
| try { | ||
| const category = await Category.create(req.body); | ||
| // Return the created category with a 201 status code | ||
| res.status(201).json(category); | ||
| } catch (error) { | ||
| const { message } = error; | ||
| res.status(500).json({ message }); | ||
| } | ||
| }; | ||
|
|
||
| // Update category | ||
| const updateCategory = async (req, res) => { | ||
| // Retrieve the id from the route params | ||
| const { id } = req.params; | ||
|
|
||
| try { | ||
| // Check and update if we have a category with that id | ||
| const category = await Category.findByIdAndUpdate(id, req.body, { new: true }); | ||
|
|
||
| // If we don't find the category return a 404 status code with a message | ||
| if (!category) { | ||
| return res.status(404).json({ message: 'Category not found' }); | ||
| } | ||
|
|
||
| // Return the updated category with a 200 status code | ||
| res.status(200).json(category); | ||
| } catch (error) { | ||
| const { message } = error; | ||
| res.status(500).json({ message }); | ||
| } | ||
| }; | ||
|
|
||
| // Delete category | ||
| const deleteCategory = async (req, res) => { | ||
| // Retrieve the id from the route params | ||
| const { id } = req.params; | ||
|
|
||
| try { | ||
| // Check and delete if we have a category with that id | ||
| const category = await Category.findByIdAndDelete(id); | ||
|
|
||
| // If we don't find the category return a 404 status code with a message | ||
| if (!category) { | ||
| return res.status(404).json({ message: 'Category not found' }); | ||
| } | ||
|
|
||
| // Return a 200 status code | ||
| res.status(200).json(category); | ||
| } catch (error) { | ||
| const { message } = error; | ||
| res.status(500).json({ message }); | ||
| } | ||
| }; | ||
|
|
||
| export default { | ||
| getCategories, | ||
| getCategoryById, | ||
| createCategory, | ||
| updateCategory, | ||
| deleteCategory | ||
| }; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to remove all this information from the environment file