farheen-psql-app 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +8 -0
- package/package.json +24 -0
- package/src/app.js +14 -0
- package/src/config/db.js +15 -0
- package/src/controllers/permissionController.js +54 -0
- package/src/controllers/roleController.js +11 -0
- package/src/controllers/user.js +76 -0
- package/src/database/schemas/permissionSchema.js +12 -0
- package/src/database/schemas/rolePermissionSchema.js +21 -0
- package/src/database/schemas/roleSchema.js +12 -0
- package/src/database/schemas/userSchema.js +26 -0
- package/src/database/setupdb.js +63 -0
- package/src/middleware/authentication.js +5 -0
- package/src/middleware/authorization.js +17 -0
- package/src/models/permission.js +48 -0
- package/src/models/role.js +48 -0
- package/src/models/rolePermission.js +29 -0
- package/src/models/user.js +72 -0
- package/src/repositories/permissionRepo.js +47 -0
- package/src/repositories/roleRepository.js +12 -0
- package/src/repositories/user.js +37 -0
- package/src/routes/index.js +4 -0
- package/src/routes/user.js +7 -0
- package/src/server.js +27 -0
- package/src/services/permissionService.js +21 -0
- package/src/services/roleService.js +10 -0
- package/src/services/user.js +28 -0
- package/src/utils/jwt.js +11 -0
package/.env
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "farheen-psql-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
+
"start": "node src/server.js",
|
|
9
|
+
"db:setup": "node script/setupdb.js"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"description": "",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"bcryptjs": "^3.0.3",
|
|
17
|
+
"cors": "^2.8.6",
|
|
18
|
+
"dotenv": "^17.4.2",
|
|
19
|
+
"express": "^5.2.1",
|
|
20
|
+
"jsonwebtoken": "^9.0.3",
|
|
21
|
+
"node-pg-migrate": "^8.0.4",
|
|
22
|
+
"pg": "^8.21.0"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/app.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
const app = express();
|
|
3
|
+
import indexRoutes from "../src/routes/index.js";
|
|
4
|
+
|
|
5
|
+
app.use(cors());
|
|
6
|
+
app.use(express.json());
|
|
7
|
+
|
|
8
|
+
app.use("/api", indexRoutes);
|
|
9
|
+
|
|
10
|
+
app.use("/", () => {
|
|
11
|
+
console.log("Health check of the app");
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export default app;
|
package/src/config/db.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
|
|
4
|
+
dotenv.config();
|
|
5
|
+
import { Pool } from "pg";
|
|
6
|
+
|
|
7
|
+
const pool = new Pool({
|
|
8
|
+
user: process.env.DB_USER,
|
|
9
|
+
host: process.env.DB_HOST,
|
|
10
|
+
database: process.env.DB_NAME,
|
|
11
|
+
password: process.env.DB_PASSWORD,
|
|
12
|
+
port: process.env.DB_PORT
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export default pool;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createPermission, deletePermission, getAllPermissions } from "../services/permissionService.js";
|
|
2
|
+
|
|
3
|
+
export const createPermissionHandler = (req, res) => {
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
|
|
7
|
+
const result = await createPermission(req.body);
|
|
8
|
+
|
|
9
|
+
return res.status(201).json({
|
|
10
|
+
success: true,
|
|
11
|
+
data: result
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
} catch (error) {
|
|
15
|
+
return res.status(500).json({
|
|
16
|
+
success: false,
|
|
17
|
+
message: error.message
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const getAllPermissionsHandler = (req, res) => {
|
|
23
|
+
try {
|
|
24
|
+
const result = await getAllPermissions();
|
|
25
|
+
|
|
26
|
+
return res.status(200).json({
|
|
27
|
+
success: true,
|
|
28
|
+
data: result
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
} catch (error) {
|
|
32
|
+
return res.status(500).json({
|
|
33
|
+
success: false,
|
|
34
|
+
message: error.message
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const deletePermissionHandler = (req, res) => {
|
|
40
|
+
try {
|
|
41
|
+
const result = await deletePermission(req.params.id);
|
|
42
|
+
|
|
43
|
+
return res.status(200).json({
|
|
44
|
+
success: true,
|
|
45
|
+
data: result
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return res.status(500).json({
|
|
50
|
+
success: false,
|
|
51
|
+
message: error.message
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createRoleService, getAllRolesService } from "../services/roleService.js";
|
|
2
|
+
|
|
3
|
+
export const createRoleHandler = (req, res) => {
|
|
4
|
+
const result = await createRoleService(req.body);
|
|
5
|
+
res.status(201).json(result);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const getAllRoles = (req, res) => {
|
|
9
|
+
const result = await getAllRolesService();
|
|
10
|
+
res.status(200).json(result);
|
|
11
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as userService from '../services/userService.js';
|
|
2
|
+
|
|
3
|
+
export const getAllUsers = async (req, res) => {
|
|
4
|
+
try {
|
|
5
|
+
const users = await userService.getAllUsers();
|
|
6
|
+
res.status(200).json(users);
|
|
7
|
+
} catch (error) {
|
|
8
|
+
console.error('Error fetching users:', error);
|
|
9
|
+
res.status(500).json({ error: 'Internal Server Error' });
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const getUserById = async (req, res) => {
|
|
14
|
+
try {
|
|
15
|
+
const { id } = req.params;
|
|
16
|
+
const user = await userService.getUserById(id);
|
|
17
|
+
if (!user) {
|
|
18
|
+
return res.status(404).json({ error: 'User not found' });
|
|
19
|
+
}
|
|
20
|
+
res.status(200).json(user);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error('Error fetching user:', error);
|
|
23
|
+
res.status(500).json({ error: 'Internal Server Error' });
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const createUser = async (req, res) => {
|
|
28
|
+
try {
|
|
29
|
+
const { name, email, age } = req.body;
|
|
30
|
+
if (!name || !email) {
|
|
31
|
+
return res.status(400).json({ error: 'Name and email are required' });
|
|
32
|
+
}
|
|
33
|
+
const newUser = await userService.createUser({ name, email, age });
|
|
34
|
+
res.status(201).json(newUser);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error('Error creating user:', error);
|
|
37
|
+
// Handle specific service errors
|
|
38
|
+
if (error.message === 'Age cannot be negative') {
|
|
39
|
+
return res.status(400).json({ error: error.message });
|
|
40
|
+
}
|
|
41
|
+
res.status(500).json({ error: 'Internal Server Error' });
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const updateUser = async (req, res) => {
|
|
46
|
+
try {
|
|
47
|
+
const { id } = req.params;
|
|
48
|
+
const { name, email, age } = req.body;
|
|
49
|
+
|
|
50
|
+
const updatedUser = await userService.updateUser(id, { name, email, age });
|
|
51
|
+
if (!updatedUser) {
|
|
52
|
+
return res.status(404).json({ error: 'User not found' });
|
|
53
|
+
}
|
|
54
|
+
res.status(200).json(updatedUser);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error('Error updating user:', error);
|
|
57
|
+
if (error.message === 'Age cannot be negative') {
|
|
58
|
+
return res.status(400).json({ error: error.message });
|
|
59
|
+
}
|
|
60
|
+
res.status(500).json({ error: 'Internal Server Error' });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const deleteUser = async (req, res) => {
|
|
65
|
+
try {
|
|
66
|
+
const { id } = req.params;
|
|
67
|
+
const deletedUser = await userService.deleteUser(id);
|
|
68
|
+
if (!deletedUser) {
|
|
69
|
+
return res.status(404).json({ error: 'User not found' });
|
|
70
|
+
}
|
|
71
|
+
res.status(200).json({ message: 'User deleted successfully', user: deletedUser });
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('Error deleting user:', error);
|
|
74
|
+
res.status(500).json({ error: 'Internal Server Error' });
|
|
75
|
+
}
|
|
76
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const permissionTable = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS permissions (
|
|
3
|
+
id SERIAL PRIMARY KEY,
|
|
4
|
+
module VARCHAR(100) NOT NULL,
|
|
5
|
+
action VARCHAR(100) NOT NULL,
|
|
6
|
+
description TEXT,
|
|
7
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
8
|
+
UNIQUE(module, action)
|
|
9
|
+
);
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
export default permissionTable;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const rolePermissionTable = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS role_permissions (
|
|
3
|
+
id SERIAL PRIMARY KEY,
|
|
4
|
+
|
|
5
|
+
role_id INTEGER NOT NULL,
|
|
6
|
+
|
|
7
|
+
permission_id INTEGER NOT NULL,
|
|
8
|
+
|
|
9
|
+
FOREIGN KEY(role_id)
|
|
10
|
+
REFERENCES roles(id)
|
|
11
|
+
ON DELETE CASCADE,
|
|
12
|
+
|
|
13
|
+
FOREIGN KEY(permission_id)
|
|
14
|
+
REFERENCES permissions(id)
|
|
15
|
+
ON DELETE CASCADE,
|
|
16
|
+
|
|
17
|
+
UNIQUE(role_id, permission_id)
|
|
18
|
+
);
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
export default rolePermissionTable;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const roleTable = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS roles (
|
|
3
|
+
id SERIAL PRIMARY KEY,
|
|
4
|
+
role_name VARCHAR(100) UNIQUE NOT NULL,
|
|
5
|
+
description TEXT,
|
|
6
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
7
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
8
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
9
|
+
);
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
export default roleTable;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const userTable = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
3
|
+
id SERIAL PRIMARY KEY,
|
|
4
|
+
|
|
5
|
+
first_name VARCHAR(100) NOT NULL,
|
|
6
|
+
|
|
7
|
+
last_name VARCHAR(100),
|
|
8
|
+
|
|
9
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
10
|
+
|
|
11
|
+
password TEXT NOT NULL,
|
|
12
|
+
|
|
13
|
+
role_id INTEGER,
|
|
14
|
+
|
|
15
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
16
|
+
|
|
17
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
18
|
+
|
|
19
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
20
|
+
|
|
21
|
+
FOREIGN KEY(role_id)
|
|
22
|
+
REFERENCES roles(id)
|
|
23
|
+
);
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
export default userTable;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
import { Client } from "pg";
|
|
4
|
+
import roleTable from "./schemas/roleSchema";
|
|
5
|
+
import permissionTable from "./schemas/permissionSchema";
|
|
6
|
+
import rolePermissionTable from "./schemas/rolePermissionSchema";
|
|
7
|
+
import userTable from "./schemas/userSchema";
|
|
8
|
+
import pool from "../config/db.js";
|
|
9
|
+
|
|
10
|
+
dotenv.config();
|
|
11
|
+
|
|
12
|
+
const tables = [
|
|
13
|
+
roleTable,
|
|
14
|
+
permissionTable,
|
|
15
|
+
rolePermissionTable,
|
|
16
|
+
userTable
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
export const setupdb = async () => {
|
|
20
|
+
const adminclient = new Client({
|
|
21
|
+
user: process.env.DB_USER,
|
|
22
|
+
host: process.env.DB_HOST,
|
|
23
|
+
database: 'postgres',
|
|
24
|
+
password: process.env.DB_PASSWORD,
|
|
25
|
+
port: process.env.DB_PORT
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
await adminclient.connect();
|
|
30
|
+
console.log("Connected to admin database");
|
|
31
|
+
|
|
32
|
+
const dbName = process.env.DB_NAME;
|
|
33
|
+
const connectDbResult = await adminclient.query(
|
|
34
|
+
"SELECT 1 FROM pg_database WHERE datname = $1",
|
|
35
|
+
[dbName]
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if (connectDbResult.rowCount === 0) {
|
|
39
|
+
console.log(`Databse '${dbName}' does not exit. Creating....`);
|
|
40
|
+
await adminclient.query(`CREATE DATABASE "${dbName}"`);
|
|
41
|
+
console.log(`Databse '${dbName}' created successfully`);
|
|
42
|
+
} else {
|
|
43
|
+
console.log(`Database '${dbName}' already exist.`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
for (const table of tables) {
|
|
48
|
+
await pool.query(table);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log("✅ All tables created");
|
|
52
|
+
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error("❌ Setup Error:", error);
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("Error creating/checking database", error);
|
|
58
|
+
} finally {
|
|
59
|
+
await adminclient.end();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// setupdb();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { verifyToken } from "../utils/jwt.js";
|
|
2
|
+
|
|
3
|
+
export const authentication = async (req, res, next) => {
|
|
4
|
+
try {
|
|
5
|
+
const token = req.headers.authorization.split(" ")[1];
|
|
6
|
+
|
|
7
|
+
if (!token) {
|
|
8
|
+
return res.status(403).json({ error: 'Unauthorized: No token provided' });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const decoded = verifyToken(token);
|
|
12
|
+
req.user = decoded;
|
|
13
|
+
next();
|
|
14
|
+
} catch (error) {
|
|
15
|
+
return res.status(401).json({ error: 'Unauthorized: Invalid token' });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const createPermissionQuery = `
|
|
2
|
+
INSERT INTO permissions
|
|
3
|
+
(
|
|
4
|
+
permission_name,
|
|
5
|
+
description,
|
|
6
|
+
created_at
|
|
7
|
+
)
|
|
8
|
+
VALUES
|
|
9
|
+
(
|
|
10
|
+
$1,
|
|
11
|
+
$2,
|
|
12
|
+
NOW()
|
|
13
|
+
)
|
|
14
|
+
RETURNING *;
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
export const getPermissionByIdQuery = `
|
|
18
|
+
SELECT *
|
|
19
|
+
FROM permissions
|
|
20
|
+
WHERE id = $1;
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
export const getPermissionByNameQuery = `
|
|
24
|
+
SELECT *
|
|
25
|
+
FROM permissions
|
|
26
|
+
WHERE permission_name = $1;
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
export const getAllPermissionsQuery = `
|
|
30
|
+
SELECT *
|
|
31
|
+
FROM permissions
|
|
32
|
+
ORDER BY id;
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
export const updatePermissionQuery = `
|
|
36
|
+
UPDATE permissions
|
|
37
|
+
SET
|
|
38
|
+
permission_name = $1,
|
|
39
|
+
description = $2
|
|
40
|
+
WHERE id = $3
|
|
41
|
+
RETURNING *;
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
export const deletePermissionQuery = `
|
|
45
|
+
DELETE FROM permissions
|
|
46
|
+
WHERE id = $1
|
|
47
|
+
RETURNING *;
|
|
48
|
+
`;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const createRoleQuery = `
|
|
2
|
+
INSERT INTO roles
|
|
3
|
+
(
|
|
4
|
+
role_name,
|
|
5
|
+
description,
|
|
6
|
+
created_at
|
|
7
|
+
)
|
|
8
|
+
VALUES
|
|
9
|
+
(
|
|
10
|
+
$1,
|
|
11
|
+
$2,
|
|
12
|
+
NOW()
|
|
13
|
+
)
|
|
14
|
+
RETURNING *;
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
export const getRoleByIdQuery = `
|
|
18
|
+
SELECT *
|
|
19
|
+
FROM roles
|
|
20
|
+
WHERE id = $1;
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
export const getRoleByNameQuery = `
|
|
24
|
+
SELECT *
|
|
25
|
+
FROM roles
|
|
26
|
+
WHERE role_name = $1;
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
export const getAllRolesQuery = `
|
|
30
|
+
SELECT *
|
|
31
|
+
FROM roles
|
|
32
|
+
ORDER BY id;
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
export const updateRoleQuery = `
|
|
36
|
+
UPDATE roles
|
|
37
|
+
SET
|
|
38
|
+
role_name = $1,
|
|
39
|
+
description = $2
|
|
40
|
+
WHERE id = $3
|
|
41
|
+
RETURNING *;
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
export const deleteRoleQuery = `
|
|
45
|
+
DELETE FROM roles
|
|
46
|
+
WHERE id = $1
|
|
47
|
+
RETURNING *;
|
|
48
|
+
`;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const assignPermissionToRoleQuery = `
|
|
2
|
+
INSERT INTO role_permissions
|
|
3
|
+
(
|
|
4
|
+
role_id,
|
|
5
|
+
permission_id
|
|
6
|
+
)
|
|
7
|
+
VALUES
|
|
8
|
+
(
|
|
9
|
+
$1,
|
|
10
|
+
$2
|
|
11
|
+
)
|
|
12
|
+
RETURNING *;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export const removePermissionFromRoleQuery = `
|
|
16
|
+
DELETE FROM role_permissions
|
|
17
|
+
WHERE role_id = $1
|
|
18
|
+
AND permission_id = $2;
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
export const getRolePermissionsQuery = `
|
|
22
|
+
SELECT
|
|
23
|
+
p.id,
|
|
24
|
+
p.permission_name
|
|
25
|
+
FROM role_permissions rp
|
|
26
|
+
INNER JOIN permissions p
|
|
27
|
+
ON rp.permission_id = p.id
|
|
28
|
+
WHERE rp.role_id = $1;
|
|
29
|
+
`;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export const createUserQuery = `
|
|
2
|
+
INSERT INTO users
|
|
3
|
+
(
|
|
4
|
+
first_name,
|
|
5
|
+
last_name,
|
|
6
|
+
email,
|
|
7
|
+
password,
|
|
8
|
+
role_id,
|
|
9
|
+
is_active,
|
|
10
|
+
created_at,
|
|
11
|
+
updated_at
|
|
12
|
+
)
|
|
13
|
+
VALUES
|
|
14
|
+
(
|
|
15
|
+
$1,
|
|
16
|
+
$2,
|
|
17
|
+
$3,
|
|
18
|
+
$4,
|
|
19
|
+
$5,
|
|
20
|
+
$6,
|
|
21
|
+
NOW(),
|
|
22
|
+
NOW()
|
|
23
|
+
)
|
|
24
|
+
RETURNING *;
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
export const getUserByIdQuery = `
|
|
28
|
+
SELECT
|
|
29
|
+
u.*,
|
|
30
|
+
r.role_name
|
|
31
|
+
FROM users u
|
|
32
|
+
LEFT JOIN roles r
|
|
33
|
+
ON u.role_id = r.id
|
|
34
|
+
WHERE u.id = $1;
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
export const getUserByEmailQuery = `
|
|
38
|
+
SELECT *
|
|
39
|
+
FROM users
|
|
40
|
+
WHERE email = $1;
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
export const getAllUsersQuery = `
|
|
44
|
+
SELECT
|
|
45
|
+
u.id,
|
|
46
|
+
u.first_name,
|
|
47
|
+
u.last_name,
|
|
48
|
+
u.email,
|
|
49
|
+
u.is_active,
|
|
50
|
+
r.role_name
|
|
51
|
+
FROM users u
|
|
52
|
+
LEFT JOIN roles r
|
|
53
|
+
ON u.role_id = r.id;
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
export const updateUserQuery = `
|
|
57
|
+
UPDATE users
|
|
58
|
+
SET
|
|
59
|
+
first_name = $1,
|
|
60
|
+
last_name = $2,
|
|
61
|
+
email = $3,
|
|
62
|
+
role_id = $4,
|
|
63
|
+
updated_at = NOW()
|
|
64
|
+
WHERE id = $5
|
|
65
|
+
RETURNING *;
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
export const deleteUserQuery = `
|
|
69
|
+
DELETE FROM users
|
|
70
|
+
WHERE id = $1
|
|
71
|
+
RETURNING *;
|
|
72
|
+
`;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import pool from "../config/db.js";
|
|
4
|
+
import { createPermissionQuery, deletePermissionQuery,
|
|
5
|
+
getAllPermissionsQuery, getPermissionByIdQuery } from "../models/permission.js";
|
|
6
|
+
|
|
7
|
+
export const createPermission = (data) => {
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
module,
|
|
11
|
+
action,
|
|
12
|
+
description
|
|
13
|
+
} = data;
|
|
14
|
+
|
|
15
|
+
const result = await pool.query(createPermissionQuery, [module, action, description]);
|
|
16
|
+
return result.rows[0];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const getAllPermissions = () => {
|
|
20
|
+
|
|
21
|
+
const result =
|
|
22
|
+
await pool.query(getAllPermissionsQuery);
|
|
23
|
+
|
|
24
|
+
return result.rows;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const getPermissionById = (id) => {
|
|
28
|
+
|
|
29
|
+
const result =
|
|
30
|
+
await pool.query(
|
|
31
|
+
getPermissionByIdQuery,
|
|
32
|
+
[id]
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return result.rows[0];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const deletePermission = (id) => {
|
|
39
|
+
|
|
40
|
+
const result =
|
|
41
|
+
await pool.query(
|
|
42
|
+
deletePermissionQuery,
|
|
43
|
+
[id]
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
return result.rows[0];
|
|
47
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import pool from "../config/db.js";
|
|
2
|
+
import { createRoleQuery, getAllRolesQuery } from "../models/role.js";
|
|
3
|
+
|
|
4
|
+
export const createRole = (data) => {
|
|
5
|
+
const result = await pool.query(createRoleQuery, [data.role_name, data.description]);
|
|
6
|
+
return result.rows[0];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const getAllRoles = () => {
|
|
10
|
+
const result = await pool.query(getAllRolesQuery);
|
|
11
|
+
return result.rows;
|
|
12
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import pool from "../config/db.js";
|
|
2
|
+
|
|
3
|
+
export const create = async (userData) => {
|
|
4
|
+
const { name, email, password, role } = userData;
|
|
5
|
+
const result = await pool.query(
|
|
6
|
+
`INSERT INTO users (name, email, password, role) VALUES ($1, $2, $3, $4) RETURNING *`,
|
|
7
|
+
[name, email, password, role]
|
|
8
|
+
)
|
|
9
|
+
return result.rows[0];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const getAll = async () => {
|
|
13
|
+
const result = await pool.query(`SELECT * FROM user ORDER BY created_at DESC`);
|
|
14
|
+
return result.rows;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const getById = async (id) => {
|
|
18
|
+
const result = await pool.query(`SELECT * FROM users WHERE id = $1`, [id]);
|
|
19
|
+
return result.rows[0];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const getByEmail = async (email) => {
|
|
23
|
+
const result = await pool.query(`SELECT * FROM users WHERE email = $1`, [email]);
|
|
24
|
+
return result.rows[0];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const update = async (id, userData) => {
|
|
28
|
+
const { name, email, role } = userData;
|
|
29
|
+
const result = await pool.query(`UPDATE users SET name = $1, email = $2, role = $3, updated_at = CURRENT_TIMESTAMPS WHERE id = $4 RETURNING *`,
|
|
30
|
+
[name, email, role, id]);
|
|
31
|
+
return result.rows[0];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const remove = async (id) => {
|
|
35
|
+
const result = await pool.query(`DELETE FROM users WHERE id = $1 RETURNING *`, [id]);
|
|
36
|
+
return result.rows[0];
|
|
37
|
+
}
|
package/src/server.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
import pool from "./config/db.js";
|
|
4
|
+
import app from "./app";
|
|
5
|
+
import { setupdb } from "./database/setupdb.js";
|
|
6
|
+
|
|
7
|
+
const port = process.env.PORT;
|
|
8
|
+
|
|
9
|
+
dotenv.config();
|
|
10
|
+
|
|
11
|
+
const startServer = async () => {
|
|
12
|
+
try {
|
|
13
|
+
const client = await pool.connect();
|
|
14
|
+
console.log("Connected to PostgreSQL database successfully");
|
|
15
|
+
|
|
16
|
+
await setupdb();
|
|
17
|
+
|
|
18
|
+
app.listen(port, () => {
|
|
19
|
+
console.log(`Server is running on port '${port}'`);
|
|
20
|
+
})
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error("Error connecting to the database", error);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
startServer();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import permissionRepository
|
|
2
|
+
from "../repositories/permissionRepository.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export const createPermission = async (data) => {
|
|
6
|
+
|
|
7
|
+
return await permissionRepository
|
|
8
|
+
.createPermission(data);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const getAllPermissions = async () => {
|
|
12
|
+
|
|
13
|
+
return await permissionRepository
|
|
14
|
+
.getAllPermissions();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const deletePermission = async (id) => {
|
|
18
|
+
|
|
19
|
+
return await permissionRepository
|
|
20
|
+
.deletePermission(id);
|
|
21
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getAllRolesQuery } from "../models/role";
|
|
2
|
+
import { createRole } from "../repositories/roleRepository.js";
|
|
3
|
+
|
|
4
|
+
export const createRoleService = (data) => {
|
|
5
|
+
return await createRole(data);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const getAllRolesService = () => {
|
|
9
|
+
return await getAllRolesQuery();
|
|
10
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as userRepository from '../repositories/userRepository.js';
|
|
2
|
+
|
|
3
|
+
export const getAllUsers = async () => {
|
|
4
|
+
return await userRepository.findAll();
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const getUserById = async (id) => {
|
|
8
|
+
return await userRepository.findById(id);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const createUser = async (userData) => {
|
|
12
|
+
// Example of business logic in service
|
|
13
|
+
if (userData.age && userData.age < 0) {
|
|
14
|
+
throw new Error('Age cannot be negative');
|
|
15
|
+
}
|
|
16
|
+
return await userRepository.create(userData);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const updateUser = async (id, userData) => {
|
|
20
|
+
if (userData.age && userData.age < 0) {
|
|
21
|
+
throw new Error('Age cannot be negative');
|
|
22
|
+
}
|
|
23
|
+
return await userRepository.update(id, userData);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const deleteUser = async (id) => {
|
|
27
|
+
return await userRepository.remove(id);
|
|
28
|
+
};
|
package/src/utils/jwt.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
|
|
3
|
+
export const accessToken = (user) => {
|
|
4
|
+
return jwt.sign({ id: user.id, email: user.email, role: user.role },
|
|
5
|
+
process.env.JWT_SECRET_key,
|
|
6
|
+
{ expiresIn: '1d' });
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const verifyToken = (token) => {
|
|
10
|
+
return jwt.verify(token, process.env.JWT_SECRET_key);
|
|
11
|
+
}
|