created API For Aplication Absensi

This commit is contained in:
2025-10-14 14:08:11 +07:00
commit 96d206d892
56 changed files with 6533 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
require('dotenv').config();
const jwt = require('jsonwebtoken');
const db = require('../../models/migration');
const User = db.User;
const optionalAuth = async (req, res, next) => {
try {
const header = req.header('Authorization');
// kalau tidak ada token, user dianggap belum login → lanjut aja
if (!header) {
req.user = null;
return next();
}
const idToken = header.replace('Bearer ', '');
const decoded = jwt.verify(idToken, process.env.JWT_SECRET_KEY);
const user = await User.findByPk(decoded.id);
if (!user || user.is_suspended) {
req.user = null;
return next();
}
req.user = user;
return next();
} catch (e) {
// kalau token invalid, tetap lanjut tapi tanpa user
req.user = null;
return next();
}
};
module.exports = optionalAuth;

48
app/middlewares/apiKey.js Normal file
View File

@@ -0,0 +1,48 @@
const express = require("express");
const app = express();
const Sequelize = require("sequelize");
const db = require("../../models/migration");
const ApiKey = db.apiKey;
async function apiKey(req, res, next) {
const api_key = req.get("ApiKey");
if (!api_key) {
return res.status(401).json({
success: false,
message: "API Key is missing",
code: 401,
});
}
try {
const apiKeyData = await ApiKey.findOne({
where: {
api_key: api_key,
is_actived: 1,
},
});
if (!apiKeyData) {
return res.status(401).json({
success: false,
message: "Unauthorized",
code: 401,
});
}
next();
} catch (err) {
console.error("Error querying API key from database:", err);
return res.status(500).json({
success: false,
message: "Internal Server Error",
code: 500,
});
}
}
module.exports = apiKey;

View File

@@ -0,0 +1,35 @@
require('dotenv').config();
const jwt = require('jsonwebtoken');
const responses = require('../helpers/responses');
const db = require('../../models/migration');
const User = db.User;
const authentication = async (req, res, next) => {
try {
const header = req.header('Authorization');
if (!header) {
return responses.failed(res, 401);
}
const idToken = header.replace('Bearer ', '');
const decoded = jwt.verify(idToken, process.env.JWT_SECRET_KEY);
const userId = decoded.id;
const user = await User.findByPk(userId);
if (!user) {
return responses.failed(res, 401);
}
if (user.is_suspended) {
return responses.failed(res, 403, 'Akun Anda telah ditangguhkan');
}
req.user = user;
return next();
} catch (e) {
console.error(e);
return responses.failed(res, 401);
}
};
module.exports = authentication;

View File

@@ -0,0 +1,16 @@
// middlewares/checkRole.js
const responses = require('../helpers/responses');
module.exports = function(...allowedRoles) {
return (req, res, next) => {
if (!req.user) {
return responses.failed(res, 401, 'Anda belum login');
}
if (!allowedRoles.includes(req.user.role)) {
return responses.failed(res, 403, 'Anda tidak memiliki izin untuk mengakses resource ini');
}
next();
};
};

View File

@@ -0,0 +1,50 @@
const fs = require('fs');
const db = require('../../models/migration');
const BugReporting = db.BugReporting;
const onFinished = require('on-finished');
// Fungsi untuk menyimpan bug report ke database
async function saveBugReport(report) {
try {
const bugReport = await BugReporting.create(report);
return bugReport.insertId;
} catch (error) {
console.error('Error while saving bug report to database:', error);
throw error;
}
}
function errorHandler(err, req, res) {
// console.error('Error :', err);
// console.error('request :', req);
// console.error('Response :', res);
const bugReport = {
class: err.constructor.name,
file: err.fileName || null,
code: null,
status_code: res.statusCode || null,
line: err.lineNumber || null,
message: err.message,
trace: err.stack,
user_id: null,
data: JSON.stringify(req.body),
url: req.originalUrl,
method: req.method,
ip: req.ip,
created_at: new Date(),
updated_at: new Date(),
};
// Simpan bug report ke database
saveBugReport(bugReport)
.then(() => {
// Tangani respons kesalahan
console.error('error: Terjadi kesalahan dalam server');
})
.catch((error) => {
console.error('Error while saving bug report:', error);
});
}
module.exports = errorHandler;

20
app/middlewares/login.js Normal file
View File

@@ -0,0 +1,20 @@
const responses = require('../helpers/responses');
const { validateToken } = require('../helpers/token');
const login = async (req, res, next) => {
let token = req.headers.authorization;
if (!token) return responses.failed(res, 404, 'token not found!');
token = token.split('')[1];
try {
const validateTokenResult = validateToken(token);
dataToken = validateTokenResult;
// console.log(dataToken);
next();
} catch (error) {
responses.failed(res, 500, error.message);
}
};
module.exports = { login };

View File

@@ -0,0 +1,20 @@
const jwt = require('jsonwebtoken')
module.exports = (req, res, next) => {
req.user = null // default selalu null
const authHeader = req.headers['authorization']
if (authHeader) {
const token = authHeader.split(' ')[1]
if (token) {
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET)
req.user = decoded
} catch (err) {
// invalid → tetap null
}
}
}
next()
}

24
app/middlewares/upload.js Normal file
View File

@@ -0,0 +1,24 @@
const multer = require("multer");
// ✅ Pakai memoryStorage → file masuk ke RAM, ada file.buffer
const storage = multer.memoryStorage();
// ✅ Filter hanya image (jpg, jpeg, png, webp)
const fileFilter = (req, file, cb) => {
const allowedTypes = ["image/jpeg", "image/jpg", "image/png", "image/webp"];
if (allowedTypes.includes(file.mimetype)) {
cb(null, true); // lolos
} else {
cb(new Error("Hanya file gambar yang diperbolehkan (jpg, jpeg, png, webp)"), false);
}
};
const upload = multer({
storage,
fileFilter,
limits: {
fileSize: 100 * 1024 * 1024,
},
});
module.exports = upload;