Compare commits
5 Commits
a6c2e7fc7e
...
5d27056906
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d27056906 | |||
| 0ae2903035 | |||
| fdeb8eb26d | |||
| 7d7891f6ca | |||
| 1b384a56b5 |
@@ -55,6 +55,9 @@ class AuthController {
|
|||||||
static async generateCaptcha(req, res) {
|
static async generateCaptcha(req, res) {
|
||||||
try {
|
try {
|
||||||
const { svg, text } = createCaptcha();
|
const { svg, text } = createCaptcha();
|
||||||
|
|
||||||
|
res.setHeader('X-Captcha-Text', text);
|
||||||
|
|
||||||
return res.status(200).json({ data: { svg, text } });
|
return res.status(200).json({ data: { svg, text } });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return res.status(500).json(setResponse([], 'Captcha failed', 500));
|
return res.status(500).json(setResponse([], 'Captcha failed', 500));
|
||||||
@@ -67,13 +70,13 @@ class AuthController {
|
|||||||
const { error, value } = loginSchema.validate(req.body, { abortEarly: false });
|
const { error, value } = loginSchema.validate(req.body, { abortEarly: false });
|
||||||
if (error) return res.status(400).json(setResponse([], 'Validation failed', 400));
|
if (error) return res.status(400).json(setResponse([], 'Validation failed', 400));
|
||||||
|
|
||||||
const { email, password, captcha, captchaText } = value;
|
const { identifier, password, captcha, captchaText } = value;
|
||||||
|
|
||||||
if (!captcha || captcha.toLowerCase() !== captchaText.toLowerCase()) {
|
if (!captcha || captcha.toLowerCase() !== captchaText.toLowerCase()) {
|
||||||
return res.status(400).json(setResponse([], 'Invalid captcha', 400));
|
return res.status(400).json(setResponse([], 'Invalid captcha', 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { user, tokens } = await AuthService.login({ email, password });
|
const { user, tokens } = await AuthService.login({ identifier, password });
|
||||||
|
|
||||||
// Set refresh token di cookie
|
// Set refresh token di cookie
|
||||||
res.cookie('refreshToken', tokens.refreshToken, {
|
res.cookie('refreshToken', tokens.refreshToken, {
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ class DeviceController {
|
|||||||
return res.status(400).json(setResponse(errors, 'Validation failed', 400));
|
return res.status(400).json(setResponse(errors, 'Validation failed', 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
const newDevice = await DeviceService.createDevice(value, req.user.userId);
|
const newDevice = await DeviceService.createDevice(value, req.user.user_id);
|
||||||
|
|
||||||
return res.status(201).json(
|
return res.status(201).json(
|
||||||
setResponse(newDevice, 'Device created successfully', 201)
|
setResponse(newDevice, 'Device created successfully', 201)
|
||||||
);
|
);
|
||||||
@@ -69,7 +70,7 @@ class DeviceController {
|
|||||||
return res.status(400).json(setResponse(errors, 'Validation failed', 400));
|
return res.status(400).json(setResponse(errors, 'Validation failed', 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedDevice = await DeviceService.updateDevice(id, value, req.user.userId);
|
const updatedDevice = await DeviceService.updateDevice(id, value, req.user.user_Id);
|
||||||
|
|
||||||
return res.status(200).json(
|
return res.status(200).json(
|
||||||
setResponse(updatedDevice.data, 'Device updated successfully', 200)
|
setResponse(updatedDevice.data, 'Device updated successfully', 200)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const registerSchema = Joi.object({
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
const loginSchema = Joi.object({
|
const loginSchema = Joi.object({
|
||||||
email: Joi.string().email().required(),
|
identifier: Joi.string().required(),
|
||||||
password: Joi.string().required(),
|
password: Joi.string().required(),
|
||||||
captcha: Joi.string().required(),
|
captcha: Joi.string().required(),
|
||||||
captchaText: Joi.string().required()
|
captchaText: Joi.string().required()
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
const { ErrorHandler } = require("../helpers/error");
|
|
||||||
const { getUserByIdDb } = require("../db/user.db");
|
|
||||||
|
|
||||||
const verifyAccess = (minLevel = 1, allowUnapprovedReadOnly = false) => {
|
|
||||||
return async (req, res, next) => {
|
|
||||||
try {
|
|
||||||
const user = req.user;
|
|
||||||
|
|
||||||
if (!user) throw new ErrorHandler(401, "Unauthorized: User not found");
|
|
||||||
|
|
||||||
// Super Admin bypass semua
|
|
||||||
if (user.is_sa) return next();
|
|
||||||
|
|
||||||
// Ambil user lengkap dari DB
|
|
||||||
const fullUser = await getUserByIdDb(user.user_id);
|
|
||||||
if (!fullUser) throw new ErrorHandler(403, "Forbidden: User not found");
|
|
||||||
|
|
||||||
// Jika belum di-approve
|
|
||||||
if (!fullUser.is_approve) {
|
|
||||||
// Hanya boleh GET (read-only)
|
|
||||||
if (req.method !== "GET") {
|
|
||||||
throw new ErrorHandler(403, "Account not approved — read-only access");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowUnapprovedReadOnly) return next();
|
|
||||||
|
|
||||||
throw new ErrorHandler(403, "Account not approved");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cek role level
|
|
||||||
if (!fullUser.role_level || fullUser.role_level < minLevel) {
|
|
||||||
throw new ErrorHandler(403, "Forbidden: Insufficient role level");
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
} catch (err) {
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = verifyAccess;
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const DeviceController = require('../controllers/device.controller');
|
const DeviceController = require('../controllers/device.controller');
|
||||||
const verifyToken = require("../middleware/verifyToken")
|
const verifyToken = require("../middleware/verifyToken")
|
||||||
const verifyAccess = require("../middleware/verifyAcces")
|
const verifyAccess = require("../middleware/verifyAccess")
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.get('/', verifyToken.verifyAccessToken, DeviceController.getAll);
|
router.get('/', verifyToken.verifyAccessToken, DeviceController.getAll);
|
||||||
router.get('/:id', verifyToken.verifyAccessToken, DeviceController.getById);
|
router.get('/:id', verifyToken.verifyAccessToken, DeviceController.getById);
|
||||||
router.post('/', verifyToken.verifyAccessToken, verifyAccess, DeviceController.create);
|
router.post('/', verifyToken.verifyAccessToken, verifyAccess(), DeviceController.create);
|
||||||
router.put('/:id', verifyToken.verifyAccessToken, verifyAccess, DeviceController.update);
|
router.put('/:id', verifyToken.verifyAccessToken, verifyAccess(), DeviceController.update);
|
||||||
router.delete('/:id', verifyToken.verifyAccessToken, verifyAccess, DeviceController.delete);
|
router.delete('/:id', verifyToken.verifyAccessToken, verifyAccess(), DeviceController.delete);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const UserController = require('../controllers/users.controller');
|
const UserController = require('../controllers/users.controller');
|
||||||
const verifyToken = require('../middleware/verifyToken');
|
const verifyToken = require('../middleware/verifyToken');
|
||||||
const verifyAccess = require('../middleware/verifyAcces');
|
const verifyAccess = require('../middleware/verifyAccess');
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const {
|
const {
|
||||||
getUserByUserEmailDb,
|
getUserByUserEmailDb,
|
||||||
createUserDb
|
createUserDb,
|
||||||
|
getUserByUsernameDb
|
||||||
} = require('../db/user.db');
|
} = require('../db/user.db');
|
||||||
const { hashPassword, comparePassword } = require('../helpers/hashPassword');
|
const { hashPassword, comparePassword } = require('../helpers/hashPassword');
|
||||||
const { ErrorHandler } = require('../helpers/error');
|
const { ErrorHandler } = require('../helpers/error');
|
||||||
@@ -46,10 +47,17 @@ class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Login
|
// Login
|
||||||
static async login({ email, password }) {
|
static async login({ identifier, password }) {
|
||||||
const user = await getUserByUserEmailDb(email);
|
let user;
|
||||||
|
|
||||||
|
if (identifier.includes('@')) {
|
||||||
|
user = await getUserByUserEmailDb(identifier);
|
||||||
|
} else {
|
||||||
|
user = await getUserByUsernameDb(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new ErrorHandler(401, 'Invalid credentials');
|
throw new ErrorHandler(401, 'Invalid credentials')
|
||||||
}
|
}
|
||||||
|
|
||||||
const passwordMatch = await comparePassword(password, user.user_password);
|
const passwordMatch = await comparePassword(password, user.user_password);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class DeviceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update device
|
// Update device
|
||||||
static async updateDevice(id, data, userId) {
|
static async updateDevice(id, data, user_Id) {
|
||||||
if (!data || typeof data !== 'object') data = {};
|
if (!data || typeof data !== 'object') data = {};
|
||||||
|
|
||||||
const existingDevice = await getDeviceByIdDb(id);
|
const existingDevice = await getDeviceByIdDb(id);
|
||||||
@@ -57,7 +57,7 @@ class DeviceService {
|
|||||||
throw new ErrorHandler(404, 'Device not found');
|
throw new ErrorHandler(404, 'Device not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
data.updated_by = userId;
|
data.updated_by = user_Id;
|
||||||
|
|
||||||
const updatedDevice = await updateDeviceDb(id, data);
|
const updatedDevice = await updateDeviceDb(id, data);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user