Merge pull request #163 from thevahidal/feature_swagger_documentation
Feature swagger documentation
This commit is contained in:
@@ -162,6 +162,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 {
|
||||
@@ -182,6 +195,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
|
||||
@@ -193,6 +215,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
|
||||
@@ -220,6 +251,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
|
||||
@@ -229,6 +268,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 });
|
||||
@@ -236,6 +284,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;
|
||||
|
||||
@@ -257,6 +318,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;
|
||||
@@ -313,6 +382,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({
|
||||
@@ -323,6 +401,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(
|
||||
@@ -341,6 +425,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;
|
||||
@@ -392,12 +485,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(403).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;
|
||||
|
||||
@@ -423,6 +548,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
|
||||
@@ -434,6 +567,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
|
||||
@@ -454,6 +596,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 });
|
||||
}
|
||||
|
||||
@@ -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' },
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found"
|
||||
@@ -540,17 +548,25 @@
|
||||
},
|
||||
"/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/RefreshAccessTokenSuccessResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
"description": "Invalid refresh token error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/InvalidRefreshTokenErrorResponse"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden"
|
||||
@@ -560,30 +576,37 @@
|
||||
},
|
||||
"/api/auth/change-password": {
|
||||
"put": {
|
||||
"description": "",
|
||||
"tags": ["Auth"],
|
||||
"summary": "Change Password",
|
||||
"description": "Endpoint to change a password",
|
||||
"parameters": [
|
||||
{
|
||||
"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"
|
||||
"description": "User not found error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/InvalidPasswordErrorResponse"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden"
|
||||
@@ -868,6 +891,181 @@
|
||||
},
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"InvalidPasswordErrorResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Invalid password"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user