Skip to content

Commit

Permalink
Merge branch 'master' into snyk-upgrade-66f93bc6087d52ba05b7faaa0a746c87
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeknovy authored May 17, 2024
2 parents 5654406 + 62321c6 commit d751df3
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 61 deletions.
34 changes: 16 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"moment": "^2.29.4",
"multer": "^1.4.5-lts.1",
"node-pg-migrate": "^6.2.2",
"pg": "^8.11.3",
"pg": "^8.11.5",
"pg-promise": "^10.15.4",
"uuid": "^9.0.1",
"winston": "^3.13.0",
Expand Down
73 changes: 43 additions & 30 deletions src/server/controllers/auth/init-user-controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,50 @@ import { AllowedRoles } from "../../middleware/authorization-middleware"

jest.mock("../../../db/db")
const mockResponse = () => {
const res: Partial<Response> = {}
res.send = jest.fn().mockReturnValue(res)
res.status = jest.fn().mockReturnValue(res)
return res
const res: Partial<Response> = {}
res.send = jest.fn().mockReturnValue(res)
res.status = jest.fn().mockReturnValue(res)
return res
}

describe("initUserController", () => {
it("should call createNewUserController if no user exists", async function () {
const querySpy = jest.spyOn(require("../users/create-new-user-controller"), "createNewUserController");
(db.manyOrNone as any).mockResolvedValue([])
const nextFunction: NextFunction = jest.fn()
const response = mockResponse()
const request = { body: { username: "test", password: "123" } }
await initUserController(
request as unknown as IGetUserAuthInfoRequest,
response as unknown as Response, nextFunction)
expect(querySpy).toHaveBeenCalledTimes(1)
expect(request.body).toEqual({ username: "test", password: "123", role: AllowedRoles.Admin })
})
it("should return an error if user already exists", async function () {
const querySpy = jest.spyOn(require("boom"), "forbidden");

(db.manyOrNone as any).mockResolvedValue(["test"])
const nextFunction: NextFunction = jest.fn()
const response = mockResponse()
const request = {}
await initUserController(
request as unknown as IGetUserAuthInfoRequest,
response as unknown as Response, nextFunction)
expect(nextFunction).toHaveBeenCalledTimes(1)
expect(querySpy).toHaveBeenCalledTimes(1)
expect(querySpy).toHaveBeenCalledWith("User was already initialized")
})
it("should call createNewUserController if no user exists", async function () {
const querySpy = jest.spyOn(require("../users/create-new-user-controller"), "createNewUserController");
(db.oneOrNone as any).mockResolvedValueOnce({}); // migration has finished
(db.manyOrNone as any).mockResolvedValue([])
const nextFunction: NextFunction = jest.fn()
const response = mockResponse()
const request = { body: { username: "test", password: "123" } }
await initUserController(
request as unknown as IGetUserAuthInfoRequest,
response as unknown as Response, nextFunction)
expect(querySpy).toHaveBeenCalledTimes(1)
expect(request.body).toEqual({ username: "test", password: "123", role: AllowedRoles.Admin })
})
it("should return an error if user already exists", async function () {
const querySpy = jest.spyOn(require("boom"), "forbidden");
(db.oneOrNone as any).mockResolvedValueOnce({}); // migration has finished
(db.manyOrNone as any).mockResolvedValue(["test"])
const nextFunction: NextFunction = jest.fn()
const response = mockResponse()
const request = {}
await initUserController(
request as unknown as IGetUserAuthInfoRequest,
response as unknown as Response, nextFunction)
expect(nextFunction).toHaveBeenCalledTimes(1)
expect(querySpy).toHaveBeenCalledTimes(1)
expect(querySpy).toHaveBeenCalledWith("User was already initialized")
})
it("should throw exception when migrations have not finished", async () => {
const spy = jest.spyOn(require("boom"), "preconditionRequired")
const nextFunction: NextFunction = jest.fn()
const response = mockResponse()
const request = {}
await initUserController(
request as unknown as IGetUserAuthInfoRequest,
response as unknown as Response, nextFunction)
expect(nextFunction).toHaveBeenCalledTimes(1)
expect(spy).toHaveBeenCalledTimes(1)
expect(spy).toHaveBeenCalledWith("Migrations were not finished, please try it again later.")
})
})
31 changes: 19 additions & 12 deletions src/server/controllers/auth/init-user-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,28 @@ import boom = require("boom")
import { Request, Response, NextFunction } from "express"
import { db } from "../../../db/db"
import { AllowedRoles } from "../../middleware/authorization-middleware"
import { getUsers } from "../../queries/auth"
import { getUsers, getRoleMigration } from "../../queries/auth"
import { createNewUserController } from "../users/create-new-user-controller"
import { MigrationNotFinishedException } from "../../errors/migration-not-finished-exception"

export const initUserController = async (req: Request, res: Response, next: NextFunction) => {
try {
const users = await db.manyOrNone(getUsers())
if (users && users.length > 0) {
return next(boom.forbidden("User was already initialized"))
}
req.body.role = AllowedRoles.Admin
await createNewUserController(req, res, next)

try {
const roleMigration = await db.oneOrNone(getRoleMigration())
if (!roleMigration) {
throw new MigrationNotFinishedException("role migration has not finished")
}
const users = await db.manyOrNone(getUsers())
if (users && users.length > 0) {
return next(boom.forbidden("User was already initialized"))
}
req.body.role = AllowedRoles.Admin
await createNewUserController(req, res, next)

} catch(error) {
return next(error)
}
} catch(error) {
if (error.code === "42P01" || error instanceof MigrationNotFinishedException) {
return next(boom.preconditionRequired("Migrations were not finished, please try it again later."))
}
return next(error)
}

}
9 changes: 9 additions & 0 deletions src/server/errors/migration-not-finished-exception.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class MigrationNotFinishedException extends Error {
constructor (message) {
super(message)

this.name = this.constructor.name

Error.captureStackTrace(this, this.constructor)
}
}
7 changes: 7 additions & 0 deletions src/server/queries/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,10 @@ export const updatePassword = (id, password) => {
values: [id, password],
}
}

export const getRoleMigration = () => {
return {
text: "SELECT * FROM pgmigrations WHERE name = $1",
values: ["1643273224321_role"],
}
}

0 comments on commit d751df3

Please sign in to comment.