Skip to content

Commit

Permalink
refactor: added missing response handler; added handler per HTTP meth…
Browse files Browse the repository at this point in the history
…od (#920)

Co-authored-by: Philip Niedertscheider <30923007+philprime@users.noreply.github.com>
  • Loading branch information
flohoch and philprime authored Apr 9, 2024
1 parent 83e4403 commit 5c7a226
Show file tree
Hide file tree
Showing 37 changed files with 3,614 additions and 3,126 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"testing.openTesting": "neverOpen"
}
7 changes: 7 additions & 0 deletions models/authResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface AuthResult {
success: boolean;
authToken?: string;
id?: number;
statusCode: number;
errorMessage?: string;
}
13 changes: 7 additions & 6 deletions models/user.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export interface User {
id?: number;
email: string;
firstName: string;
lastName: string;
role?: string;
}
id?: number;
email: string;
firstName?: string;
lastName?: string;
role?: string;
orgId?: number;
}
211 changes: 113 additions & 98 deletions pages/api/admin/v0.1/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import { validate } from "class-validator";
import { StatusCodes } from "http-status-codes";
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "../../../../../lib/services/db";
import { AuthResult } from "../../../../../models/authResult";
import { CreateAppDto } from "../../../../../models/dtos/request/createAppDto";
import { AppDto } from "../../../../../models/dtos/response/appDto";
import { MessageDto } from "../../../../../models/dtos/response/messageDto";
import { authenticate } from "../../../../../util/adminApi/auth";
import { Logger } from "../../../../../util/logger";

const logger = new Logger(__filename);

/**
* @swagger
* tags:
Expand Down Expand Up @@ -115,8 +118,6 @@ export default async function handler(
req: NextApiRequest,
res: NextApiResponse<AppDto | ErrorDto>
) {
const logger = new Logger(__filename);

const authResult = await authenticate(req, "app");

// When authResult was not successful, return error with respective
Expand All @@ -130,107 +131,121 @@ export default async function handler(
// Find app by token
// If found, return app data with message
case "GET":
logger.log(`Looking up app with id(='${authResult.id})'`);

const app = await prisma.app.findUnique({
where: {
id: authResult.id,
},
include: {
messages: true,
},
});

if (app == null) {
logger.error(`No app found with id '${authResult.id}'`);
return res
.status(StatusCodes.NOT_FOUND)
.json(getErrorDto(`No app found with id '${authResult.id}'`));
}

const convertedMessages: MessageDto[] = app.messages.map(
(message): MessageDto => ({
id: message.id,
createdAt: message.createdAt,
updatedAt: message.updatedAt,
blocking: message.blocking,
title: message.title,
body: message.body,
endDate: message.endDate,
startDate: message.startDate,
})
);
const foundAppDto: AppDto = {
id: app.id,
createdAt: app.createdAt,
updatedAt: app.updatedAt,
name: app.name,
publicKey: app.publicKey,
messages: convertedMessages,
};

return res.status(StatusCodes.OK).json(foundAppDto);

return getHandler(req, res, authResult);
// Update app
case "PUT":
const updateAppDto = plainToInstance(CreateAppDto, req.body);
const validationErrors = await validate(updateAppDto);

if (validationErrors.length > 0) {
const errors = validationErrors
.flatMap((error) =>
error.constraints
? Object.values(error.constraints)
: ["An unknown error occurred"]
)
.join(", ");
return res
.status(StatusCodes.BAD_REQUEST)
.json(getErrorDto(`Validation failed: ${errors}`));
}

try {
logger.log(`Updating app with id(='${authResult.id})'`);

const updatedApp = await prisma.app.update({
where: {
id: authResult.id,
},
data: {
name: updateAppDto.name,
},
});

const dto: AppDto = {
id: updatedApp.id,
createdAt: updatedApp.createdAt,
updatedAt: updatedApp.updatedAt,
name: updatedApp.name,
publicKey: updatedApp.publicKey,
};

return res.status(StatusCodes.CREATED).json(dto);
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
logger.error(`No app found with id '${authResult.id}'`);
return res
.status(StatusCodes.NOT_FOUND)
.json(getErrorDto("No app found with id " + authResult.id));
}

logger.error(`Internal server error occurred: ${e}`);
return res
.status(StatusCodes.INTERNAL_SERVER_ERROR)
.json(
getErrorDto(
"An internal server error occurred - please try again later!"
)
);
}

return putHandler(req, res, authResult);
default:
return res
.status(StatusCodes.METHOD_NOT_ALLOWED)
.json(getErrorDto("method not allowed"));
}
}

async function getHandler(
req: NextApiRequest,
res: NextApiResponse,
authResult: AuthResult
) {
logger.log(`Looking up app with id(='${authResult.id})'`);

const app = await prisma.app.findUnique({
where: {
id: authResult.id,
},
include: {
messages: true,
},
});

if (app == null) {
logger.error(`No app found with id '${authResult.id}'`);
return res
.status(StatusCodes.NOT_FOUND)
.json(getErrorDto(`No app found with id '${authResult.id}'`));
}

const convertedMessages: MessageDto[] = app.messages.map(
(message): MessageDto => ({
id: message.id,
createdAt: message.createdAt,
updatedAt: message.updatedAt,
blocking: message.blocking,
title: message.title,
body: message.body,
endDate: message.endDate,
startDate: message.startDate,
})
);
const foundAppDto: AppDto = {
id: app.id,
createdAt: app.createdAt,
updatedAt: app.updatedAt,
name: app.name,
publicKey: app.publicKey,
messages: convertedMessages,
};

return res.status(StatusCodes.OK).json(foundAppDto);
}

async function putHandler(
req: NextApiRequest,
res: NextApiResponse,
authResult: AuthResult
) {
const updateAppDto = plainToInstance(CreateAppDto, req.body);
const validationErrors = await validate(updateAppDto);

if (validationErrors.length > 0) {
const errors = validationErrors
.flatMap((error) =>
error.constraints
? Object.values(error.constraints)
: ["An unknown error occurred"]
)
.join(", ");
return res
.status(StatusCodes.BAD_REQUEST)
.json(getErrorDto(`Validation failed: ${errors}`));
}

try {
logger.log(`Updating app with id(='${authResult.id})'`);

const updatedApp = await prisma.app.update({
where: {
id: authResult.id,
},
data: {
name: updateAppDto.name,
},
});

const dto: AppDto = {
id: updatedApp.id,
createdAt: updatedApp.createdAt,
updatedAt: updatedApp.updatedAt,
name: updatedApp.name,
publicKey: updatedApp.publicKey,
};

return res.status(StatusCodes.CREATED).json(dto);
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
logger.error(`No app found with id '${authResult.id}'`);
return res
.status(StatusCodes.NOT_FOUND)
.json(getErrorDto("No app found with id " + authResult.id));
}

logger.error(`Internal server error occurred: ${e}`);
return res
.status(StatusCodes.INTERNAL_SERVER_ERROR)
.json(
getErrorDto(
"An internal server error occurred - please try again later!"
)
);
}
}
Loading

0 comments on commit 5c7a226

Please sign in to comment.