Add user GET endpoint, schemas, and security middlewares
Introduces GET /users/:id endpoint with validation schema, adds tests for user and register routes, and applies security middlewares (helmet, hpp, cors) to the server. Also adds ESLint configuration and updates logger with linting comments.
This commit is contained in:
parent
7e1eaf3f1f
commit
335aef34e3
28
eslint.config.js
Normal file
28
eslint.config.js
Normal file
@ -0,0 +1,28 @@
|
||||
const js = require("@eslint/js")
|
||||
const globals = require("globals")
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
ignores: ["node_modules", "logs", "coverage", ".env", "*.log"],
|
||||
},
|
||||
js.configs.recommended,
|
||||
{
|
||||
languageOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "commonjs",
|
||||
globals: {
|
||||
...globals.node,
|
||||
...globals.jest,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
"no-unused-vars": "warn",
|
||||
"no-undef": "error",
|
||||
"eqeqeq": "error",
|
||||
"indent": ["error", 4],
|
||||
"quotes": ["error", "double"],
|
||||
"semi": ["error", "never"],
|
||||
"no-console": "warn",
|
||||
},
|
||||
},
|
||||
]
|
||||
@ -33,11 +33,13 @@ function write($stream, level, color, content, extraLabels = []) {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`[${date}] `.magenta + `[${level}]`[color] + consoleLabels + " " + message)
|
||||
$stream.write(`[${date}] [${level}]${fileLabels} ${stripColors(message)}\n`)
|
||||
}
|
||||
|
||||
function createLogger(root) {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
const fileName = (/false/).test(process.env.IS_PROD.toLowerCase()) ? new Date().toLocaleString("fr-FR", { timeZone: "UTC" }).replace(/[\/:]/g, "-").replace(/ /g, "_") : "DEV-LOG"
|
||||
|
||||
const logsDir = path.join(root, "logs")
|
||||
@ -77,6 +79,7 @@ function stripColors(string) {
|
||||
if (!string || typeof string !== "string") {
|
||||
return string
|
||||
}
|
||||
// eslint-disable-next-line no-control-regex
|
||||
return string.replace(/\x1B\[[0-9;]*[mK]/g, "")
|
||||
}
|
||||
|
||||
|
||||
1085
package-lock.json
generated
1085
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -17,18 +17,25 @@
|
||||
"scripts": {
|
||||
"start:dev": "nodemon .",
|
||||
"start": "node .",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"homepage": "https://gitea.azures.fr/azures04/Base-REST-API",
|
||||
"readme": "https://gitea.azures.fr/azures04/Base-REST-API/src/branch/main/README.md",
|
||||
"dependencies": {
|
||||
"colors": "^1.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^17.2.3",
|
||||
"express": "^5.2.1",
|
||||
"helmet": "^8.1.0",
|
||||
"hpp": "^0.2.3",
|
||||
"path-to-regexp": "^8.3.0",
|
||||
"zod": "^4.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.2",
|
||||
"eslint": "^9.39.2",
|
||||
"globals": "^16.5.0",
|
||||
"nodemon": "^3.1.11"
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,7 @@ const express = require("express")
|
||||
const router = express.Router()
|
||||
const registerService = require("../services/register")
|
||||
|
||||
router.post("/", async (req, res, next) => {
|
||||
try {
|
||||
router.post("/", async (req, res) => {
|
||||
const { email, username, password } = req.body
|
||||
const registerResult = registerService.register({ email, username, password })
|
||||
return res.status(200).json({
|
||||
@ -11,9 +10,6 @@ router.post("/", async (req, res, next) => {
|
||||
message: "User successfully registered",
|
||||
data: registerResult
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@ -1,8 +1,17 @@
|
||||
const express = require("express")
|
||||
const DefaultError = require("../../errors/DefaultError")
|
||||
const router = express.Router()
|
||||
|
||||
router.post("/", async (req, res, next) => {
|
||||
|
||||
router.get("", async (req, res) => {
|
||||
const bearer = req.headers.authorization
|
||||
if (bearer == "Bearer token") {
|
||||
return res.status(200).json({
|
||||
id: req.params.id,
|
||||
username: "johndoe"
|
||||
})
|
||||
} else {
|
||||
throw new DefaultError(403, "Invalid token", "", "InvalidTokenException")
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@ -3,9 +3,6 @@ const z = require("zod")
|
||||
module.exports = {
|
||||
POST: {
|
||||
headers: z.object({
|
||||
authorization: z.string()
|
||||
.startsWith("Bearer ", { message: "Token d'authentification manquant ou invalide." })
|
||||
.optional(),
|
||||
"content-type": z.string().regex(/application\/json/i).optional()
|
||||
}),
|
||||
body: z.object({
|
||||
|
||||
15
schemas/users/[id].js
Normal file
15
schemas/users/[id].js
Normal file
@ -0,0 +1,15 @@
|
||||
const z = require("zod")
|
||||
|
||||
module.exports = {
|
||||
GET: {
|
||||
headers: z.object({
|
||||
authorization: z.string()
|
||||
.startsWith("Bearer ", { message: "Token d'authentification manquant ou invalide." }),
|
||||
"content-type": z.string().regex(/application\/json/i).optional()
|
||||
}),
|
||||
error: {
|
||||
code: 422,
|
||||
message: "Invalid request data"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,12 @@
|
||||
const express = require("express")
|
||||
const hpp = require("hpp")
|
||||
const app = express()
|
||||
const cors = require("cors")
|
||||
const path = require("node:path")
|
||||
const utils = require("./modules/utils")
|
||||
const Logger = require("./modules/logger")
|
||||
const logger = Logger.createLogger(__dirname)
|
||||
const utils = require("./modules/utils")
|
||||
const helmet = require("helmet")
|
||||
const loader = require("./modules/loader")
|
||||
const DefaultError = require("./errors/DefaultError")
|
||||
const path2regex = require("path-to-regexp")
|
||||
@ -13,6 +16,10 @@ const schemas = loader.getRecursiveFiles(path.join(__dirname, "schemas"))
|
||||
|
||||
const schemaRegistry = {}
|
||||
|
||||
app.use(hpp())
|
||||
app.use(helmet())
|
||||
app.use(cors({ origin: "*" }))
|
||||
|
||||
app.use(express.json())
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
const crypto = require("node:crypto")
|
||||
const DefaultError = require("../errors/DefaultError")
|
||||
|
||||
function register({ email, username, password }) {
|
||||
if (true) {
|
||||
function register({ email, username }) {
|
||||
const canRegister = true
|
||||
if (canRegister === true) {
|
||||
return {
|
||||
id: crypto.randomUUID(),
|
||||
username: username,
|
||||
|
||||
8
tests/register.rest
Normal file
8
tests/register.rest
Normal file
@ -0,0 +1,8 @@
|
||||
POST http://localhost:3000/register HTTP/1.1
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"email": "johndoe@exemple.com",
|
||||
"username": "johndoe",
|
||||
"password": "Password123"
|
||||
}
|
||||
2
tests/users/id.rest
Normal file
2
tests/users/id.rest
Normal file
@ -0,0 +1,2 @@
|
||||
GET http://localhost:3000/users/johndoe HTTP/1.1
|
||||
authorization: Bearer token
|
||||
Loading…
x
Reference in New Issue
Block a user