mirror of
https://github.com/bubblecup-12/VogelSocialMedia.git
synced 2025-07-06 15:18:48 +00:00
added authentication and swagger
This commit is contained in:
parent
c311e3adda
commit
64c0d79438
8 changed files with 447 additions and 56 deletions
|
@ -1 +1,2 @@
|
|||
DATABASE_URL="postgres://postgres:YourPassword@localhost:5432/prisma"
|
||||
TOKEN_SECRET=ThisIsVeryImportantChangeThisToSomethingSecureThisIsUsedToEncryptTheJWT
|
|
@ -5,6 +5,8 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@prisma/client": "^6.7.0",
|
||||
"@types/bcryptjs": "^3.0.0",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.5.0",
|
||||
"express": "^5.1.0",
|
||||
|
@ -12,12 +14,16 @@
|
|||
"jsonwebtoken": "^9.0.2",
|
||||
"node": "^22.15.0",
|
||||
"pg": "^8.15.6",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"swagger-ui-express": "^5.0.1",
|
||||
"zod": "^3.24.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.1",
|
||||
"@types/jsonwebtoken": "^9.0.9",
|
||||
"@types/node": "^22.15.2",
|
||||
"@types/swagger-jsdoc": "^6.0.4",
|
||||
"@types/swagger-ui-express": "^4.1.8",
|
||||
"nodemon": "^3.1.10",
|
||||
"prettier": "3.5.3",
|
||||
"prisma": "^6.7.0",
|
||||
|
@ -26,7 +32,7 @@
|
|||
"typescript": "^5.8.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "ts-node src/server.ts",
|
||||
"start": "nodemon src/server.ts",
|
||||
"build": "tsc",
|
||||
"dev": "ts-node-dev --respawn src/server.ts"
|
||||
}
|
||||
|
|
|
@ -3,42 +3,107 @@ import { PrismaClient } from "@prisma/client";
|
|||
import { UserLoginDto, userLoginSchema } from "../schemas/userSchemas";
|
||||
import jwt from "jsonwebtoken";
|
||||
import dotenv from "dotenv";
|
||||
import { string } from "zod";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
const prisma = new PrismaClient();
|
||||
// load environment variables from .env file
|
||||
dotenv.config();
|
||||
const JWT_SECRET: string = process.env.TOKEN_SECRET!;
|
||||
|
||||
function generateAccessToken(username: string) {
|
||||
return jwt.sign({ username }, JWT_SECRET, { expiresIn: "1800s" });
|
||||
const JWT_SECRET: string = process.env.TOKEN_SECRET!; // this secret is used to sign the JWT token
|
||||
// Generate a JWT token with the username as payload and a secret from the environment variables which expires in 1800 seconds (30 minutes)
|
||||
function generateAccessToken(username: string, userId: string) {
|
||||
return jwt.sign(
|
||||
{ username: username, role: "user", sub: userId },
|
||||
JWT_SECRET,
|
||||
{ expiresIn: "1800s", issuer: "VogelApi" }
|
||||
); //TODO: change role to user role
|
||||
}
|
||||
|
||||
// Endpoint to register a new user
|
||||
export const registerUser = async (req: Request, res: Response) => {
|
||||
const userRequest = await req.body;
|
||||
const user = await prisma.user.create({ data: userRequest });
|
||||
console.log(user.username);
|
||||
res.json({ message: "User registered successfully", data: req.body });
|
||||
const { username, password, email } = await req.body; //gets the data from the request body
|
||||
if (!username || !password || !email) {
|
||||
// check if username, password and email are provided and
|
||||
res
|
||||
.status(400)
|
||||
.json({ message: "Username, password and email are required" });
|
||||
}
|
||||
const existingUser = await prisma.user.findUnique({
|
||||
// check if the user already exists
|
||||
where: {
|
||||
username: username,
|
||||
},
|
||||
});
|
||||
if (existingUser) {
|
||||
// if the user already exists, return an error message
|
||||
res.status(400).json({ message: `User "${username}" already exists` });
|
||||
}
|
||||
const hashedPassword = await bcrypt.hash(password, 10); // hash the password with bcrypt
|
||||
if (!hashedPassword) {
|
||||
// check if the password was hashed successfully
|
||||
res.status(500).json({ message: "Server Error" });
|
||||
}
|
||||
const userData = {
|
||||
// create a new user object with the data from the request body and the hashed password
|
||||
username: username,
|
||||
email: email,
|
||||
password: hashedPassword,
|
||||
};
|
||||
const user = await prisma.user.create({ data: userData }); // create a new user in the database
|
||||
if (!user) {
|
||||
// check if the user was created successfully
|
||||
res.status(500).json({ message: "Server Error" });
|
||||
}
|
||||
res.json({ message: "User registered successfully" });
|
||||
res.status(201).json({
|
||||
message: "user created",
|
||||
data: { username: username, email: email },
|
||||
}); // return the user object with the username and email
|
||||
};
|
||||
|
||||
export const loginUser = (req: Request, res: Response) => {
|
||||
const token: string = generateAccessToken(req.body.username);
|
||||
res.json({ message: "User logged in successfully", data: req.body, token });
|
||||
// Endpoint to login a user (unfinished)
|
||||
export const loginUser = async (req: Request, res: Response) => {
|
||||
const { username, password } = req.body; // get the data from the request body
|
||||
if (!username || !password) {
|
||||
// check if username and password are provided
|
||||
res.status(400).json({ message: "Username and password are required" });
|
||||
}
|
||||
const user = await prisma.user.findUnique({
|
||||
// check if the user exists
|
||||
where: {
|
||||
username: username,
|
||||
},
|
||||
});
|
||||
if (!user) {
|
||||
// if the user does not exist, return an error message
|
||||
res.status(400).json({ message: `User "${username}" not found` });
|
||||
return;
|
||||
}
|
||||
const isPasswordValid = await bcrypt.compare(password, user.password); // compare the password with the hashed password in the database
|
||||
if (!isPasswordValid) {
|
||||
// if the password is not valid, return an error message
|
||||
res.status(401).json({ message: "Invalid password" });
|
||||
}
|
||||
const token: string = generateAccessToken(user.username, user.id); // generate a JWT token with the username and userId as payload
|
||||
res.set("Authorization", `Bearer ${token}`); // set the token in the response header
|
||||
res.json({ message: "User logged in successfully" });
|
||||
};
|
||||
|
||||
// Endpoint to get user data
|
||||
export const getUser = async (req: Request, res: Response) => {
|
||||
const username = req.body.username;
|
||||
console.log(username, req.body);
|
||||
const username: string = req.query.username as string;
|
||||
if (!username) {
|
||||
res.status(400).json({ message: "Username is required" });
|
||||
}
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
username: username,
|
||||
},
|
||||
});
|
||||
if (!user) {
|
||||
res.status(404).json({ message: "User not found" });
|
||||
res.status(404).json({ message: `User "${username}" not found` });
|
||||
return;
|
||||
}
|
||||
res.json({ message: "User found", data: user });
|
||||
res.json({
|
||||
message: "User found",
|
||||
data: { username: user.username, email: user.email },
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
import express, { NextFunction, Request, Response } from "express";
|
||||
import jwt from "jsonwebtoken";
|
||||
import jwt, { TokenExpiredError } from "jsonwebtoken";
|
||||
import dotenv from "dotenv";
|
||||
import { string } from "zod";
|
||||
dotenv.config();
|
||||
// imports the JWT secret
|
||||
const JWT_SECRET: string = process.env.TOKEN_SECRET!;
|
||||
|
||||
if (!JWT_SECRET) console.log("no JWT secret");
|
||||
// create an interface for the JWT payload
|
||||
// this interface is used to define the structure of the JWT payload
|
||||
interface JwtPayload {
|
||||
username: string;
|
||||
iat: number;
|
||||
exp: number;
|
||||
}
|
||||
|
||||
// extend the Express Request interface to include the user property
|
||||
// this is used to store the JWT payload in the request object
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
|
@ -17,27 +21,26 @@ declare global {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Middleware function to authenticate the JWT token
|
||||
export function authenticateToken() {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
const authHeader = req.headers["authorization"];
|
||||
const token = authHeader && authHeader.split(" ")[1];
|
||||
const authHeader = req.headers["authorization"]; // get the authorization header from the request
|
||||
const token = authHeader && authHeader.split(" ")[1]; // split the header to get the token
|
||||
|
||||
if (token == null) res.sendStatus(401);
|
||||
if (token == null)
|
||||
res.sendStatus(401); // if there is no token, return 401 Unauthorized
|
||||
else {
|
||||
jwt.verify(
|
||||
token,
|
||||
process.env.TOKEN_SECRET as string,
|
||||
(err: any, user: any) => {
|
||||
console.log(err);
|
||||
|
||||
if (err) res.sendStatus(403);
|
||||
|
||||
req.user = user;
|
||||
|
||||
next();
|
||||
},
|
||||
);
|
||||
jwt.verify(token, JWT_SECRET, (err: any, user: any) => {
|
||||
// verify the token with the secret
|
||||
console.log(err);
|
||||
if (err) {
|
||||
if (err instanceof TokenExpiredError)
|
||||
// check if the error is expired and return 401
|
||||
res.status(401).json({ message: "Token expired" });
|
||||
else res.status(403).json({ message: "Invalid token" });
|
||||
}
|
||||
next();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,17 +14,100 @@ import {
|
|||
loginUser,
|
||||
getUser,
|
||||
} from "../controllers/userController";
|
||||
/**
|
||||
* @swagger
|
||||
* components:
|
||||
* schemas:
|
||||
* UserRegistrationDto:
|
||||
* type: object
|
||||
* required:
|
||||
* - username
|
||||
* - email
|
||||
* - password
|
||||
* properties:
|
||||
* username:
|
||||
* type: string
|
||||
* email:
|
||||
* type: string
|
||||
* format: email
|
||||
* password:
|
||||
* type: string
|
||||
* format: password
|
||||
* UserLoginDto:
|
||||
* type: object
|
||||
* required:
|
||||
* - username
|
||||
* - password
|
||||
* properties:
|
||||
* username:
|
||||
* type: string
|
||||
* password:
|
||||
* type: string
|
||||
*/
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/user/register:
|
||||
* post:
|
||||
* summary: Register a new user
|
||||
* tags: [User]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/UserRegistrationDto'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Benutzer erfolgreich registriert
|
||||
* 400:
|
||||
* description: Ungültige Eingabedaten
|
||||
*/
|
||||
userRouter.post(
|
||||
"/register",
|
||||
validateData(userRegistrationSchema),
|
||||
registerUser,
|
||||
registerUser
|
||||
);
|
||||
/**
|
||||
* @swagger
|
||||
* /api/user/login:
|
||||
* post:
|
||||
* summary: Log in a user
|
||||
* tags: [User]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/UserLoginDto'
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Login erfolgreich
|
||||
* 401:
|
||||
* description: Ungültige Anmeldedaten
|
||||
*/
|
||||
userRouter.post("/login", validateData(userLoginSchema), loginUser);
|
||||
userRouter.get(
|
||||
"/getUser",
|
||||
authenticateToken(),
|
||||
validateData(userLoginSchema),
|
||||
getUser,
|
||||
);
|
||||
/**
|
||||
* @swagger
|
||||
* /api/user/getUser/{username}:
|
||||
* get:
|
||||
* summary: Get user data
|
||||
* tags: [User]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: username
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* description: Der Benutzername, nach dem gesucht werden soll
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Login erfolgreich
|
||||
* 401:
|
||||
* description: Ungültige Anmeldedaten
|
||||
*/
|
||||
userRouter.get("/getUser/:username", authenticateToken(), getUser);
|
||||
|
||||
export default userRouter;
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const userRegistrationSchema = z.object({
|
||||
username: z.string(),
|
||||
username: z.string().regex(/^\S*$/, "Username must not contain spaces"), // No whitespaces allowed,
|
||||
email: z.string().email(),
|
||||
password: z.string().min(8),
|
||||
});
|
||||
|
||||
export const userLoginSchema = z.object({
|
||||
username: z.string(),
|
||||
password: z.string().min(8),
|
||||
username: z.string().regex(/^\S*$/, "Username must not contain spaces"), // No whitespaces allowed,
|
||||
password: z.string(),
|
||||
});
|
||||
// DTO-Typen aus den Schemas ableiten
|
||||
export type UserRegistrationDto = z.infer<typeof userRegistrationSchema>;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import express, { Request, Response } from "express";
|
||||
import express, { Request, Response, Application } from "express";
|
||||
|
||||
import dotenv from "dotenv";
|
||||
import userRouter from "./routes/userRoutes";
|
||||
|
@ -9,9 +9,50 @@ dotenv.config();
|
|||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
//swagger configuration
|
||||
import swaggerJSDoc from "swagger-jsdoc";
|
||||
import swaggerUi from "swagger-ui-express";
|
||||
|
||||
const options = {
|
||||
definition: {
|
||||
openapi: "3.1.0",
|
||||
info: {
|
||||
title: "VogelApi",
|
||||
version: "0.0.1",
|
||||
description:
|
||||
"This is a simple CRUD API application made with Express and documented with Swagger",
|
||||
},
|
||||
servers: [
|
||||
{
|
||||
url: "http://localhost:3000",
|
||||
},
|
||||
],
|
||||
components: {
|
||||
securitySchemes: {
|
||||
bearerAuth: {
|
||||
type: "http",
|
||||
scheme: "bearer",
|
||||
bearerFormat: "JWT", // Optional, for documentation purposes
|
||||
},
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{
|
||||
bearerAuth: [], // Apply globally if needed
|
||||
},
|
||||
],
|
||||
},
|
||||
apis: ["src/routes/*.ts"], // Hier werden alle Routen-Dateien mit Swagger-Kommentaren geladen
|
||||
};
|
||||
const specs = swaggerJSDoc(options);
|
||||
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(specs));
|
||||
|
||||
app.use(bodyParser.json());
|
||||
app.use("/api/user", userRouter);
|
||||
|
||||
// Sample route
|
||||
app.get("/api/hello", (req, res) => {
|
||||
res.send("Hello World!");
|
||||
});
|
||||
app.listen(port, () => {
|
||||
console.log(`Server läuft auf http://localhost:${port}`);
|
||||
});
|
||||
|
|
|
@ -2,6 +2,38 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@apidevtools/json-schema-ref-parser@^9.0.6":
|
||||
version "9.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz#8ff5386b365d4c9faa7c8b566ff16a46a577d9b8"
|
||||
integrity sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==
|
||||
dependencies:
|
||||
"@jsdevtools/ono" "^7.1.3"
|
||||
"@types/json-schema" "^7.0.6"
|
||||
call-me-maybe "^1.0.1"
|
||||
js-yaml "^4.1.0"
|
||||
|
||||
"@apidevtools/openapi-schemas@^2.0.4":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz#9fa08017fb59d80538812f03fc7cac5992caaa17"
|
||||
integrity sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==
|
||||
|
||||
"@apidevtools/swagger-methods@^3.0.2":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz#b789a362e055b0340d04712eafe7027ddc1ac267"
|
||||
integrity sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==
|
||||
|
||||
"@apidevtools/swagger-parser@10.0.3":
|
||||
version "10.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz#32057ae99487872c4dd96b314a1ab4b95d89eaf5"
|
||||
integrity sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==
|
||||
dependencies:
|
||||
"@apidevtools/json-schema-ref-parser" "^9.0.6"
|
||||
"@apidevtools/openapi-schemas" "^2.0.4"
|
||||
"@apidevtools/swagger-methods" "^3.0.2"
|
||||
"@jsdevtools/ono" "^7.1.3"
|
||||
call-me-maybe "^1.0.1"
|
||||
z-schema "^5.0.1"
|
||||
|
||||
"@cspotcode/source-map-support@^0.8.0":
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
|
||||
|
@ -152,6 +184,11 @@
|
|||
"@jridgewell/resolve-uri" "^3.0.3"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
|
||||
"@jsdevtools/ono@^7.1.3":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796"
|
||||
integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==
|
||||
|
||||
"@prisma/client@^6.7.0":
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-6.7.0.tgz#69f913b0a8cfb6aa5de5dca6aa57bfd4e91e7e95"
|
||||
|
@ -201,6 +238,11 @@
|
|||
dependencies:
|
||||
"@prisma/debug" "6.7.0"
|
||||
|
||||
"@scarf/scarf@=1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.4.0.tgz#3bbb984085dbd6d982494538b523be1ce6562972"
|
||||
integrity sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==
|
||||
|
||||
"@tsconfig/node10@^1.0.7":
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2"
|
||||
|
@ -221,6 +263,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
|
||||
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
|
||||
|
||||
"@types/bcryptjs@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-3.0.0.tgz#d7be11653aa82cf17ffee4f3925f1f80cfc1add2"
|
||||
integrity sha512-WRZOuCuaz8UcZZE4R5HXTco2goQSI2XxjGY3hbM/xDvwmqFWd4ivooImsMx65OKM6CtNKbnZ5YL+YwAwK7c1dg==
|
||||
dependencies:
|
||||
bcryptjs "*"
|
||||
|
||||
"@types/body-parser@*":
|
||||
version "1.19.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4"
|
||||
|
@ -246,7 +295,7 @@
|
|||
"@types/range-parser" "*"
|
||||
"@types/send" "*"
|
||||
|
||||
"@types/express@^5.0.1":
|
||||
"@types/express@*", "@types/express@^5.0.1":
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.1.tgz#138d741c6e5db8cc273bec5285cd6e9d0779fc9f"
|
||||
integrity sha512-UZUw8vjpWFXuDnjFTh7/5c2TWDlQqeXHi6hcN7F2XSVT5P+WmUnnbFS3KA6Jnc6IsEqI2qCVu2bK0R0J4A8ZQQ==
|
||||
|
@ -260,6 +309,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f"
|
||||
integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==
|
||||
|
||||
"@types/json-schema@^7.0.6":
|
||||
version "7.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
||||
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
||||
|
||||
"@types/jsonwebtoken@^9.0.9":
|
||||
version "9.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3"
|
||||
|
@ -322,6 +376,19 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
|
||||
integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==
|
||||
|
||||
"@types/swagger-jsdoc@^6.0.4":
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.4.tgz#bb4f60f3a5f103818e022f2e29ff8935113fb83d"
|
||||
integrity sha512-W+Xw5epcOZrF/AooUM/PccNMSAFOKWZA5dasNyMujTwsBkU74njSJBpvCCJhHAJ95XRMzQrrW844Btu0uoetwQ==
|
||||
|
||||
"@types/swagger-ui-express@^4.1.8":
|
||||
version "4.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/swagger-ui-express/-/swagger-ui-express-4.1.8.tgz#3c0e0bf2543c7efb500eaa081bfde6d92f88096c"
|
||||
integrity sha512-AhZV8/EIreHFmBV5wAs0gzJUNq9JbbSXgJLQubCC0jtIo6prnI9MIRRxnU4MZX9RB9yXxF1V4R7jtLl/Wcj31g==
|
||||
dependencies:
|
||||
"@types/express" "*"
|
||||
"@types/serve-static" "*"
|
||||
|
||||
accepts@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-2.0.0.tgz#bbcf4ba5075467f3f2131eab3cffc73c2f5d7895"
|
||||
|
@ -355,11 +422,21 @@ arg@^4.1.0:
|
|||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
bcryptjs@*, bcryptjs@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-3.0.2.tgz#caadcca1afefe372ed6e20f86db8e8546361c1ca"
|
||||
integrity sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
|
||||
|
@ -426,6 +503,11 @@ call-bound@^1.0.2:
|
|||
call-bind-apply-helpers "^1.0.2"
|
||||
get-intrinsic "^1.3.0"
|
||||
|
||||
call-me-maybe@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa"
|
||||
integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==
|
||||
|
||||
chokidar@^3.5.1, chokidar@^3.5.2:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
|
||||
|
@ -441,6 +523,16 @@ chokidar@^3.5.1, chokidar@^3.5.2:
|
|||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
commander@6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.0.tgz#b990bfb8ac030aedc6d11bc04d1488ffef56db75"
|
||||
integrity sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==
|
||||
|
||||
commander@^10.0.0:
|
||||
version "10.0.1"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
|
||||
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
@ -498,6 +590,13 @@ diff@^4.0.1:
|
|||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||
|
||||
doctrine@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
||||
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
dotenv@^16.5.0:
|
||||
version "16.5.0"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692"
|
||||
|
@ -596,6 +695,11 @@ escape-html@^1.0.3:
|
|||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
etag@^1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
|
@ -709,6 +813,18 @@ glob-parent@~5.1.2:
|
|||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob@7.1.6:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.1.3:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
|
||||
|
@ -825,6 +941,13 @@ is-promise@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3"
|
||||
integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
jsonwebtoken@^9.0.2:
|
||||
version "9.0.2"
|
||||
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3"
|
||||
|
@ -858,6 +981,11 @@ jws@^3.2.2:
|
|||
jwa "^1.4.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
|
||||
|
||||
lodash.includes@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
||||
|
@ -868,6 +996,11 @@ lodash.isboolean@^3.0.3:
|
|||
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
|
||||
integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
|
||||
|
||||
lodash.isinteger@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
|
||||
|
@ -888,6 +1021,11 @@ lodash.isstring@^4.0.1:
|
|||
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
|
||||
integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==
|
||||
|
||||
lodash.mergewith@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
|
||||
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
|
||||
|
||||
lodash.once@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||
|
@ -925,7 +1063,7 @@ mime-types@^3.0.0, mime-types@^3.0.1:
|
|||
dependencies:
|
||||
mime-db "^1.54.0"
|
||||
|
||||
minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
|
@ -1335,6 +1473,39 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
swagger-jsdoc@^6.2.8:
|
||||
version "6.2.8"
|
||||
resolved "https://registry.yarnpkg.com/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz#6d33d9fb07ff4a7c1564379c52c08989ec7d0256"
|
||||
integrity sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==
|
||||
dependencies:
|
||||
commander "6.2.0"
|
||||
doctrine "3.0.0"
|
||||
glob "7.1.6"
|
||||
lodash.mergewith "^4.6.2"
|
||||
swagger-parser "^10.0.3"
|
||||
yaml "2.0.0-1"
|
||||
|
||||
swagger-parser@^10.0.3:
|
||||
version "10.0.3"
|
||||
resolved "https://registry.yarnpkg.com/swagger-parser/-/swagger-parser-10.0.3.tgz#04cb01c18c3ac192b41161c77f81e79309135d03"
|
||||
integrity sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==
|
||||
dependencies:
|
||||
"@apidevtools/swagger-parser" "10.0.3"
|
||||
|
||||
swagger-ui-dist@>=5.0.0:
|
||||
version "5.21.0"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.21.0.tgz#aed230fe6e294c9470217e67697d601e3bb8eb9d"
|
||||
integrity sha512-E0K3AB6HvQd8yQNSMR7eE5bk+323AUxjtCz/4ZNKiahOlPhPJxqn3UPIGs00cyY/dhrTDJ61L7C/a8u6zhGrZg==
|
||||
dependencies:
|
||||
"@scarf/scarf" "=1.4.0"
|
||||
|
||||
swagger-ui-express@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz#fb8c1b781d2793a6bd2f8a205a3f4bd6fa020dd8"
|
||||
integrity sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==
|
||||
dependencies:
|
||||
swagger-ui-dist ">=5.0.0"
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
|
@ -1436,6 +1607,11 @@ v8-compile-cache-lib@^3.0.1:
|
|||
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
|
||||
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
|
||||
|
||||
validator@^13.7.0:
|
||||
version "13.15.0"
|
||||
resolved "https://registry.yarnpkg.com/validator/-/validator-13.15.0.tgz#2dc7ce057e7513a55585109eec29b2c8e8c1aefd"
|
||||
integrity sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==
|
||||
|
||||
vary@^1, vary@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
|
@ -1451,11 +1627,27 @@ xtend@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
||||
yaml@2.0.0-1:
|
||||
version "2.0.0-1"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.0.0-1.tgz#8c3029b3ee2028306d5bcf396980623115ff8d18"
|
||||
integrity sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==
|
||||
|
||||
yn@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
||||
|
||||
z-schema@^5.0.1:
|
||||
version "5.0.6"
|
||||
resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-5.0.6.tgz#46d6a687b15e4a4369e18d6cb1c7b8618fc256c5"
|
||||
integrity sha512-+XR1GhnWklYdfr8YaZv/iu+vY+ux7V5DS5zH1DQf6bO5ufrt/5cgNhVO5qyhsjFXvsqQb/f08DWE9b6uPscyAg==
|
||||
dependencies:
|
||||
lodash.get "^4.4.2"
|
||||
lodash.isequal "^4.5.0"
|
||||
validator "^13.7.0"
|
||||
optionalDependencies:
|
||||
commander "^10.0.0"
|
||||
|
||||
zod@^3.24.4:
|
||||
version "3.24.4"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.4.tgz#e2e2cca5faaa012d76e527d0d36622e0a90c315f"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue