├── .DS_Store
├── .gitignore
├── README.md
├── api-learn
├── .env
├── app.js
├── package-lock.json
├── package.json
└── src
│ ├── controllers
│ └── auth.controllers.js
│ ├── models
│ └── user.model.js
│ └── routes
│ ├── auth.routes.js
│ └── index.js
├── api-learnv2
├── .env
├── app.js
├── package-lock.json
├── package.json
└── src
│ └── middlewares
│ └── middleware.js
├── e-commerce-mysql
├── .DS_Store
├── README.md
├── data
│ └── db.js
├── default_index.js
├── index.js
├── package-lock.json
├── package.json
├── public
│ ├── .DS_Store
│ └── images
│ │ ├── 1.webp
│ │ ├── 2.webp
│ │ ├── 3.webp
│ │ ├── 4.webp
│ │ └── 5.webp
├── routes
│ └── users.js
└── views
│ ├── 404.ejs
│ ├── index.ejs
│ ├── partials
│ ├── navbar.ejs
│ └── product.ejs
│ ├── product_details.ejs
│ └── products.ejs
├── patient-system-api
├── package-lock.json
├── package.json
└── src
│ ├── api
│ ├── config
│ │ └── index.js
│ ├── controllers
│ │ └── auth.js
│ └── routes
│ │ ├── auth.js
│ │ └── index.js
│ └── app.js
├── question-answer-api
├── README.MD
├── app.js
├── package-lock.json
├── package.json
└── src
│ ├── controllers
│ ├── admin.contoller.js
│ ├── answer.controller.js
│ ├── auth.controller.js
│ ├── quesitons.controller.js
│ └── user.controller.js
│ ├── helpers
│ ├── auth
│ │ └── auth.helper.js
│ ├── db
│ │ ├── db.error.helpers.js
│ │ └── db.js
│ ├── error
│ │ └── CustomError.js
│ ├── input
│ │ └── input.helper.js
│ └── libraries
│ │ └── sendEmail.js
│ ├── middlewares
│ ├── auth.middleware.js
│ ├── error.handler.js
│ └── image.upload.js
│ ├── models
│ ├── answer.model.js
│ ├── question.model.js
│ └── user.model.js
│ └── routes
│ ├── admin.js
│ ├── answer.js
│ ├── auth.js
│ ├── index.js
│ ├── questions.js
│ └── users.js
└── todo-mysql
├── .DS_Store
├── README.MD
├── db
└── db.js
├── index.js
├── package-lock.json
├── package.json
├── routes
└── route.js
└── views
└── index.ejs
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # npm
2 | node_modules
3 |
4 | # config
5 | config.js
6 | *.env
7 |
8 | # ----
9 | .DS_Store
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Learn Node.js
2 | My development and learning process with node.js per day.
3 |
4 | - First Project (Basic E-commerce App)
5 | - Second Project (Basic Todo App)
6 | - Third Project (Stack-Overflow Clone Rest Api)
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/api-learn/.env:
--------------------------------------------------------------------------------
1 | PORT = 8080
2 |
--------------------------------------------------------------------------------
/api-learn/app.js:
--------------------------------------------------------------------------------
1 | const express = require("express")
2 | const app = express()
3 | const port = process.env.PORT || 8081
4 |
5 | app.use("/", (req, res) => {
6 | res.json({
7 | message: "Hello world"
8 | })
9 | })
10 |
11 | app.listen(port, () => {
12 | console.log(`The server was listening ${port}`)
13 | })
--------------------------------------------------------------------------------
/api-learn/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api-learn",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "app.js",
6 | "scripts": {
7 | "start": "nodemon app.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "dotenv": "^16.0.3",
15 | "express": "^4.18.2",
16 | "express-async-errors": "^3.1.1",
17 | "jsonwebtoken": "^8.5.1",
18 | "mongoose": "^6.6.5"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/api-learn/src/controllers/auth.controllers.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/api-learn/src/controllers/auth.controllers.js
--------------------------------------------------------------------------------
/api-learn/src/models/user.model.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose")
2 |
3 | const userShema = new mongoose.Schema({
4 | name: {
5 | type: String,
6 | required: true,
7 | trim: true
8 | },
9 | lastname: {
10 | type: String,
11 | required: true,
12 | trim: true
13 | },
14 | email: {
15 | type: String,
16 | required: true,
17 | trim: true,
18 | unique: true
19 | },
20 | password: {
21 | type: String,
22 | required: true,
23 | trim: true
24 | }
25 | }, { collection: "users", timestamps: true })
26 |
27 | const user = mongoose.model("users", userShema)
28 |
29 | module.exports = user
--------------------------------------------------------------------------------
/api-learn/src/routes/auth.routes.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/api-learn/src/routes/auth.routes.js
--------------------------------------------------------------------------------
/api-learn/src/routes/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/api-learn/src/routes/index.js
--------------------------------------------------------------------------------
/api-learnv2/.env:
--------------------------------------------------------------------------------
1 | PORT = 4040
--------------------------------------------------------------------------------
/api-learnv2/app.js:
--------------------------------------------------------------------------------
1 | const express = require("express")
2 | const app = express()
3 | const port = process.env.PORT || 4041
4 | const { authControl, banControl, homeControl } = require("./src/middlewares/middleware")
5 |
6 | const users = [
7 | {
8 | id: 1,
9 | name: "Ahmet Kaan",
10 | surname: "Uzman",
11 | type: "user",
12 | createdTime: Date.now(),
13 | isActive: true,
14 | },
15 | {
16 | id: 2,
17 | name: "Test",
18 | surname: "User",
19 | type: "user",
20 | createdTime: Date.now(),
21 | isActive: true,
22 | },
23 | {
24 | id: 3,
25 | name: "Test",
26 | surname: "Admin",
27 | type: "admin",
28 | createdTime: Date.now(),
29 | isActive: true,
30 | },
31 | ]
32 |
33 | app.use(express.json())
34 |
35 | /// Middlewares usage in general routes
36 | app.use(authControl, banControl)
37 |
38 |
39 | /// Middlewares usage in only a route
40 | app.get("/", homeControl, (req, res) => {
41 | res.send("hello world")
42 | })
43 |
44 | app.get("/users", (req, res) => {
45 | res.json(users)
46 | })
47 |
48 | app.get("/users/:id", (req, res) => {
49 | res.json(
50 | users.find(e => e.id == req.params.id)
51 | )
52 | })
53 |
54 | app.post("/addUser", (req, res) => {
55 | const newUser = req.body
56 | users.push(newUser)
57 | res.json({
58 | succes: true,
59 | user: newUser
60 | })
61 | })
62 |
63 | app.put("/updateUser/:id", (req, res) => {
64 | let updatedUser = users.find(e => e.id == req.params.id)
65 | updatedUser = req.body
66 | res.json({
67 | succes: true,
68 | body: updatedUser
69 | })
70 | })
71 |
72 | app.delete("/deleteUser/:id", (req, res) => {
73 | for (let i = 0; i < users.length; i++) {
74 | if (users[i].id == req.params.id) {
75 | users.splice(i, 1)
76 | }
77 | }
78 | res.json({
79 | succes: true,
80 | body: users,
81 | })
82 | })
83 |
84 | /// General error route
85 | app.get("*", (req, res) => {
86 | res.status(404).json(
87 | {
88 | message: "This page doesn't exist."
89 | }
90 | )
91 | })
92 |
93 | app.listen(port, () => {
94 | console.log("The server was started!")
95 | })
--------------------------------------------------------------------------------
/api-learnv2/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api-learnv2",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "api-learnv2",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "express": "^4.18.2"
13 | }
14 | },
15 | "node_modules/accepts": {
16 | "version": "1.3.8",
17 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
18 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
19 | "dependencies": {
20 | "mime-types": "~2.1.34",
21 | "negotiator": "0.6.3"
22 | },
23 | "engines": {
24 | "node": ">= 0.6"
25 | }
26 | },
27 | "node_modules/array-flatten": {
28 | "version": "1.1.1",
29 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
30 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
31 | },
32 | "node_modules/body-parser": {
33 | "version": "1.20.1",
34 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
35 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
36 | "dependencies": {
37 | "bytes": "3.1.2",
38 | "content-type": "~1.0.4",
39 | "debug": "2.6.9",
40 | "depd": "2.0.0",
41 | "destroy": "1.2.0",
42 | "http-errors": "2.0.0",
43 | "iconv-lite": "0.4.24",
44 | "on-finished": "2.4.1",
45 | "qs": "6.11.0",
46 | "raw-body": "2.5.1",
47 | "type-is": "~1.6.18",
48 | "unpipe": "1.0.0"
49 | },
50 | "engines": {
51 | "node": ">= 0.8",
52 | "npm": "1.2.8000 || >= 1.4.16"
53 | }
54 | },
55 | "node_modules/bytes": {
56 | "version": "3.1.2",
57 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
58 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
59 | "engines": {
60 | "node": ">= 0.8"
61 | }
62 | },
63 | "node_modules/call-bind": {
64 | "version": "1.0.2",
65 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
66 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
67 | "dependencies": {
68 | "function-bind": "^1.1.1",
69 | "get-intrinsic": "^1.0.2"
70 | },
71 | "funding": {
72 | "url": "https://github.com/sponsors/ljharb"
73 | }
74 | },
75 | "node_modules/content-disposition": {
76 | "version": "0.5.4",
77 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
78 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
79 | "dependencies": {
80 | "safe-buffer": "5.2.1"
81 | },
82 | "engines": {
83 | "node": ">= 0.6"
84 | }
85 | },
86 | "node_modules/content-type": {
87 | "version": "1.0.4",
88 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
89 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
90 | "engines": {
91 | "node": ">= 0.6"
92 | }
93 | },
94 | "node_modules/cookie": {
95 | "version": "0.5.0",
96 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
97 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
98 | "engines": {
99 | "node": ">= 0.6"
100 | }
101 | },
102 | "node_modules/cookie-signature": {
103 | "version": "1.0.6",
104 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
105 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
106 | },
107 | "node_modules/debug": {
108 | "version": "2.6.9",
109 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
110 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
111 | "dependencies": {
112 | "ms": "2.0.0"
113 | }
114 | },
115 | "node_modules/depd": {
116 | "version": "2.0.0",
117 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
118 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
119 | "engines": {
120 | "node": ">= 0.8"
121 | }
122 | },
123 | "node_modules/destroy": {
124 | "version": "1.2.0",
125 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
126 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
127 | "engines": {
128 | "node": ">= 0.8",
129 | "npm": "1.2.8000 || >= 1.4.16"
130 | }
131 | },
132 | "node_modules/ee-first": {
133 | "version": "1.1.1",
134 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
135 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
136 | },
137 | "node_modules/encodeurl": {
138 | "version": "1.0.2",
139 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
140 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
141 | "engines": {
142 | "node": ">= 0.8"
143 | }
144 | },
145 | "node_modules/escape-html": {
146 | "version": "1.0.3",
147 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
148 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
149 | },
150 | "node_modules/etag": {
151 | "version": "1.8.1",
152 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
153 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
154 | "engines": {
155 | "node": ">= 0.6"
156 | }
157 | },
158 | "node_modules/express": {
159 | "version": "4.18.2",
160 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
161 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
162 | "dependencies": {
163 | "accepts": "~1.3.8",
164 | "array-flatten": "1.1.1",
165 | "body-parser": "1.20.1",
166 | "content-disposition": "0.5.4",
167 | "content-type": "~1.0.4",
168 | "cookie": "0.5.0",
169 | "cookie-signature": "1.0.6",
170 | "debug": "2.6.9",
171 | "depd": "2.0.0",
172 | "encodeurl": "~1.0.2",
173 | "escape-html": "~1.0.3",
174 | "etag": "~1.8.1",
175 | "finalhandler": "1.2.0",
176 | "fresh": "0.5.2",
177 | "http-errors": "2.0.0",
178 | "merge-descriptors": "1.0.1",
179 | "methods": "~1.1.2",
180 | "on-finished": "2.4.1",
181 | "parseurl": "~1.3.3",
182 | "path-to-regexp": "0.1.7",
183 | "proxy-addr": "~2.0.7",
184 | "qs": "6.11.0",
185 | "range-parser": "~1.2.1",
186 | "safe-buffer": "5.2.1",
187 | "send": "0.18.0",
188 | "serve-static": "1.15.0",
189 | "setprototypeof": "1.2.0",
190 | "statuses": "2.0.1",
191 | "type-is": "~1.6.18",
192 | "utils-merge": "1.0.1",
193 | "vary": "~1.1.2"
194 | },
195 | "engines": {
196 | "node": ">= 0.10.0"
197 | }
198 | },
199 | "node_modules/finalhandler": {
200 | "version": "1.2.0",
201 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
202 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
203 | "dependencies": {
204 | "debug": "2.6.9",
205 | "encodeurl": "~1.0.2",
206 | "escape-html": "~1.0.3",
207 | "on-finished": "2.4.1",
208 | "parseurl": "~1.3.3",
209 | "statuses": "2.0.1",
210 | "unpipe": "~1.0.0"
211 | },
212 | "engines": {
213 | "node": ">= 0.8"
214 | }
215 | },
216 | "node_modules/forwarded": {
217 | "version": "0.2.0",
218 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
219 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
220 | "engines": {
221 | "node": ">= 0.6"
222 | }
223 | },
224 | "node_modules/fresh": {
225 | "version": "0.5.2",
226 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
227 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
228 | "engines": {
229 | "node": ">= 0.6"
230 | }
231 | },
232 | "node_modules/function-bind": {
233 | "version": "1.1.1",
234 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
235 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
236 | },
237 | "node_modules/get-intrinsic": {
238 | "version": "1.1.3",
239 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
240 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
241 | "dependencies": {
242 | "function-bind": "^1.1.1",
243 | "has": "^1.0.3",
244 | "has-symbols": "^1.0.3"
245 | },
246 | "funding": {
247 | "url": "https://github.com/sponsors/ljharb"
248 | }
249 | },
250 | "node_modules/has": {
251 | "version": "1.0.3",
252 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
253 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
254 | "dependencies": {
255 | "function-bind": "^1.1.1"
256 | },
257 | "engines": {
258 | "node": ">= 0.4.0"
259 | }
260 | },
261 | "node_modules/has-symbols": {
262 | "version": "1.0.3",
263 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
264 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
265 | "engines": {
266 | "node": ">= 0.4"
267 | },
268 | "funding": {
269 | "url": "https://github.com/sponsors/ljharb"
270 | }
271 | },
272 | "node_modules/http-errors": {
273 | "version": "2.0.0",
274 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
275 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
276 | "dependencies": {
277 | "depd": "2.0.0",
278 | "inherits": "2.0.4",
279 | "setprototypeof": "1.2.0",
280 | "statuses": "2.0.1",
281 | "toidentifier": "1.0.1"
282 | },
283 | "engines": {
284 | "node": ">= 0.8"
285 | }
286 | },
287 | "node_modules/iconv-lite": {
288 | "version": "0.4.24",
289 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
290 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
291 | "dependencies": {
292 | "safer-buffer": ">= 2.1.2 < 3"
293 | },
294 | "engines": {
295 | "node": ">=0.10.0"
296 | }
297 | },
298 | "node_modules/inherits": {
299 | "version": "2.0.4",
300 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
301 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
302 | },
303 | "node_modules/ipaddr.js": {
304 | "version": "1.9.1",
305 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
306 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
307 | "engines": {
308 | "node": ">= 0.10"
309 | }
310 | },
311 | "node_modules/media-typer": {
312 | "version": "0.3.0",
313 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
314 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
315 | "engines": {
316 | "node": ">= 0.6"
317 | }
318 | },
319 | "node_modules/merge-descriptors": {
320 | "version": "1.0.1",
321 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
322 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
323 | },
324 | "node_modules/methods": {
325 | "version": "1.1.2",
326 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
327 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
328 | "engines": {
329 | "node": ">= 0.6"
330 | }
331 | },
332 | "node_modules/mime": {
333 | "version": "1.6.0",
334 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
335 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
336 | "bin": {
337 | "mime": "cli.js"
338 | },
339 | "engines": {
340 | "node": ">=4"
341 | }
342 | },
343 | "node_modules/mime-db": {
344 | "version": "1.52.0",
345 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
346 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
347 | "engines": {
348 | "node": ">= 0.6"
349 | }
350 | },
351 | "node_modules/mime-types": {
352 | "version": "2.1.35",
353 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
354 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
355 | "dependencies": {
356 | "mime-db": "1.52.0"
357 | },
358 | "engines": {
359 | "node": ">= 0.6"
360 | }
361 | },
362 | "node_modules/ms": {
363 | "version": "2.0.0",
364 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
365 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
366 | },
367 | "node_modules/negotiator": {
368 | "version": "0.6.3",
369 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
370 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
371 | "engines": {
372 | "node": ">= 0.6"
373 | }
374 | },
375 | "node_modules/object-inspect": {
376 | "version": "1.12.2",
377 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
378 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
379 | "funding": {
380 | "url": "https://github.com/sponsors/ljharb"
381 | }
382 | },
383 | "node_modules/on-finished": {
384 | "version": "2.4.1",
385 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
386 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
387 | "dependencies": {
388 | "ee-first": "1.1.1"
389 | },
390 | "engines": {
391 | "node": ">= 0.8"
392 | }
393 | },
394 | "node_modules/parseurl": {
395 | "version": "1.3.3",
396 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
397 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
398 | "engines": {
399 | "node": ">= 0.8"
400 | }
401 | },
402 | "node_modules/path-to-regexp": {
403 | "version": "0.1.7",
404 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
405 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
406 | },
407 | "node_modules/proxy-addr": {
408 | "version": "2.0.7",
409 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
410 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
411 | "dependencies": {
412 | "forwarded": "0.2.0",
413 | "ipaddr.js": "1.9.1"
414 | },
415 | "engines": {
416 | "node": ">= 0.10"
417 | }
418 | },
419 | "node_modules/qs": {
420 | "version": "6.11.0",
421 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
422 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
423 | "dependencies": {
424 | "side-channel": "^1.0.4"
425 | },
426 | "engines": {
427 | "node": ">=0.6"
428 | },
429 | "funding": {
430 | "url": "https://github.com/sponsors/ljharb"
431 | }
432 | },
433 | "node_modules/range-parser": {
434 | "version": "1.2.1",
435 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
436 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
437 | "engines": {
438 | "node": ">= 0.6"
439 | }
440 | },
441 | "node_modules/raw-body": {
442 | "version": "2.5.1",
443 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
444 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
445 | "dependencies": {
446 | "bytes": "3.1.2",
447 | "http-errors": "2.0.0",
448 | "iconv-lite": "0.4.24",
449 | "unpipe": "1.0.0"
450 | },
451 | "engines": {
452 | "node": ">= 0.8"
453 | }
454 | },
455 | "node_modules/safe-buffer": {
456 | "version": "5.2.1",
457 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
458 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
459 | "funding": [
460 | {
461 | "type": "github",
462 | "url": "https://github.com/sponsors/feross"
463 | },
464 | {
465 | "type": "patreon",
466 | "url": "https://www.patreon.com/feross"
467 | },
468 | {
469 | "type": "consulting",
470 | "url": "https://feross.org/support"
471 | }
472 | ]
473 | },
474 | "node_modules/safer-buffer": {
475 | "version": "2.1.2",
476 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
477 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
478 | },
479 | "node_modules/send": {
480 | "version": "0.18.0",
481 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
482 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
483 | "dependencies": {
484 | "debug": "2.6.9",
485 | "depd": "2.0.0",
486 | "destroy": "1.2.0",
487 | "encodeurl": "~1.0.2",
488 | "escape-html": "~1.0.3",
489 | "etag": "~1.8.1",
490 | "fresh": "0.5.2",
491 | "http-errors": "2.0.0",
492 | "mime": "1.6.0",
493 | "ms": "2.1.3",
494 | "on-finished": "2.4.1",
495 | "range-parser": "~1.2.1",
496 | "statuses": "2.0.1"
497 | },
498 | "engines": {
499 | "node": ">= 0.8.0"
500 | }
501 | },
502 | "node_modules/send/node_modules/ms": {
503 | "version": "2.1.3",
504 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
505 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
506 | },
507 | "node_modules/serve-static": {
508 | "version": "1.15.0",
509 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
510 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
511 | "dependencies": {
512 | "encodeurl": "~1.0.2",
513 | "escape-html": "~1.0.3",
514 | "parseurl": "~1.3.3",
515 | "send": "0.18.0"
516 | },
517 | "engines": {
518 | "node": ">= 0.8.0"
519 | }
520 | },
521 | "node_modules/setprototypeof": {
522 | "version": "1.2.0",
523 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
524 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
525 | },
526 | "node_modules/side-channel": {
527 | "version": "1.0.4",
528 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
529 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
530 | "dependencies": {
531 | "call-bind": "^1.0.0",
532 | "get-intrinsic": "^1.0.2",
533 | "object-inspect": "^1.9.0"
534 | },
535 | "funding": {
536 | "url": "https://github.com/sponsors/ljharb"
537 | }
538 | },
539 | "node_modules/statuses": {
540 | "version": "2.0.1",
541 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
542 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
543 | "engines": {
544 | "node": ">= 0.8"
545 | }
546 | },
547 | "node_modules/toidentifier": {
548 | "version": "1.0.1",
549 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
550 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
551 | "engines": {
552 | "node": ">=0.6"
553 | }
554 | },
555 | "node_modules/type-is": {
556 | "version": "1.6.18",
557 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
558 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
559 | "dependencies": {
560 | "media-typer": "0.3.0",
561 | "mime-types": "~2.1.24"
562 | },
563 | "engines": {
564 | "node": ">= 0.6"
565 | }
566 | },
567 | "node_modules/unpipe": {
568 | "version": "1.0.0",
569 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
570 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
571 | "engines": {
572 | "node": ">= 0.8"
573 | }
574 | },
575 | "node_modules/utils-merge": {
576 | "version": "1.0.1",
577 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
578 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
579 | "engines": {
580 | "node": ">= 0.4.0"
581 | }
582 | },
583 | "node_modules/vary": {
584 | "version": "1.1.2",
585 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
586 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
587 | "engines": {
588 | "node": ">= 0.8"
589 | }
590 | }
591 | },
592 | "dependencies": {
593 | "accepts": {
594 | "version": "1.3.8",
595 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
596 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
597 | "requires": {
598 | "mime-types": "~2.1.34",
599 | "negotiator": "0.6.3"
600 | }
601 | },
602 | "array-flatten": {
603 | "version": "1.1.1",
604 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
605 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
606 | },
607 | "body-parser": {
608 | "version": "1.20.1",
609 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
610 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
611 | "requires": {
612 | "bytes": "3.1.2",
613 | "content-type": "~1.0.4",
614 | "debug": "2.6.9",
615 | "depd": "2.0.0",
616 | "destroy": "1.2.0",
617 | "http-errors": "2.0.0",
618 | "iconv-lite": "0.4.24",
619 | "on-finished": "2.4.1",
620 | "qs": "6.11.0",
621 | "raw-body": "2.5.1",
622 | "type-is": "~1.6.18",
623 | "unpipe": "1.0.0"
624 | }
625 | },
626 | "bytes": {
627 | "version": "3.1.2",
628 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
629 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
630 | },
631 | "call-bind": {
632 | "version": "1.0.2",
633 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
634 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
635 | "requires": {
636 | "function-bind": "^1.1.1",
637 | "get-intrinsic": "^1.0.2"
638 | }
639 | },
640 | "content-disposition": {
641 | "version": "0.5.4",
642 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
643 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
644 | "requires": {
645 | "safe-buffer": "5.2.1"
646 | }
647 | },
648 | "content-type": {
649 | "version": "1.0.4",
650 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
651 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
652 | },
653 | "cookie": {
654 | "version": "0.5.0",
655 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
656 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
657 | },
658 | "cookie-signature": {
659 | "version": "1.0.6",
660 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
661 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
662 | },
663 | "debug": {
664 | "version": "2.6.9",
665 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
666 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
667 | "requires": {
668 | "ms": "2.0.0"
669 | }
670 | },
671 | "depd": {
672 | "version": "2.0.0",
673 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
674 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
675 | },
676 | "destroy": {
677 | "version": "1.2.0",
678 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
679 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
680 | },
681 | "ee-first": {
682 | "version": "1.1.1",
683 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
684 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
685 | },
686 | "encodeurl": {
687 | "version": "1.0.2",
688 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
689 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
690 | },
691 | "escape-html": {
692 | "version": "1.0.3",
693 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
694 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
695 | },
696 | "etag": {
697 | "version": "1.8.1",
698 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
699 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
700 | },
701 | "express": {
702 | "version": "4.18.2",
703 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
704 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
705 | "requires": {
706 | "accepts": "~1.3.8",
707 | "array-flatten": "1.1.1",
708 | "body-parser": "1.20.1",
709 | "content-disposition": "0.5.4",
710 | "content-type": "~1.0.4",
711 | "cookie": "0.5.0",
712 | "cookie-signature": "1.0.6",
713 | "debug": "2.6.9",
714 | "depd": "2.0.0",
715 | "encodeurl": "~1.0.2",
716 | "escape-html": "~1.0.3",
717 | "etag": "~1.8.1",
718 | "finalhandler": "1.2.0",
719 | "fresh": "0.5.2",
720 | "http-errors": "2.0.0",
721 | "merge-descriptors": "1.0.1",
722 | "methods": "~1.1.2",
723 | "on-finished": "2.4.1",
724 | "parseurl": "~1.3.3",
725 | "path-to-regexp": "0.1.7",
726 | "proxy-addr": "~2.0.7",
727 | "qs": "6.11.0",
728 | "range-parser": "~1.2.1",
729 | "safe-buffer": "5.2.1",
730 | "send": "0.18.0",
731 | "serve-static": "1.15.0",
732 | "setprototypeof": "1.2.0",
733 | "statuses": "2.0.1",
734 | "type-is": "~1.6.18",
735 | "utils-merge": "1.0.1",
736 | "vary": "~1.1.2"
737 | }
738 | },
739 | "finalhandler": {
740 | "version": "1.2.0",
741 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
742 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
743 | "requires": {
744 | "debug": "2.6.9",
745 | "encodeurl": "~1.0.2",
746 | "escape-html": "~1.0.3",
747 | "on-finished": "2.4.1",
748 | "parseurl": "~1.3.3",
749 | "statuses": "2.0.1",
750 | "unpipe": "~1.0.0"
751 | }
752 | },
753 | "forwarded": {
754 | "version": "0.2.0",
755 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
756 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
757 | },
758 | "fresh": {
759 | "version": "0.5.2",
760 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
761 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
762 | },
763 | "function-bind": {
764 | "version": "1.1.1",
765 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
766 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
767 | },
768 | "get-intrinsic": {
769 | "version": "1.1.3",
770 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
771 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
772 | "requires": {
773 | "function-bind": "^1.1.1",
774 | "has": "^1.0.3",
775 | "has-symbols": "^1.0.3"
776 | }
777 | },
778 | "has": {
779 | "version": "1.0.3",
780 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
781 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
782 | "requires": {
783 | "function-bind": "^1.1.1"
784 | }
785 | },
786 | "has-symbols": {
787 | "version": "1.0.3",
788 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
789 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
790 | },
791 | "http-errors": {
792 | "version": "2.0.0",
793 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
794 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
795 | "requires": {
796 | "depd": "2.0.0",
797 | "inherits": "2.0.4",
798 | "setprototypeof": "1.2.0",
799 | "statuses": "2.0.1",
800 | "toidentifier": "1.0.1"
801 | }
802 | },
803 | "iconv-lite": {
804 | "version": "0.4.24",
805 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
806 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
807 | "requires": {
808 | "safer-buffer": ">= 2.1.2 < 3"
809 | }
810 | },
811 | "inherits": {
812 | "version": "2.0.4",
813 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
814 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
815 | },
816 | "ipaddr.js": {
817 | "version": "1.9.1",
818 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
819 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
820 | },
821 | "media-typer": {
822 | "version": "0.3.0",
823 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
824 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
825 | },
826 | "merge-descriptors": {
827 | "version": "1.0.1",
828 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
829 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
830 | },
831 | "methods": {
832 | "version": "1.1.2",
833 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
834 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
835 | },
836 | "mime": {
837 | "version": "1.6.0",
838 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
839 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
840 | },
841 | "mime-db": {
842 | "version": "1.52.0",
843 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
844 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
845 | },
846 | "mime-types": {
847 | "version": "2.1.35",
848 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
849 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
850 | "requires": {
851 | "mime-db": "1.52.0"
852 | }
853 | },
854 | "ms": {
855 | "version": "2.0.0",
856 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
857 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
858 | },
859 | "negotiator": {
860 | "version": "0.6.3",
861 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
862 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
863 | },
864 | "object-inspect": {
865 | "version": "1.12.2",
866 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
867 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
868 | },
869 | "on-finished": {
870 | "version": "2.4.1",
871 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
872 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
873 | "requires": {
874 | "ee-first": "1.1.1"
875 | }
876 | },
877 | "parseurl": {
878 | "version": "1.3.3",
879 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
880 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
881 | },
882 | "path-to-regexp": {
883 | "version": "0.1.7",
884 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
885 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
886 | },
887 | "proxy-addr": {
888 | "version": "2.0.7",
889 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
890 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
891 | "requires": {
892 | "forwarded": "0.2.0",
893 | "ipaddr.js": "1.9.1"
894 | }
895 | },
896 | "qs": {
897 | "version": "6.11.0",
898 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
899 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
900 | "requires": {
901 | "side-channel": "^1.0.4"
902 | }
903 | },
904 | "range-parser": {
905 | "version": "1.2.1",
906 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
907 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
908 | },
909 | "raw-body": {
910 | "version": "2.5.1",
911 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
912 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
913 | "requires": {
914 | "bytes": "3.1.2",
915 | "http-errors": "2.0.0",
916 | "iconv-lite": "0.4.24",
917 | "unpipe": "1.0.0"
918 | }
919 | },
920 | "safe-buffer": {
921 | "version": "5.2.1",
922 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
923 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
924 | },
925 | "safer-buffer": {
926 | "version": "2.1.2",
927 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
928 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
929 | },
930 | "send": {
931 | "version": "0.18.0",
932 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
933 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
934 | "requires": {
935 | "debug": "2.6.9",
936 | "depd": "2.0.0",
937 | "destroy": "1.2.0",
938 | "encodeurl": "~1.0.2",
939 | "escape-html": "~1.0.3",
940 | "etag": "~1.8.1",
941 | "fresh": "0.5.2",
942 | "http-errors": "2.0.0",
943 | "mime": "1.6.0",
944 | "ms": "2.1.3",
945 | "on-finished": "2.4.1",
946 | "range-parser": "~1.2.1",
947 | "statuses": "2.0.1"
948 | },
949 | "dependencies": {
950 | "ms": {
951 | "version": "2.1.3",
952 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
953 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
954 | }
955 | }
956 | },
957 | "serve-static": {
958 | "version": "1.15.0",
959 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
960 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
961 | "requires": {
962 | "encodeurl": "~1.0.2",
963 | "escape-html": "~1.0.3",
964 | "parseurl": "~1.3.3",
965 | "send": "0.18.0"
966 | }
967 | },
968 | "setprototypeof": {
969 | "version": "1.2.0",
970 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
971 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
972 | },
973 | "side-channel": {
974 | "version": "1.0.4",
975 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
976 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
977 | "requires": {
978 | "call-bind": "^1.0.0",
979 | "get-intrinsic": "^1.0.2",
980 | "object-inspect": "^1.9.0"
981 | }
982 | },
983 | "statuses": {
984 | "version": "2.0.1",
985 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
986 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
987 | },
988 | "toidentifier": {
989 | "version": "1.0.1",
990 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
991 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
992 | },
993 | "type-is": {
994 | "version": "1.6.18",
995 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
996 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
997 | "requires": {
998 | "media-typer": "0.3.0",
999 | "mime-types": "~2.1.24"
1000 | }
1001 | },
1002 | "unpipe": {
1003 | "version": "1.0.0",
1004 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1005 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
1006 | },
1007 | "utils-merge": {
1008 | "version": "1.0.1",
1009 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1010 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
1011 | },
1012 | "vary": {
1013 | "version": "1.1.2",
1014 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1015 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
1016 | }
1017 | }
1018 | }
1019 |
--------------------------------------------------------------------------------
/api-learnv2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api-learnv2",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "app.js",
6 | "scripts": {
7 | "start": "nodemon app.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "express": "^4.18.2"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/api-learnv2/src/middlewares/middleware.js:
--------------------------------------------------------------------------------
1 | const authControl = (req, res, next) => {
2 | const isToken = true
3 | if (isToken) {
4 | next()
5 | } else {
6 | res.json({
7 | succes: false,
8 | message: "No token provided!"
9 | })
10 | }
11 | }
12 |
13 | const banControl = (req, res, next) => {
14 | const isBanned = false
15 | if (isBanned) {
16 | res.json({
17 | succes: false,
18 | message: "You are banned user!"
19 | })
20 | } else {
21 | next()
22 | }
23 | }
24 |
25 | const homeControl = (req, res, next) => {
26 | console.log("home control")
27 | next()
28 | }
29 |
30 | module.exports = {
31 | authControl,
32 | banControl,
33 | homeControl,
34 | }
--------------------------------------------------------------------------------
/e-commerce-mysql/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/e-commerce-mysql/.DS_Store
--------------------------------------------------------------------------------
/e-commerce-mysql/README.md:
--------------------------------------------------------------------------------
1 | ## 💻 Basic E-Commerce
2 |
3 | ### 🔎 Preview
4 | https://user-images.githubusercontent.com/55639112/194768553-8f44f112-6c84-4933-9ad8-2e44834eddec.mov
5 |
6 | ### 📁 Description
7 | Hello everyone! This is my first back-end project in software development. The project was written node.js programming langueage and with MySql Database. Project shows data on mysql database with ejs template engine. Also when I was coding of the design I used Bootstrap 5.2 version. The Home Screen was shown products. If you click to product name You can visit product detail page. Aside from that If you click to product tab on of the website You can visit product page and If you click to home tab on of the website You can visit home page. In pages of all data were come from mysql database. I am gonna show database scheme under chapter.
8 |
9 | ### 🚀 Database
10 |
11 |
12 |
13 | ### 🧑🏻💻 Coding
14 | I tried to write the code of this project as clean as possible and I learnt node.js, node.js routes, express, ejs and mysql.
15 |
--------------------------------------------------------------------------------
/e-commerce-mysql/data/db.js:
--------------------------------------------------------------------------------
1 | const mysql = require("mysql2")
2 | const config = require("../config")
3 |
4 | let dbConnection = mysql.createConnection(config.db)
5 |
6 | dbConnection.connect(function (err) {
7 | if (err) {
8 | console.error(err);
9 | }
10 | dbConnection.query("select * from Products", function (err, res) {
11 | console.log(res[0])
12 | console.log("********")
13 | })
14 | dbConnection.query("select * from Products where price > 25000.00", function (err, res) {
15 | console.log(res)
16 | console.log("********")
17 | })
18 | console.log("db connection was successful")
19 |
20 | })
21 |
22 | module.exports = dbConnection.promise();
--------------------------------------------------------------------------------
/e-commerce-mysql/default_index.js:
--------------------------------------------------------------------------------
1 |
2 | var http = require("http");
3 | var fs = require("fs");
4 |
5 | var server = http.createServer((req, res) => {
6 | switch (req.url) {
7 | case "/":
8 | readFile("views/index.html", res);
9 | break;
10 | case "/products":
11 | readFile("views/products.html", res);
12 | break;
13 | default:
14 | readFile("views/404.html", res);
15 | break;
16 | }
17 | });
18 |
19 | function readFile(path, res) {
20 | fs.readFile(path, (err, html) => {
21 | if (err) {
22 | res.write("
14 | Price: <%= price %>₺ 15 |
16 |17 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum, a? Dicta 18 | libero quibusdam amet similique iusto inventore aut labore molestias natus 19 | cum explicabo odio unde, repellat sed in, nam perspiciatis fuga a ratione. 20 | Quis, animi odit! Officia, odio soluta cupiditate nesciunt error sequi 21 | tempore dolores, quia ea quas ipsa possimus! Perspiciatis nihil modi eum 22 | facere deleniti totam, repellat mollitia, quos dicta iste quisquam fuga, 23 | voluptatem a ipsam similique. Id quia beatae reprehenderit rerum dicta 24 | nostrum saepe ullam, commodi maxime? Reiciendis nisi minima mollitia! 25 | Quaerat, corporis excepturi tempora debitis minima similique voluptates quas 26 | reprehenderit, labore earum amet? Expedita, dolore sunt? A! 27 |
28 |29 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum, a? Dicta 30 | libero quibusdam amet similique iusto inventore aut labore molestias natus 31 | cum explicabo odio unde, repellat sed in, nam perspiciatis fuga a ratione. 32 | Quis, animi odit! Officia, odio soluta cupiditate nesciunt error sequi 33 | tempore dolores, quia ea quas ipsa possimus! Perspiciatis nihil modi eum 34 | facere deleniti totam, repellat mollitia, quos dicta iste quisquam fuga, 35 | voluptatem a ipsam similique. Id quia beatae reprehenderit rerum dicta 36 | nostrum saepe ullam, commodi maxime? Reiciendis nisi minima mollitia! 37 | Quaerat, corporis excepturi tempora debitis minima similique voluptates quas 38 | reprehenderit, labore earum amet? Expedita, dolore sunt? A! 39 |
40 |This is your reset password token : ${token}.
67 | ` 68 | 69 | try { 70 | await sendMail({ 71 | from: process.env.SMTP_USER, 72 | to: resetEmail, 73 | subject: "Reset ur password.", 74 | html: emailTemplate 75 | }) 76 | user.resetPasswordToken = token 77 | await user.save() 78 | res.status(200).json( 79 | { 80 | success: true, 81 | message: "Password reset successful. A 6-digit password reset token has been sent to your email.", 82 | token: token 83 | } 84 | ) 85 | } catch (err) { 86 | user.resetPasswordToken = undefined 87 | await user.save() 88 | return next(new CustomError("Email could not be sent", 500)) 89 | } 90 | 91 | }) 92 | 93 | const resetPassword = asyncErrorHandler(async (req, res, next) => { 94 | 95 | const { resetPasswordToken } = req.query 96 | const { password } = req.body 97 | 98 | if (!resetPasswordToken) { 99 | return next(new CustomError("Please provide a valid token", 400)) 100 | } 101 | let user = await User.findOne({ 102 | resetPasswordToken: resetPasswordToken, 103 | }) 104 | if (!user) { 105 | return next(new CustomError("Please provide a valid token", 400)) 106 | } else { 107 | user.password = password 108 | await user.save() 109 | 110 | return res.status(200).json( 111 | { 112 | success: true, 113 | message: "Reset password process successful!", 114 | user: user 115 | } 116 | ) 117 | } 118 | 119 | 120 | }) 121 | 122 | const imageUpload = asyncErrorHandler(async (req, res, next) => { 123 | 124 | const user = await User.findByIdAndUpdate(req.user.id, { 125 | "img": req.savedProfileImage 126 | }, { new: true, runValidators: true }) 127 | 128 | res.status(200).json({ 129 | success: true, 130 | message: "Image Upload Successful", 131 | user: user 132 | }) 133 | }) 134 | 135 | export { 136 | register, login, 137 | tokenControl, forgotPassword, 138 | resetPassword, imageUpload 139 | } -------------------------------------------------------------------------------- /question-answer-api/src/controllers/quesitons.controller.js: -------------------------------------------------------------------------------- 1 | import Question from "../models/question.model.js" 2 | import User from "../models/user.model.js" 3 | import CustomError from "../helpers/error/CustomError.js" 4 | import asyncErrorHandler from "express-async-handler" 5 | import Answer from "../models/answer.model.js" 6 | 7 | const getAllQuestions = asyncErrorHandler(async (req, res, next) => { 8 | let query = Question.find({ isActive: true }) 9 | .populate( 10 | { 11 | path: "user", 12 | select: "id name lastname question" 13 | } 14 | ).populate( 15 | { 16 | path: "answer", 17 | match: { isActive: true } 18 | } 19 | ).populate( 20 | { 21 | path: "fav" 22 | } 23 | ) 24 | 25 | 26 | const questions = await query 27 | questions.sort((a, b) => b.createdAt - a.createdAt) 28 | 29 | return res.status(200) 30 | .json({ 31 | questions 32 | }) 33 | }) 34 | 35 | const getQuestion = asyncErrorHandler(async (req, res, next) => { 36 | const question = await Question.findOne( 37 | { 38 | _id: req.question.id, 39 | isActive: true 40 | } 41 | ) 42 | .populate( 43 | { 44 | path: "user", 45 | select: "id name lastname question" 46 | } 47 | ).populate( 48 | { 49 | path: "answer", 50 | match: { isActive: true } 51 | } 52 | ).populate( 53 | { 54 | path: "fav" 55 | } 56 | ) 57 | if (question) { 58 | return res.status(200) 59 | .json({ 60 | success: true, 61 | question: question 62 | }) 63 | } else { 64 | return next(new CustomError("This question was deleted.")) 65 | } 66 | 67 | }) 68 | 69 | const addQuestion = asyncErrorHandler(async (req, res, next) => { 70 | const params = req.body 71 | const question = await Question.create({ 72 | ...params, 73 | user: req.user.id, 74 | }) 75 | const user = await User.findById({ _id: req.user.id }) 76 | user.question.push(question) 77 | await user.save() 78 | res.status(200) 79 | .json({ 80 | success: true, 81 | message: "You added a question in successful!", 82 | question: question, 83 | }) 84 | }) 85 | 86 | const updateQuestion = asyncErrorHandler(async (req, res, next) => { 87 | const params = req.body 88 | const question = req.question 89 | let updatedQuestion = await Question.findByIdAndUpdate(question.id, { 90 | ...params 91 | }, { new: true, runValidators: true }).populate( 92 | { 93 | path: "user", 94 | select: "id name lastname" 95 | } 96 | ).populate( 97 | { 98 | path: "answer", 99 | } 100 | ) 101 | 102 | updatedQuestion = await updatedQuestion.save() 103 | 104 | return res.status(200) 105 | .json({ 106 | success: true, 107 | question: updatedQuestion, 108 | }) 109 | }) 110 | 111 | const deleteQuestion = asyncErrorHandler(async (req, res, next) => { 112 | const userId = req.user.id 113 | 114 | const question = req.question 115 | question.isActive = false 116 | question.answer.forEach(async e => { 117 | await Answer.findByIdAndUpdate(e, { isActive: false }) 118 | }); 119 | 120 | await question.save() 121 | return res.status(200) 122 | .json({ 123 | success: true, 124 | deletedQuestion: question 125 | }) 126 | }) 127 | 128 | const favQuestion = asyncErrorHandler(async (req, res, next) => { 129 | const question = req.question 130 | if (question.fav.includes(req.user.id)) { 131 | return next(new CustomError("You already fav this question", 400)) 132 | } 133 | question.fav.push(req.user.id) 134 | await question.save() 135 | return res.status(200) 136 | .json({ 137 | success: true, 138 | question: question 139 | }) 140 | }) 141 | 142 | const unFavQuestion = asyncErrorHandler(async (req, res, next) => { 143 | let question = req.question 144 | if (!question.fav.includes(req.user.id)) { 145 | return next(new CustomError("You already unfav this question", 400)) 146 | } 147 | question.fav = question.fav.filter(e => !question.fav.includes(e)) 148 | await question.save() 149 | return res.status(200) 150 | .json({ 151 | success: true, 152 | question: question 153 | }) 154 | }) 155 | 156 | export { 157 | getAllQuestions, getQuestion, 158 | addQuestion, updateQuestion, 159 | deleteQuestion, favQuestion, 160 | unFavQuestion 161 | } -------------------------------------------------------------------------------- /question-answer-api/src/controllers/user.controller.js: -------------------------------------------------------------------------------- 1 | 2 | import User from "../models/user.model.js" 3 | import asyncErrorHandler from "express-async-handler" 4 | 5 | const getAllUsers = asyncErrorHandler(async (req, res, next) => { 6 | const users = await User.find() 7 | return res.status(200) 8 | .json({ 9 | success: true, 10 | users: users 11 | }) 12 | }) 13 | 14 | const getUserById = asyncErrorHandler(async (req, res, next) => { 15 | const user = await User.findById({ _id: req.params.id }) 16 | .populate({ 17 | path: "question", 18 | match: { isActive: true }, 19 | populate: { 20 | path: "answer", 21 | match: { isActive: true } 22 | } 23 | }) 24 | .populate({ 25 | path: "answer", 26 | match: { isActive: true } 27 | }) 28 | return res.status(200) 29 | .json({ 30 | success: true, 31 | user: user 32 | }) 33 | }) 34 | 35 | const editProfile = asyncErrorHandler(async (req, res, next) => { 36 | const body = req.body 37 | const user = await User.findByIdAndUpdate(req.user.id, 38 | { ...body, email: req.user.email }, 39 | { new: true }) 40 | return res.status(200) 41 | .json({ 42 | succes: true, 43 | updatedUser: user 44 | }) 45 | }) 46 | 47 | export { getAllUsers, getUserById, editProfile } -------------------------------------------------------------------------------- /question-answer-api/src/helpers/auth/auth.helper.js: -------------------------------------------------------------------------------- 1 | const isTokenIncluded = (req) => { 2 | return (req.headers['authorization'] 3 | .startsWith("Bearer ")) 4 | } 5 | 6 | const getAccessTokenFromHeader = (req) => { 7 | const authorization = req.headers['authorization'] 8 | // [Bearer:] First index of list 9 | // [token] Second index of list 10 | const token = authorization.split(" ")[1] 11 | return token 12 | } 13 | 14 | export { isTokenIncluded, getAccessTokenFromHeader } -------------------------------------------------------------------------------- /question-answer-api/src/helpers/db/db.error.helpers.js: -------------------------------------------------------------------------------- 1 | import asyncErrorHandler from "express-async-handler" 2 | import User from "../../models/user.model.js" 3 | import Question from "../../models/question.model.js" 4 | import Answer from "../../models/answer.model.js" 5 | import CustomError from "../../helpers/error/CustomError.js" 6 | 7 | const checkUserExist = asyncErrorHandler(async (req, res, next) => { 8 | const { id } = req.params 9 | const user = await User.findById({ _id: id }) 10 | if (!user) { 11 | return next(new CustomError("There is no such user with that id"), 400) 12 | } 13 | req.user = user 14 | next() 15 | }) 16 | 17 | const checkQuesitonExist = asyncErrorHandler(async (req, res, next) => { 18 | const { id } = req.params 19 | const question = await Question.findById({ _id: id, }) 20 | if (!question) { 21 | return next(new CustomError("There is no such question with that id"), 400) 22 | } 23 | req.question = question 24 | next() 25 | }) 26 | 27 | const checkAnswerExist = asyncErrorHandler(async (req, res, next) => { 28 | const { answerId } = req.params 29 | const questionId = req.question._id 30 | const question = await Question.findOne( 31 | { _id: questionId, isActive: true } 32 | ) 33 | if (question) { 34 | const answer = await Answer.findOne({ 35 | _id: answerId, 36 | question: questionId 37 | }).populate({ 38 | path: "user", 39 | select: "id name lastname " 40 | }) 41 | .populate({ 42 | path: "question", 43 | select: "id title subtitle" 44 | }) 45 | if (!answer) { 46 | return next(new CustomError("There is no such answer with that id"), 400) 47 | } 48 | req.answer = answer 49 | next() 50 | } else { 51 | return next(new CustomError("This question was deleted.")) 52 | } 53 | 54 | }) 55 | 56 | export { checkUserExist, checkQuesitonExist, checkAnswerExist } -------------------------------------------------------------------------------- /question-answer-api/src/helpers/db/db.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | 3 | const connectDb = async () => { 4 | try { 5 | await mongoose.connect(process.env.MONGO_URI) 6 | console.log("connection successful!") 7 | } catch (err) { 8 | console.error(err) 9 | } 10 | } 11 | 12 | export default connectDb -------------------------------------------------------------------------------- /question-answer-api/src/helpers/error/CustomError.js: -------------------------------------------------------------------------------- 1 | class CustomError extends Error { 2 | constructor(message, status) { 3 | super(message) 4 | this.status = status 5 | } 6 | } 7 | 8 | export default CustomError -------------------------------------------------------------------------------- /question-answer-api/src/helpers/input/input.helper.js: -------------------------------------------------------------------------------- 1 | import bcrypt from "bcryptjs" 2 | import CustomError from "../error/CustomError.js" 3 | 4 | const validateUserInput = (email, pass, next) => { 5 | if (!email) { 6 | return next(new CustomError("Please enter email.", 400)) 7 | } else if (!pass) { 8 | return next(new CustomError("Please enter password.", 400)) 9 | } else if (!email && !pass) { 10 | return next(new CustomError("Please enter email and password.", 400)) 11 | } 12 | } 13 | 14 | const comparePassword = (pass, hashPass) => { 15 | return bcrypt.compareSync(pass, hashPass) 16 | } 17 | 18 | export { validateUserInput, comparePassword } -------------------------------------------------------------------------------- /question-answer-api/src/helpers/libraries/sendEmail.js: -------------------------------------------------------------------------------- 1 | import nodemailer from "nodemailer" 2 | 3 | const sendMail = async (mailOptions) => { 4 | const { SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD } = process.env 5 | let transporter = nodemailer.createTransport({ 6 | host: SMTP_HOST, 7 | port: SMTP_PORT, 8 | secure: true, 9 | auth: { 10 | user: SMTP_USER, 11 | pass: SMTP_PASSWORD 12 | } 13 | }) 14 | 15 | let info = await transporter.sendMail(mailOptions) 16 | console.log(`Message send: ${info.messageId}`) 17 | } 18 | 19 | export default sendMail -------------------------------------------------------------------------------- /question-answer-api/src/middlewares/auth.middleware.js: -------------------------------------------------------------------------------- 1 | import jwt from "jsonwebtoken" 2 | import asyncErrorHandler from "express-async-handler" 3 | import CustomError from "../helpers/error/CustomError.js" 4 | import User from "../models/user.model.js" 5 | import Question from "../models/question.model.js" 6 | import { 7 | isTokenIncluded, 8 | getAccessTokenFromHeader 9 | } from "../helpers/auth/auth.helper.js" 10 | 11 | const getAccessToRoute = (req, res, next) => { 12 | const unAuthorizedError = new CustomError("No token provided", 401) 13 | const { JWT_SECRET_KEY } = process.env 14 | if (!isTokenIncluded(req)) { 15 | return next(unAuthorizedError) 16 | } 17 | const token = getAccessTokenFromHeader(req) 18 | 19 | 20 | jwt.verify(token, JWT_SECRET_KEY, (err, decoded) => { 21 | if (err) { 22 | return next(unAuthorizedError) 23 | } 24 | req.user = { 25 | id: decoded.id, 26 | name: decoded.name, 27 | } 28 | next() 29 | }) 30 | } 31 | 32 | const getAdminAccess = asyncErrorHandler(async (req, res, next) => { 33 | const { id } = req.user 34 | const user = await User.findById({ _id: id }) 35 | 36 | if (user.role != "admin") { 37 | return next(new CustomError("Only admins can access this route", 403)) 38 | } 39 | next() 40 | }) 41 | 42 | const getQuestionOwnerAccess = asyncErrorHandler(async (req, res, next) => { 43 | const userId = req.user.id 44 | const { id } = req.params 45 | const question = await Question.findById({ _id: id }) 46 | 47 | if (question.user != userId) { 48 | return next(new CustomError("Only owner can handle this operation", 403)) 49 | } 50 | req.question = question 51 | next() 52 | }) 53 | 54 | export { 55 | getAccessToRoute, 56 | getAdminAccess, 57 | getQuestionOwnerAccess 58 | } -------------------------------------------------------------------------------- /question-answer-api/src/middlewares/error.handler.js: -------------------------------------------------------------------------------- 1 | import CustomError from "../helpers/error/CustomError.js" 2 | 3 | const errorHandler = (err, req, res, next) => { 4 | let customError = err 5 | console.log(customError.name, customError.message) 6 | if (err.name == "SyntaxError") { 7 | customError = new CustomError("Unexpected Syntax", 400) 8 | } 9 | if (err.name == "ValidationError") { 10 | if (err.message.includes("content") && err.message.includes("a content")) { 11 | customError = new CustomError("Please provide a content.", 400) 12 | } else if (err.message.includes("content")) { 13 | customError = new CustomError("Please provide a title at least 10 characters.", 400) 14 | } else { 15 | customError = new CustomError(err.message, 400) 16 | } 17 | } 18 | if (err.code == 11000) { 19 | // Duplicate Key error 20 | if (err.message.includes("email")) { 21 | const message = "Your email address is used.\nPlease try again with enter other email." 22 | customError = new CustomError(message, 400) 23 | 24 | } else if (err.message.includes("title")) { 25 | const message = "This title is used.\nPlease try again with enter other title." 26 | customError = new CustomError(message, 400) 27 | } else { 28 | customError = new CustomError("Duplicate Key Error", 400) 29 | } 30 | } 31 | 32 | res.status(customError.status || 500).json( 33 | { 34 | succes: false, 35 | message: customError.message || "Internal Server Error" 36 | } 37 | ) 38 | } 39 | 40 | export { errorHandler } -------------------------------------------------------------------------------- /question-answer-api/src/middlewares/image.upload.js: -------------------------------------------------------------------------------- 1 | import multer from "multer" 2 | import path from "path" 3 | import CustomError from "../helpers/error/CustomError.js" 4 | 5 | const storage = multer.diskStorage({ 6 | destination: function (req, file, cb) { 7 | const rootDir = path.dirname(require.main.filename) 8 | cb(null, path.join(rootDir, "/public/uploads")) 9 | }, 10 | filename: function (req, file, cb) { 11 | // File - Mimetype - image/png, image/jpg 12 | const extension = file.mimetype.split("/")[1] 13 | req.savedProfileImage = `image_${req.user.id}.${extension}` 14 | cb(null, req.savedProfileImage) 15 | } 16 | }) 17 | 18 | const fileFilter = (req, file, cb) => { 19 | let allowedTypes = ["image/jpg", "image/jpeg", "image/png"] 20 | 21 | if (!allowedTypes.includes(file.mimetype)) { 22 | return cb(new CustomError("Please provide a valid image file", 400), false) 23 | } 24 | return cb(null, true) 25 | } 26 | 27 | const profileImageUpload = multer({ storage, fileFilter }) 28 | 29 | export default profileImageUpload -------------------------------------------------------------------------------- /question-answer-api/src/models/answer.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | import Question from "../models/question.model.js" 3 | 4 | const AnswerSchema = new mongoose.Schema({ 5 | content: { 6 | type: String, 7 | required: [true, "Please provide a content"], 8 | minlength: [10, "Please provide a title at least 10 characters"] 9 | }, 10 | createdAt: { 11 | type: Date, 12 | default: Date.now() 13 | }, 14 | fav: [ 15 | { 16 | type: mongoose.Schema.ObjectId, 17 | ref: "User" 18 | } 19 | ], 20 | user: { 21 | type: mongoose.Schema.ObjectId, 22 | ref: "User", 23 | required: true 24 | }, 25 | question: { 26 | type: mongoose.Schema.ObjectId, 27 | ref: "Question", 28 | required: true 29 | }, 30 | isActive: { 31 | type: Boolean, 32 | default: true, 33 | } 34 | }) 35 | 36 | AnswerSchema.pre("save", async function (next) { 37 | if (!this.isModified("user")) return next() 38 | 39 | try { 40 | const question = await Question.findById({ _id: this.question }) 41 | question.answer.push(this._id) 42 | await question.save() 43 | next() 44 | } catch (err) { 45 | return next(err) 46 | } 47 | }) 48 | 49 | const Answer = mongoose.model("Answer", AnswerSchema) 50 | 51 | export default Answer -------------------------------------------------------------------------------- /question-answer-api/src/models/question.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | import slugify from "slugify" 3 | 4 | const QuesitonSchema = new mongoose.Schema({ 5 | title: { 6 | type: String, 7 | required: [true, "Please provide a title"], 8 | minlength: [10, "Please provide a title at least 10 characters"], 9 | unique: true, 10 | }, 11 | subtitle: { 12 | type: String, 13 | required: [true, "Please provide a subtitle"], 14 | minlength: [10, "Please provide a subtitle at least 10 characters"], 15 | }, 16 | slug: String, 17 | createdAt: { 18 | type: Date, 19 | default: Date.now() 20 | }, 21 | isActive: { 22 | type: Boolean, 23 | default: true, 24 | }, 25 | user: { 26 | type: mongoose.Schema.ObjectId, 27 | required: true, 28 | ref: "User", 29 | }, 30 | fav: [ 31 | { 32 | type: mongoose.Schema.ObjectId, 33 | ref: "User" 34 | } 35 | ], 36 | answer: [ 37 | { 38 | type: mongoose.Schema.ObjectId, 39 | ref: "Answer" 40 | } 41 | ], 42 | }) 43 | 44 | QuesitonSchema.pre("save", function (next) { 45 | if (!this.isModified("title")) { 46 | next() 47 | } 48 | this.slug = this.createSlugify() 49 | next() 50 | }) 51 | 52 | QuesitonSchema.methods.createSlugify = function () { 53 | return slugify(this.title, { 54 | replacement: "-", 55 | remove: /[*+~.()'"!:@]/g, 56 | lower: true, 57 | trim: true, 58 | }) 59 | } 60 | 61 | const Question = mongoose.model("Question", QuesitonSchema) 62 | export default Question -------------------------------------------------------------------------------- /question-answer-api/src/models/user.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import bcrypt from "bcryptjs" 3 | import jwt from "jsonwebtoken" 4 | import crypto from "crypto" 5 | import Question from "../models/question.model.js" 6 | 7 | const UserSchema = new mongoose.Schema({ 8 | name: { 9 | type: String, 10 | required: [true, "Please provide a name"], 11 | trim: true 12 | }, 13 | lastname: { 14 | type: String, 15 | required: [true, "Please provide a lastname"], 16 | trim: true 17 | }, 18 | email: { 19 | type: String, 20 | required: [true, "Please provide a email"], 21 | unique: true, 22 | match: [ 23 | /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, 24 | "Please provide a valid email" 25 | ], 26 | }, 27 | role: { 28 | type: String, 29 | default: "user", 30 | enum: ["user", "admin"] 31 | }, 32 | password: { 33 | type: String, 34 | minLength: [6, "Please provide a password with min lenght 6"], 35 | required: [true, "Please provide a password"], 36 | select: false 37 | }, 38 | createdAt: { 39 | type: Date, 40 | default: Date.now 41 | }, 42 | title: { 43 | type: String 44 | }, 45 | about: { 46 | type: String 47 | }, 48 | place: { 49 | type: String 50 | }, 51 | website: { 52 | type: String 53 | }, 54 | img: { 55 | type: String, 56 | default: "default.svg" 57 | }, 58 | isBlocked: { 59 | type: Boolean, 60 | default: false, 61 | }, 62 | isActive: { 63 | type: Boolean, 64 | default: true, 65 | }, 66 | resetPasswordToken: { 67 | type: String 68 | }, 69 | question: [ 70 | { 71 | type: mongoose.Schema.ObjectId, 72 | ref: "Question" 73 | } 74 | ], 75 | answer: [ 76 | { 77 | type: mongoose.Schema.ObjectId, 78 | ref: "Answer" 79 | } 80 | ], 81 | token: { 82 | type: String 83 | } 84 | }) 85 | 86 | UserSchema.methods.generateJwtFromUser = function () { 87 | const { JWT_SECRET_KEY, JWT_EXPIRE } = process.env 88 | const payload = { 89 | id: this._id, 90 | name: this.name 91 | } 92 | const token = jwt.sign(payload, JWT_SECRET_KEY, { expiresIn: JWT_EXPIRE }) 93 | return token 94 | } 95 | 96 | UserSchema.methods.getResetPasswordTokenFromUser = function () { 97 | const randomHexString = crypto.randomBytes(16).toString("hex") 98 | const resetPasswordToken = crypto 99 | .createHash("SHA256") 100 | .update(randomHexString) 101 | .digest("hex") 102 | const { RESET_PASSWORD_EXPIRE } = process.env 103 | this.resetPasswordToken = resetPasswordToken 104 | this.resetPasswordExpire = Date.now() + parseInt(RESET_PASSWORD_EXPIRE) 105 | return resetPasswordToken 106 | } 107 | 108 | UserSchema.pre("save", function (next) { 109 | // password is change? 110 | if (!this.isModified("password")) { 111 | next() 112 | } 113 | 114 | // if password is not change, password is hashed 115 | bcrypt.genSalt(10, (err, salt) => { 116 | if (err) next(err) 117 | bcrypt.hash(this.password, salt, (err, hash) => { 118 | if (err) next(err) 119 | this.password = hash 120 | next() 121 | }) 122 | }) 123 | }) 124 | 125 | const User = mongoose.model("User", UserSchema) 126 | 127 | export default User -------------------------------------------------------------------------------- /question-answer-api/src/routes/admin.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute, getAdminAccess} from "../middlewares/auth.middleware.js" 3 | import { blockUser, deleteUser } from "../controllers/admin.contoller.js" 4 | import { checkUserExist } from "../helpers/db/db.error.helpers.js" 5 | 6 | const router = express.Router() 7 | 8 | router.use([getAccessToRoute, getAdminAccess]) 9 | 10 | router.get("/blockUser/:id", checkUserExist, blockUser) 11 | router.delete("/deleteUser/:id", checkUserExist, deleteUser) 12 | 13 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/answer.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute } from "../middlewares/auth.middleware.js" 3 | import { checkAnswerExist } from "../helpers/db/db.error.helpers.js" 4 | import { 5 | getAllAnswers, getAnswerById, 6 | addNewAnswerToQuestion, updateAnswer, 7 | deleteAnswer, favAnswer, 8 | unFavAnswer 9 | } from "../controllers/answer.controller.js" 10 | const router = express.Router({ mergeParams: true }) 11 | 12 | router.use(getAccessToRoute) 13 | 14 | router.get("/", getAllAnswers) 15 | router.post("/", addNewAnswerToQuestion) 16 | router.get("/:answerId", checkAnswerExist, getAnswerById), 17 | router.put("/:answerId", checkAnswerExist, updateAnswer) 18 | router.delete("/:answerId", checkAnswerExist, deleteAnswer) 19 | router.get("/:answerId/favAnswer", checkAnswerExist, favAnswer) 20 | router.get("/:answerId/unFavAnswer", checkAnswerExist, unFavAnswer) 21 | 22 | 23 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/auth.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute } from "../middlewares/auth.middleware.js" 3 | import { 4 | register, login, 5 | tokenControl, forgotPassword, 6 | resetPassword, imageUpload 7 | } from "../controllers/auth.controller.js" 8 | import profileImageUpload from "../middlewares/image.upload.js" 9 | const router = express.Router() 10 | 11 | router.post("/login", login) 12 | router.post("/register", register) 13 | router.get("/tokenControl", getAccessToRoute, tokenControl) 14 | router.post("/forgotPassword", forgotPassword) 15 | router.put("/resetPassword", resetPassword) 16 | router.post( 17 | "/imageUpload", 18 | [getAccessToRoute, profileImageUpload.single("profile_image")], 19 | imageUpload 20 | ) 21 | 22 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/index.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import auth from "./auth.js" 3 | import users from "./users.js" 4 | import admin from "./admin.js" 5 | import questions from "./questions.js" 6 | 7 | const router = express.Router() 8 | 9 | router.use("/auth", auth) 10 | router.use("/users", users) 11 | router.use("/admin", admin) 12 | router.use("/questions", questions) 13 | 14 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/questions.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute, getQuestionOwnerAccess } from "../middlewares/auth.middleware.js" 3 | import { checkQuesitonExist } from "../helpers/db/db.error.helpers.js" 4 | import { 5 | getAllQuestions, getQuestion, 6 | addQuestion, updateQuestion, 7 | deleteQuestion, favQuestion, 8 | unFavQuestion 9 | } from "../controllers/quesitons.controller.js" 10 | import answer from "../routes/answer.js" 11 | 12 | const router = express.Router() 13 | 14 | router.use(getAccessToRoute) 15 | router.get("/allQuestions", getAllQuestions) 16 | router.get("/getQuestion/:id", checkQuesitonExist, getQuestion) 17 | router.post("/ask", addQuestion) 18 | router.put( 19 | "/updateQuestion/:id", 20 | [checkQuesitonExist, 21 | getQuestionOwnerAccess], 22 | updateQuestion 23 | ) 24 | router.delete("/deleteQuestion/:id", 25 | [checkQuesitonExist, 26 | getQuestionOwnerAccess], 27 | deleteQuestion 28 | ) 29 | router.get("/favQuestion/:id", 30 | checkQuesitonExist, 31 | favQuestion 32 | ) 33 | router.get("/unFavQuestion/:id", 34 | checkQuesitonExist, 35 | unFavQuestion 36 | ) 37 | router.use("/:id/answers", checkQuesitonExist, answer) 38 | 39 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/users.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute } from "../middlewares/auth.middleware.js" 3 | import { 4 | getAllUsers, 5 | getUserById, 6 | editProfile 7 | } from "../controllers/user.controller.js" 8 | import { checkUserExist } from "../helpers/db/db.error.helpers.js" 9 | 10 | const router = express.Router() 11 | 12 | router.use(getAccessToRoute) 13 | 14 | router.get("/getAllUsers", getAllUsers) 15 | router.get("/:id", checkUserExist, getUserById) 16 | router.put("/edit", editProfile) 17 | 18 | export default router -------------------------------------------------------------------------------- /todo-mysql/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/todo-mysql/.DS_Store -------------------------------------------------------------------------------- /todo-mysql/README.MD: -------------------------------------------------------------------------------- 1 | ## 💻 Basic Todo App 2 | 3 | ### 🔎 Preview 4 | https://user-images.githubusercontent.com/55639112/195473254-c86797df-d656-4ed6-8e29-3c6b32720d47.mov 5 | 6 | ### 📁 Description 7 | Hello everyone! This is my second back-end project in software development. The project was written node.js programming langueage and with MySql Database. 8 | Project reads and writes data (read, write, delete, add) on mysql database with ejs template engine and nodejs. Also when I was coding of the design I used Bootstrap 5.2 version. In page all of the data and all of the operations (read, write, delete, add) on website is happened from database. You can create a todo list and management this list in this project. You can add and delete a todo or todos in your list otherwise you can delete all todos from your list. I am gonna show database scheme under chapter. 9 | 10 | ### 🚀 Database 11 |