Swagger API documentation
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Account
|
||||
* description: API to manage accounts
|
||||
*/
|
||||
import { Router, Request, Response } from "express";
|
||||
import { Account } from "../models/user/account.model";
|
||||
import { validateString } from "../scripts/validateHelper";
|
||||
@@ -11,20 +17,38 @@ import { encryptString } from "../scripts/encryptScripts";
|
||||
|
||||
export const account = Router()
|
||||
|
||||
account.get("/", verifyToken, (req: Request, res: Response) => {
|
||||
Account.findAll({
|
||||
include: [ AccountRole ]
|
||||
})
|
||||
.then(accounts => {
|
||||
res.status(200).json(accounts)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
// Login user
|
||||
account.get("/account/login", async (req: Request, res: Response) => {
|
||||
/**
|
||||
* @swagger
|
||||
* /accounts/login:
|
||||
* get:
|
||||
* summary: Start login process
|
||||
* tags: [Account]
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: username
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: Username
|
||||
* - in: query
|
||||
* name: password
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: User password
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Login successful
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/loginResponse'
|
||||
* 401:
|
||||
* description: Wrong credentials
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
account.get("/login", async (req: Request, res: Response) => {
|
||||
const encryptedPassword = encryptString(String(req.query.password))
|
||||
|
||||
try {
|
||||
@@ -47,10 +71,7 @@ account.get("/account/login", async (req: Request, res: Response) => {
|
||||
})
|
||||
} else {
|
||||
// Status: 401 Unauthorized
|
||||
res.status(401).json({
|
||||
code: 401,
|
||||
message: "Unauthorized"
|
||||
})
|
||||
res.status(401).send()
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).send()
|
||||
@@ -58,12 +79,35 @@ account.get("/account/login", async (req: Request, res: Response) => {
|
||||
})
|
||||
|
||||
|
||||
account.get("/account/data", verifyToken, async(req: Request, res: Response) => {
|
||||
/**
|
||||
* @swagger
|
||||
* /accounts/account:
|
||||
* get:
|
||||
* summary: Get all data about an user account
|
||||
* tags: [Account]
|
||||
* security:
|
||||
* - JWT: []
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/useraccount'
|
||||
* 401:
|
||||
* description: Unauthorized
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
account.get("/account", verifyToken, async(req: Request, res: Response) => {
|
||||
Account.findOne({
|
||||
where: {
|
||||
id: req["id"]
|
||||
},
|
||||
include: [ Address, AccountRole, Payment ]
|
||||
include: [ Address, AccountRole, Payment ],
|
||||
attributes: {
|
||||
exclude: [ "accountRoleId" ]
|
||||
}
|
||||
})
|
||||
.then(account => {
|
||||
res.status(200).json(account)
|
||||
@@ -74,7 +118,31 @@ account.get("/account/data", verifyToken, async(req: Request, res: Response) =>
|
||||
})
|
||||
|
||||
|
||||
// Creating a new user
|
||||
/**
|
||||
* @swagger
|
||||
* /accounts/account:
|
||||
* post:
|
||||
* summary: Create a new user account
|
||||
* tags: [Account]
|
||||
* requestBody:
|
||||
* description: Minimal user data body
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/minimalAccount'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/useraccount'
|
||||
* 400:
|
||||
* description: Username/password too short
|
||||
* 409:
|
||||
* description: Username already in use
|
||||
*/
|
||||
account.post("/account", async (req: Request, res: Response) => {
|
||||
// Check if username is valid
|
||||
if (!validateString(req.body.username, 4))
|
||||
@@ -121,6 +189,28 @@ account.post("/account", async (req: Request, res: Response) => {
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /accounts/account:
|
||||
* patch:
|
||||
* summary: Update an user accounts data
|
||||
* tags: [Account]
|
||||
* security:
|
||||
* - JWT: []
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/useraccount'
|
||||
* 401:
|
||||
* description: Unauthorized
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
account.patch("/account", verifyToken, (req: Request, res: Response) => {
|
||||
Account.update(req.body,
|
||||
{
|
||||
@@ -164,7 +254,31 @@ account.patch("/account", verifyToken, (req: Request, res: Response) => {
|
||||
})
|
||||
})
|
||||
|
||||
account.delete("/account/:id", (req: Request, res: Response) => {
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /accounts/account/{id}:
|
||||
* delete:
|
||||
* summary: Delete an user account
|
||||
* tags: [Account]
|
||||
* security:
|
||||
* - JWT: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: number
|
||||
* required: true
|
||||
* description: ID of user account
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
* 401:
|
||||
* description: Unauthorized
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
account.delete("/account/:id", verifyToken, (req: Request, res: Response) => {
|
||||
Account.destroy({
|
||||
where: {
|
||||
id: req.params.id
|
||||
@@ -176,4 +290,37 @@ account.delete("/account/:id", (req: Request, res: Response) => {
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /accounts/:
|
||||
* get:
|
||||
* summary: Request all user accounts
|
||||
* tags: [Account]
|
||||
* security:
|
||||
* - JWT: []
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/useraccount'
|
||||
* 401:
|
||||
* description: Unauthorized
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
account.get("/", verifyToken, (req: Request, res: Response) => {
|
||||
Account.findAll({
|
||||
include: [ AccountRole ]
|
||||
})
|
||||
.then(accounts => {
|
||||
res.status(200).json(accounts)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
@@ -1,18 +1,38 @@
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Api
|
||||
* description: Main API access point for misc events
|
||||
*/
|
||||
import { Request, Response, NextFunction, Router } from 'express'
|
||||
import { deleteAllTables, deleteExerciseProgressTables, prepopulateDatabase, prepopulateExerciseDatabase } from '../scripts/databaseHelper'
|
||||
|
||||
export const api = Router()
|
||||
|
||||
/**
|
||||
* Status check endpoint
|
||||
* @swagger
|
||||
* /api:
|
||||
* get:
|
||||
* summary: Status check endpoint
|
||||
* tags: [Api]
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Server is up and running
|
||||
*/
|
||||
api.get("/", (req: Request, res: Response, next: NextFunction) => {
|
||||
res.status(200).send()
|
||||
})
|
||||
|
||||
/**
|
||||
* Reset the whole database to factory state
|
||||
* Doesn't effect ExerciseTable and ExerciseGroupTable
|
||||
* @swagger
|
||||
* /api/resetdatabase:
|
||||
* get:
|
||||
* summary: Reset the database to factory state
|
||||
* description: Doesn't effect ExerciseTable and ExerciseGroupTable
|
||||
* tags: [Api]
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Reset successful
|
||||
*/
|
||||
api.get("/resetdatabase", async (req: Request, res: Response, next: NextFunction) => {
|
||||
// Step 1: Delete all data tables
|
||||
@@ -26,7 +46,15 @@ api.get("/resetdatabase", async (req: Request, res: Response, next: NextFunction
|
||||
})
|
||||
|
||||
/**
|
||||
* Reset ExerciseTable and ExerciseGroupTable to factory state
|
||||
* @swagger
|
||||
* /api/resetExerciseProgress:
|
||||
* get:
|
||||
* summary: Reset exercises to factory state
|
||||
* description: Reset ExerciseTable and ExerciseGroupTable to factory state
|
||||
* tags: [Api]
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Reset successful
|
||||
*/
|
||||
api.get("/resetExerciseProgress", async (req: Request, res: Response, next: NextFunction) => {
|
||||
deleteExerciseProgressTables()
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Bands
|
||||
* description: API to manage the bands
|
||||
*/
|
||||
import { Member } from "../models/acts/member.model";
|
||||
import { Band } from "../models/acts/band.model";
|
||||
import { Request, Response, Router } from "express";
|
||||
@@ -13,7 +19,33 @@ import { sequelize } from "../database";
|
||||
export const band = Router()
|
||||
|
||||
/**
|
||||
* Get all bands
|
||||
* @swagger
|
||||
* /bands:
|
||||
* get:
|
||||
* summary: Download all available bands
|
||||
* tags: [Bands]
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: sort
|
||||
* schema:
|
||||
* type: string
|
||||
* required: false
|
||||
* description: Sort bands by number of concerts ascending (asc) or descending (desc)
|
||||
* - in: query
|
||||
* name: count
|
||||
* schema:
|
||||
* type: number
|
||||
* required: false
|
||||
* description: Limit number of results
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of band objects
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/band'
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
band.get("/", (req: Request, res: Response) => {
|
||||
let sort = req.query.sort
|
||||
@@ -71,7 +103,7 @@ band.get("/", (req: Request, res: Response) => {
|
||||
/**
|
||||
* Get all information about one band
|
||||
*/
|
||||
band.get("/band/:name", (req: Request, res: Response) => {
|
||||
band.get("/:name", (req: Request, res: Response) => {
|
||||
Band.findOne({
|
||||
where: {
|
||||
name: { [Op.like]: req.params.name }
|
||||
|
||||
@@ -1,8 +1,30 @@
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Cities
|
||||
* description: API to manage the cities
|
||||
*/
|
||||
import { City } from "../models/locations/city.model";
|
||||
import { Request, Response, Router } from "express";
|
||||
|
||||
export const city = Router()
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /cities:
|
||||
* get:
|
||||
* summary: Download all cities
|
||||
* tags: [Cities]
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of all cities as objects
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/city'
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
city.get("/", (req: Request, res: Response) => {
|
||||
City.findAll()
|
||||
.then(cities => {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Exercises
|
||||
* description: API to manage the exercise progress
|
||||
*/
|
||||
import { Op } from "sequelize";
|
||||
import { Exercise } from "../models/exercises/exercise.model";
|
||||
import { ExerciseGroup } from "../models/exercises/exerciseGroup.model";
|
||||
@@ -6,11 +12,28 @@ import { Request, Response, Router } from "express";
|
||||
export const exercises = Router()
|
||||
|
||||
/**
|
||||
* Get all Exercises grouped in ExerciseGroups
|
||||
* @swagger
|
||||
* /exercises:
|
||||
* get:
|
||||
* summary: Download all exercises
|
||||
* tags: [Exercises]
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Array of all exercises
|
||||
* type: array
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/exercise'
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
exercises.get("/", (req: Request, res: Response) => {
|
||||
Exercise.findAll({
|
||||
include: [ ExerciseGroup ]
|
||||
include: [ ExerciseGroup ],
|
||||
attributes: {
|
||||
exclude: [ "exerciseGroupId" ]
|
||||
}
|
||||
})
|
||||
.then(result => {
|
||||
result.sort((a, b) => {
|
||||
@@ -25,11 +48,39 @@ exercises.get("/", (req: Request, res: Response) => {
|
||||
})
|
||||
|
||||
/**
|
||||
* Update state of an Exercise
|
||||
*
|
||||
* @param groupNr Number of exercise group (not ID)
|
||||
* @param exerciseNr Number of exercise (not ID)
|
||||
* @param state New state boolean
|
||||
* @swagger
|
||||
* /exercises/{groupNr}/{exerciseNr}/{state}:
|
||||
* post:
|
||||
* summary: Update an exercise solved state
|
||||
* tags: [Exercises]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: groupNr
|
||||
* schema:
|
||||
* type: number
|
||||
* required: true
|
||||
* description: Number of exercise group (not ID)
|
||||
* - in: path
|
||||
* name: exerciseNr
|
||||
* schema:
|
||||
* type: number
|
||||
* required: true
|
||||
* description: Number of exercise (not ID)
|
||||
* - in: path
|
||||
* name: state
|
||||
* schema:
|
||||
* type: number
|
||||
* required: true
|
||||
* description: 1 = Solved, 0 = Unsolved
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Edited exercise
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/exercise'
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
exercises.post("/:groupNr/:exerciseNr/:state", (req: Request, res: Response) => {
|
||||
Exercise.findOne({
|
||||
@@ -43,7 +94,10 @@ exercises.post("/:groupNr/:exerciseNr/:state", (req: Request, res: Response) =>
|
||||
}
|
||||
]
|
||||
},
|
||||
include: [ ExerciseGroup ]
|
||||
include: [ ExerciseGroup ],
|
||||
attributes: {
|
||||
exclude: [ "exerciseGroupId" ]
|
||||
}
|
||||
})
|
||||
.then(async exercise => {
|
||||
let changed = false
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Files
|
||||
* description: API for handling static files
|
||||
*/
|
||||
import { Request, Response, NextFunction, Router } from 'express'
|
||||
import fs, { createReadStream } from "fs"
|
||||
import fs from "fs"
|
||||
import multer from "multer"
|
||||
const upload = multer({ dest: './backend/images/' })
|
||||
import licenses from "../data/licenses.json"
|
||||
@@ -8,7 +14,18 @@ import path from 'path'
|
||||
export const files = Router()
|
||||
|
||||
/**
|
||||
* Get all folders
|
||||
* @swagger
|
||||
* /files/folders:
|
||||
* get:
|
||||
* summary: Get all static folders
|
||||
* tags: [Files]
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Login successful
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/folder'
|
||||
*/
|
||||
files.get("/folders", async (req: Request, res: Response) => {
|
||||
let dirNames = fs.readdirSync(path.resolve(__dirname, "../images"))
|
||||
@@ -26,9 +43,25 @@ files.get("/folders", async (req: Request, res: Response) => {
|
||||
|
||||
|
||||
/**
|
||||
* Get all uploaded file names by folder name
|
||||
*
|
||||
* @param folder Name of folder on server
|
||||
* @swagger
|
||||
* /files/{folder}:
|
||||
* get:
|
||||
* summary: Get all files in one folder
|
||||
* tags: [Files]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: folder
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: Name of folder
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Login successful
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/file'
|
||||
*/
|
||||
files.get("/:folder", async (req: Request, res: Response) => {
|
||||
let result = []
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Orders
|
||||
* description: API to manage orders
|
||||
*/
|
||||
import { Router, Request, Response } from "express";
|
||||
import { Order } from "../models/ordering/order.model";
|
||||
import { Concert } from "../models/acts/concert.model";
|
||||
@@ -15,8 +21,34 @@ import { Account } from "../models/user/account.model";
|
||||
|
||||
export const order = Router()
|
||||
|
||||
// Get all orders
|
||||
/**
|
||||
* @swagger
|
||||
* /orders:
|
||||
* get:
|
||||
* summary: Get orders of an account or all available
|
||||
* tags: [Orders]
|
||||
* security:
|
||||
* - JWT: []
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: id
|
||||
* schema:
|
||||
* type: string
|
||||
* required: false
|
||||
* description: User account id to filter the orders
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/order'
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
order.get("/", verifyToken, (req: Request, res: Response) => {
|
||||
const accountId = req.query.id
|
||||
|
||||
Order.findAll({
|
||||
include: [
|
||||
{
|
||||
@@ -47,69 +79,58 @@ order.get("/", verifyToken, (req: Request, res: Response) => {
|
||||
},
|
||||
Address,
|
||||
Payment,
|
||||
Account
|
||||
]
|
||||
Account,
|
||||
],
|
||||
attributes: {
|
||||
exclude: [ "accountId", "addressId", "paymentId" ]
|
||||
}
|
||||
})
|
||||
.then(orders => {
|
||||
res.status(200).json(orders)
|
||||
if (accountId != undefined) {
|
||||
let filteredOrders = orders.filter(order => {
|
||||
return order.id == accountId
|
||||
})
|
||||
|
||||
res.status(200).json(filteredOrders)
|
||||
} else {
|
||||
res.status(200).json(orders)
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /orders:
|
||||
* post:
|
||||
* summary: Place a new order
|
||||
* tags: [Orders]
|
||||
* security:
|
||||
* - JWT: []
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: id
|
||||
* schema:
|
||||
* type: string
|
||||
* required: false
|
||||
* description: User account id to filter the orders
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/order'
|
||||
* 500:
|
||||
* description: Internal server error
|
||||
*/
|
||||
order.post("/", verifyToken, (req: Request, res: Response) => {
|
||||
req.body["accountId"] = req["id"]
|
||||
|
||||
// Get all orders of one account by it's user id
|
||||
order.get("/:id", (req: Request, res: Response) => {
|
||||
Order.findAll({
|
||||
where: { accountId: req.params.id },
|
||||
include: [
|
||||
{
|
||||
model: Ticket,
|
||||
include: [
|
||||
{
|
||||
model: Concert,
|
||||
include: [
|
||||
{
|
||||
model: Band
|
||||
},
|
||||
{
|
||||
model: Location,
|
||||
include: [ City ]
|
||||
}
|
||||
],
|
||||
attributes: {
|
||||
exclude: [
|
||||
"categoryId",
|
||||
"brandId"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
model: Seat,
|
||||
include: [
|
||||
{
|
||||
model: SeatRow,
|
||||
include: [ SeatGroup ]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
Payment,
|
||||
Address
|
||||
]
|
||||
})
|
||||
.then(orders => {
|
||||
res.status(200).json(orders)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
console.log(req.body)
|
||||
|
||||
// Place a new order
|
||||
order.post("/", (req: Request, res: Response) => {
|
||||
Order.create(req.body)
|
||||
.then(async order => {
|
||||
for (let ticket of req.body.tickets) {
|
||||
|
||||
Reference in New Issue
Block a user