Add swagger setup for the new routes

This commit is contained in:
AbegaM
2024-03-08 12:11:17 +03:00
parent 45534e7317
commit fc2f01157f
3 changed files with 425 additions and 21 deletions

View File

@@ -153,6 +153,19 @@ const updateSuperuser = async (fields) => {
};
const registerUser = async (req, res) => {
/*
#swagger.tags = ['Auth']
#swagger.summary = 'Register User'
#swagger.description = 'Endpoint to signup'
#swagger.parameters['username'] = {
in: 'body',
required: true,
type: 'object',
schema: { $ref: '#/definitions/UserRegistrationRequestBody' }
}
*/
const { username, password } = req.body.fields;
try {
@@ -173,6 +186,15 @@ const registerUser = async (req, res) => {
if (user.length > 0) {
return res.status(409).send({ message: 'This username is taken' });
/*
#swagger.responses[409] = {
description: 'Username taken error',
schema: {
$ref: '#/definitions/UsernameTakenErrorResponse'
}
}
*/
}
// check if the password is weak
@@ -180,6 +202,15 @@ const registerUser = async (req, res) => {
return res.status(400).send({
message: 'This password is weak, please use another password',
});
/*
#swagger.responses[400] = {
description: 'Weak password error',
schema: {
$ref: '#/definitions/WeakPasswordErrorResponse'
}
}
*/
}
// hash the password
@@ -207,6 +238,14 @@ const registerUser = async (req, res) => {
return res.status(500).send({
message: 'Please restart soul so a default role can be created',
});
/*
#swagger.responses[500] = {
description: 'Server error',
schema: {
$ref: '#/definitions/DefaultRoleNotCreatedErrorResponse'
}
}
*/
}
// create a role for the user
@@ -216,6 +255,15 @@ const registerUser = async (req, res) => {
});
res.status(201).send({ message: 'Row Inserted' });
/*
#swagger.responses[201] = {
description: 'Row inserted',
schema: {
$ref: '#/definitions/InsertRowSuccessResponse'
}
}
*/
} catch (error) {
console.log(error);
res.status(500).send({ message: error.message });
@@ -223,6 +271,19 @@ const registerUser = async (req, res) => {
};
const obtainAccessToken = async (req, res) => {
/*
#swagger.tags = ['Auth']
#swagger.summary = 'Obtain Access Token'
#swagger.description = 'Endpoint to generate access and refresh tokens'
#swagger.parameters['body'] = {
in: 'body',
required: true,
type: 'object',
schema: { $ref: '#/definitions/ObtainAccessTokenRequestBody' }
}
*/
// extract payload
const { username, password } = req.body.fields;
@@ -244,6 +305,14 @@ const obtainAccessToken = async (req, res) => {
if (!isMatch) {
return res.status(401).send({ message: 'Invalid username or password' });
/*
#swagger.responses[401] = {
description: 'Invalid username or password error',
schema: {
$ref: '#/definitions/InvalidCredentialErrorResponse'
}
}
*/
}
let userRoles, permissions, roleIds;
@@ -294,6 +363,15 @@ const obtainAccessToken = async (req, res) => {
res.cookie('refreshToken', refreshToken, cookieOptions);
res.status(201).send({ message: 'Success', data: { userId: user.id } });
/*
#swagger.responses[201] = {
description: 'Access token and Refresh token generated',
schema: {
$ref: '#/definitions/ObtainAccessTokenSuccessResponse'
}
}
*/
} catch (error) {
console.log(error);
return res.status(500).json({
@@ -304,6 +382,12 @@ const obtainAccessToken = async (req, res) => {
};
const refreshAccessToken = async (req, res) => {
/*
#swagger.tags = ['Auth']
#swagger.summary = 'Refresh Access Token'
#swagger.description = 'Endpoint to refresh access and refresh tokens'
*/
try {
// extract the payload from the token and verify it
const payload = await decodeToken(
@@ -322,6 +406,15 @@ const refreshAccessToken = async (req, res) => {
return res
.status(401)
.send({ message: `User with userId = ${payload.userId} not found` });
/*
#swagger.responses[401] = {
description: 'User not found error',
schema: {
$ref: '#/definitions/UserNotFoundErrorResponse'
}
}
*/
}
let userRoles, permissions, roleIds;
@@ -373,12 +466,44 @@ const refreshAccessToken = async (req, res) => {
res.cookie('refreshToken', refreshToken, cookieOptions);
res.status(200).send({ message: 'Success', data: { userId: user.id } });
/*
#swagger.responses[200] = {
description: 'Access token refreshed',
schema: {
$ref: '#/definitions/RefreshAccessTokenSuccessResponse'
}
}
*/
} catch (error) {
res.status(401).send({ message: 'Invalid refresh token' });
/*
#swagger.responses[401] = {
description: 'Invalid refresh token error',
schema: {
$ref: '#/definitions/InvalidRefreshTokenErrorResponse'
}
}
*/
}
};
const changePassword = async (req, res) => {
/*
#swagger.tags = ['Auth']
#swagger.summary = 'Change Password'
#swagger.description = 'Endpoint to change a password'
#swagger.parameters['body'] = {
in: 'body',
required: true,
type: 'object',
schema: {
$ref: '#/definitions/ChangePasswordRequestBody'
}
}
*/
const userInfo = req.user;
const { currentPassword, newPassword } = req.body.fields;
@@ -404,6 +529,14 @@ const changePassword = async (req, res) => {
if (!isMatch) {
return res.status(401).send({ message: 'Invalid current password' });
/*
#swagger.responses[401] = {
description: 'User not found error',
schema: {
$ref: '#/definitions/InvalidPasswordErrorResponse'
}
}
*/
}
// check if the new password is strong
@@ -411,6 +544,15 @@ const changePassword = async (req, res) => {
return res.status(400).send({
message: 'This password is weak, please use another password',
});
/*
#swagger.responses[400] = {
description: 'Weak password error',
schema: {
$ref: '#/definitions/WeakPasswordErrorResponse'
}
}
*/
}
// hash the password
@@ -431,6 +573,15 @@ const changePassword = async (req, res) => {
message: 'Password updated successfully',
data: { id: user.id, username: user.username },
});
/*
#swagger.responses[200] = {
description: 'Weak password error',
schema: {
$ref: '#/definitions/ChangePasswordSuccessResponse'
}
}
*/
} catch (error) {
res.status(500).send({ message: error.message });
}

View File

@@ -31,6 +31,10 @@ const doc = {
name: 'Rows',
description: 'Rows endpoints',
},
{
name: 'Auth',
description: 'Auth endpoints',
},
],
securityDefinitions: {},
definitions: {
@@ -122,6 +126,69 @@ const doc = {
TransactionRequestBody: {
$ref: '#/definitions/Transaction',
},
ObtainAccessTokenRequestBody: {
fields: {
username: '@john',
password: 'Ak22#cPM33@v*#',
},
},
ObtainAccessTokenSuccessResponse: {
message: 'Success',
data: {
userId: 1,
},
},
InvalidCredentialErrorResponse: {
message: 'Invalid username or password',
},
UserRegisterationRequestBody: {
fields: {
username: '@john',
password: 'Ak22#cPM33@v*#',
},
},
WeakPasswordErrorResponse: {
message: 'This password is weak, please use another password',
},
UsernameTakenErrorResponse: {
message: 'This username is taken',
},
DefaultRoleNotCreatedErrorResponse: {
message: 'Please restart soul so a default role can be created',
},
UserNotFoundErrorResponse: {
message: 'User not found',
},
InvalidRefreshTokenErrorResponse: {
message: 'Invalid refresh token',
},
ChangePasswordRequestBody: {
fields: {
currentPassword: 'Ak22#cPM33@v*#',
newPassword: 'hKB33o@3245CD$',
},
},
ChangePasswordSuccessResponse: {
message: 'Password updated successfully',
data: { id: 1, username: '@john' },
},
RefreshAccessTokenSuccessResponse: {
message: 'Success',
data: { userId: 1 },
},
InvalidPasswordErrorResponse: { message: 'Invalid password' },
},
};

View File

@@ -19,6 +19,10 @@
{
"name": "Rows",
"description": "Rows endpoints"
},
{
"name": "Auth",
"description": "Auth endpoints"
}
],
"schemes": ["http", "https"],
@@ -504,30 +508,34 @@
},
"/api/auth/token/obtain": {
"post": {
"description": "",
"tags": ["Auth"],
"summary": "Obtain Access Token",
"description": "Endpoint to generate access and refresh tokens",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"fields": {
"example": "any"
}
}
"$ref": "#/definitions/ObtainAccessTokenRequestBody"
}
}
],
"responses": {
"201": {
"description": "Created"
"description": "Access token and Refresh token generated",
"schema": {
"$ref": "#/definitions/ObtainAccessTokenSuccessResponse"
}
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
"description": "Invalid username or password error",
"schema": {
"$ref": "#/definitions/InvalidCredentialErrorResponse"
}
},
"500": {
"description": "Internal Server Error"
@@ -537,24 +545,34 @@
},
"/api/auth/token/refresh": {
"get": {
"description": "",
"tags": ["Auth"],
"summary": "Refresh Access Token",
"description": "Endpoint to refresh access and refresh tokens",
"parameters": [],
"responses": {
"200": {
"description": "OK"
"description": "Access token refreshed ",
"schema": {
"$ref": "#/definitions/UserNotFoundErrorResponse"
}
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
"description": "Invalid refresh token error",
"schema": {
"$ref": "#/definitions/InvalidRefreshTokenErrorResponse"
}
}
}
}
},
"/api/auth/{userId}/change-password": {
"put": {
"description": "",
"tags": ["Auth"],
"summary": "Change Password",
"description": "Endpoint to change a password",
"parameters": [
{
"name": "userId",
@@ -565,22 +583,24 @@
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"fields": {
"example": "any"
}
}
"$ref": "#/definitions/ChangePasswordRequestBody"
}
}
],
"responses": {
"200": {
"description": "OK"
"description": "Weak password error",
"schema": {
"$ref": "#/definitions/ChangePasswordSuccessResponse"
}
},
"400": {
"description": "Bad Request"
"description": "Weak password error",
"schema": {
"$ref": "#/definitions/WeakPasswordErrorResponse"
}
},
"401": {
"description": "Unauthorized"
@@ -868,6 +888,172 @@
},
"TransactionRequestBody": {
"$ref": "#/definitions/Transaction"
},
"ObtainAccessTokenRequestBody": {
"type": "object",
"properties": {
"fields": {
"type": "object",
"properties": {
"username": {
"type": "string",
"example": "@john"
},
"password": {
"type": "string",
"example": "Ak22#cPM33@v*#"
}
}
}
}
},
"ObtainAccessTokenSuccessResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Success"
},
"data": {
"type": "object",
"properties": {
"userId": {
"type": "number",
"example": 1
}
}
}
}
},
"InvalidCredentialErrorResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Invalid username or password"
}
}
},
"UserRegisterationRequestBody": {
"type": "object",
"properties": {
"fields": {
"type": "object",
"properties": {
"username": {
"type": "string",
"example": "@john"
},
"password": {
"type": "string",
"example": "Ak22#cPM33@v*#"
}
}
}
}
},
"WeakPasswordErrorResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "This password is weak, please use another password"
}
}
},
"UsernameTakenErrorResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "This username is taken"
}
}
},
"DefaultRoleNotCreatedErrorResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Please restart soul so a default role can be created"
}
}
},
"UserNotFoundErrorResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "User not found"
}
}
},
"InvalidRefreshTokenErrorResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Invalid refresh token"
}
}
},
"ChangePasswordRequestBody": {
"type": "object",
"properties": {
"fields": {
"type": "object",
"properties": {
"currentPassword": {
"type": "string",
"example": "Ak22#cPM33@v*#"
},
"newPassword": {
"type": "string",
"example": "hKB33o@3245CD$"
}
}
}
}
},
"ChangePasswordSuccessResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Password updated successfully"
},
"data": {
"type": "object",
"properties": {
"id": {
"type": "number",
"example": 1
},
"username": {
"type": "string",
"example": "@john"
}
}
}
}
},
"RefreshAccessTokenSuccessResponse": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Success"
},
"data": {
"type": "object",
"properties": {
"userId": {
"type": "number",
"example": 1
}
}
}
}
}
}
}