mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-04-20 03:50:20 +00:00
- Added a new Parental Control page for managing device access and notifications. - Introduced blockDevice function to handle blocking and unblocking devices based on payment status. - Enhanced omada-actions.ts to include device blocking logic and improved error handling. - Updated DevicesTable component to integrate BlockDeviceButton for managing device states. - Implemented API route for checking device statuses and sending notifications for expiring devices. - Refactored payment processing to update device statuses upon successful payment verification. - Added new utility functions for API key validation and SMS notifications. These changes improve user control over device management and enhance the overall functionality of the application.
146 lines
3.8 KiB
TypeScript
146 lines
3.8 KiB
TypeScript
import { blockDevice } from "@/actions/omada-actions";
|
|
import prisma from "@/lib/db";
|
|
import { validateApiKey } from "@/lib/utils";
|
|
import { addDays, addMonths, isAfter, isWithinInterval } from "date-fns";
|
|
|
|
const lastRunTime = new Date();
|
|
|
|
export async function GET(request: Request) {
|
|
try {
|
|
// Validate API key before proceeding
|
|
validateApiKey(request);
|
|
|
|
const currentTime = new Date();
|
|
const hoursSinceLastRun =
|
|
(currentTime.getTime() - lastRunTime.getTime()) / (1000 * 60 * 60);
|
|
|
|
// Get all active and unblocked devices with their latest payment
|
|
const devices = await prisma.device.findMany({
|
|
where: {
|
|
isActive: true,
|
|
blocked: false,
|
|
},
|
|
include: {
|
|
payment: true,
|
|
User: true,
|
|
},
|
|
});
|
|
let devicesNeedingNotification = 0;
|
|
let devicesBlocked = 0;
|
|
|
|
for (const device of devices) {
|
|
let expiryDate = new Date();
|
|
|
|
const payment = device.payment;
|
|
expiryDate = addMonths(
|
|
payment?.paidAt || new Date(),
|
|
payment?.numberOfMonths || 0,
|
|
);
|
|
|
|
// Calculate notification threshold (5 days before expiry)
|
|
const notificationThreshold = addDays(expiryDate, -5);
|
|
|
|
const currentDate = new Date();
|
|
|
|
console.log("device name -> ", device.name);
|
|
console.log("paid date -> ", device.payment?.paidAt);
|
|
console.log("no of months paid -> ", device.payment?.numberOfMonths);
|
|
console.log("calculated expire date -> ", expiryDate);
|
|
console.log("notification threshold -> ", notificationThreshold);
|
|
console.log("current date -> ", currentDate);
|
|
|
|
// Check if device is within notification period
|
|
if (
|
|
isWithinInterval(currentDate, {
|
|
start: notificationThreshold,
|
|
end: expiryDate,
|
|
})
|
|
) {
|
|
// Device is within 5 days of expiring
|
|
if (device.User?.phoneNumber) {
|
|
await sendNotifySms(
|
|
new Date(expiryDate),
|
|
device.User.phoneNumber,
|
|
device.name,
|
|
);
|
|
devicesNeedingNotification++;
|
|
}
|
|
}
|
|
|
|
// Check if device has expired
|
|
if (isAfter(currentDate, expiryDate)) {
|
|
// Device has expired, block it
|
|
await prisma.device.update({
|
|
where: { id: device.id },
|
|
data: {
|
|
isActive: false,
|
|
blocked: true,
|
|
},
|
|
});
|
|
devicesBlocked++;
|
|
}
|
|
await blockDevice({
|
|
macAddress: device.mac,
|
|
type: "block",
|
|
});
|
|
}
|
|
|
|
if (hoursSinceLastRun < 24) {
|
|
return Response.json({
|
|
totalActiveDevices: devices.length,
|
|
devicesChecked: {
|
|
notified: devicesNeedingNotification,
|
|
blocked: devicesBlocked,
|
|
},
|
|
message: "Check was run recently",
|
|
nextCheckIn: `${Math.round(24 - hoursSinceLastRun)} hours`,
|
|
});
|
|
}
|
|
|
|
return Response.json({
|
|
success: true,
|
|
totalActiveDevices: devices.length,
|
|
devicesChecked: {
|
|
notified: devicesNeedingNotification,
|
|
blocked: devicesBlocked,
|
|
},
|
|
runAt: currentTime,
|
|
});
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
if (error.message === "API key is missing") {
|
|
return Response.json({ error: "API key is required" }, { status: 401 });
|
|
}
|
|
if (error.message === "Invalid API key") {
|
|
return Response.json({ error: "Invalid API key" }, { status: 403 });
|
|
}
|
|
}
|
|
|
|
console.error("Error in device check:", error);
|
|
return Response.json({ error: "Failed to check devices" }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
// Mock function - replace with your actual SMS implementation
|
|
async function sendNotifySms(
|
|
expireDate: Date,
|
|
phoneNumber: string,
|
|
deviceName?: string,
|
|
) {
|
|
const respose = await fetch("https://smsapi.sarlink.link/send", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
api_key: process.env.SMS_API_KEY,
|
|
number: phoneNumber,
|
|
text: `REMINDER! Your device [${deviceName}] will expire on ${new Date(expireDate)}.`,
|
|
}),
|
|
});
|
|
const data = await respose.json();
|
|
console.log(data);
|
|
return data;
|
|
// Implement your SMS logic here
|
|
}
|