diff --git a/api/Get All Users.bru b/api/Get All Users.bru new file mode 100644 index 0000000..bd6012b --- /dev/null +++ b/api/Get All Users.bru @@ -0,0 +1,11 @@ +meta { + name: Get All Users + type: http + seq: 2 +} + +get { + url: 127.0.0.1:3500/api/v1/users/ + body: none + auth: none +} diff --git a/api/bruno.json b/api/bruno.json new file mode 100644 index 0000000..87abd02 --- /dev/null +++ b/api/bruno.json @@ -0,0 +1,9 @@ +{ + "version": "1", + "name": "OWASP Crypto API", + "type": "collection", + "ignore": [ + "node_modules", + ".git" + ] +} \ No newline at end of file diff --git a/package.json b/package.json index fb7a103..4c74045 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-express-js-template", "type": "module", - "version": "0.1.0", + "version": "0.1.1", "description": "", "author": "Timofey Makhankov", "license": "MIT", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml deleted file mode 100644 index cbdc7a6..0000000 --- a/pnpm-workspace.yaml +++ /dev/null @@ -1,5 +0,0 @@ -ignoredBuiltDependencies: - - unrs-resolver - -onlyBuiltDependencies: - - esbuild diff --git a/src/app.ts b/src/app.ts index 101411d..fcbba5d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,16 @@ import express, { Express } from "express" +import userRouter from "./models/user/user.route" + +const routeCategory = (category: string): string => { + return `/api/v1/${category}` +} const app: Express = express() +app.use(express.json()) + +app.use(routeCategory("users"), userRouter) +app.use(routeCategory("roles"), userRouter) +app.use(routeCategory("permission"), userRouter) + export default app \ No newline at end of file diff --git a/src/db/config.ts b/src/db/config.ts index 43b5b5c..0c68e27 100644 --- a/src/db/config.ts +++ b/src/db/config.ts @@ -1,5 +1,9 @@ import "dotenv/config" import { drizzle } from "drizzle-orm/libsql" import env from "../env" +import * as schema from "../db/schema" -export const db = drizzle({ connection: { url: env.DB_FILE_NAME } }) \ No newline at end of file +export const db = drizzle({ + schema: schema, + connection: { url: env.DB_FILE_NAME } +}) \ No newline at end of file diff --git a/src/models/user/user.controller.ts b/src/models/user/user.controller.ts new file mode 100644 index 0000000..2748bdc --- /dev/null +++ b/src/models/user/user.controller.ts @@ -0,0 +1,36 @@ +import { Request, Response } from "express"; +import { UserService } from "./user.service"; +import { InsertUser } from "../../db/domain"; + +export const getAllUsers = async (res: Response) => { + const users = await UserService.getAll() + return res.status(200).json(users) +} + +export const getUserById = async (req: Request, res: Response) => { + const { id } = req.params + if (Number.isNaN(+id)) { + return res.status(400).json({ message: "Invalid Id" }) + } else { + const user = await UserService.getUserById(+id) + if(user) { + return res.status(200).json(user) + } else { + return res.status(400).json({ message: "User not found" }) + } + } +} + +export const createUser = async (req: Request, res: Response) => { + const user: InsertUser = req.body + const [ result ] = await UserService.createUser(user) + return res.status(201).json(result) +} + +export const updateUser = async (req: Request, res: Response) => { + +} + +export const deleteUser = async (req: Request, res: Response) => { + +} \ No newline at end of file diff --git a/src/models/user/user.route.ts b/src/models/user/user.route.ts new file mode 100644 index 0000000..2d57926 --- /dev/null +++ b/src/models/user/user.route.ts @@ -0,0 +1,12 @@ +import { Router } from "express"; +import { createUser, deleteUser, getAllUsers, getUserById, updateUser } from "./user.controller"; + +const router: Router = Router() + +router.get("/", (_req, res, _next) => {getAllUsers(res)}) +router.get("/:id", (req, res, _next) => { getUserById(req, res) }) +router.post("/", (req, res, _next) => { createUser(req, res) }) +router.put("/:id", (req, res, _next) => { updateUser(req, res) }) +router.delete("/:id", (req, res, _next) => { deleteUser(req, res) }) + +export default router; \ No newline at end of file diff --git a/src/models/user/user.service.ts b/src/models/user/user.service.ts new file mode 100644 index 0000000..be63791 --- /dev/null +++ b/src/models/user/user.service.ts @@ -0,0 +1,102 @@ +import { eq } from "drizzle-orm"; +import { db } from "../../db/config"; +import { InsertUser, User } from "../../db/domain"; +import { permissionsTable, rolesPermissionsTable, rolesTable, usersRolesTable, usersTable } from "../../db/schema"; + +export const UserService = { + async getAll() { + const rows = await db.select() + .from(usersRolesTable) + .innerJoin(usersTable, eq(usersRolesTable.userId, usersTable.id)) + .innerJoin(rolesTable, eq(usersRolesTable.roleId, rolesTable.id)) + .innerJoin(rolesPermissionsTable, eq(rolesTable.id, rolesPermissionsTable.roleId)) + .innerJoin(permissionsTable, eq(rolesPermissionsTable.permissionId, permissionsTable.id)) + .all() + const result = rows.reduce<{ user: User; roles: string[]; permissions: string[] }[]>( + (acc, row) => { + const user = row.users; + const role = row.roles; + const permission = row.permissions; + if(!acc.find((v) => v.user.id === user.id)) { + acc.push({ user, roles: [], permissions: [] }) + } + if (!acc.find((v) => v.user.id === user.id)?.roles.includes(role.name)) { + acc = acc.map((v) => v.user.id === user.id ? { ...v, roles: v.roles.concat(role.name) } : v) + } + if (!acc.find((v) => v.user.id === user.id)?.permissions.includes(permission.name)) { + acc = acc.map((v) => v.user.id === user.id ? { ...v, permissions: v.permissions.concat(permission.name) } : v) + } + return acc + }, [] + ) + return result + /*db.query.usersTable.findMany({ + with: { + usersToRoles: { + columns: { + roleId: false, + userId: false + }, + with: { + role: { + columns: { + id: true, + name: true + }, + with: { + rolesToPermissions: { + columns: { + roleId: false, + permissionId: false + }, + with: { + permission: true + } + } + } + } + } + } + } + })*/ + }, + async getUserById(id: number) { + return db.query.usersTable.findFirst( + { + where(fields, operators) { + return operators.eq(fields.id, id); + }, + with: { + usersToRoles: { + columns: { + roleId: false, + userId: false + }, + with: { + role: { + columns: { + id: true, + name: true + }, + with: { + rolesToPermissions: { + columns: { + roleId: false, + permissionId: false + }, + with: { + permission: true + } + } + } + } + } + } + } + } + ) + }, + async createUser(user: InsertUser) { + return db.insert(usersTable).values(user).returning() + } +} \ No newline at end of file diff --git a/src/router/auth.ts b/src/router/auth.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/routes/example.ts b/src/routes/example.ts deleted file mode 100644 index 32007d0..0000000 --- a/src/routes/example.ts +++ /dev/null @@ -1,5 +0,0 @@ -import app from "../app" - -app.get("/", (_req, res) => { - res.send("Hello world!") -}) \ No newline at end of file