| | const prisma = require("../utils/prisma"); |
| | const { v4: uuidv4 } = require("uuid"); |
| | const ip = require("ip"); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const TemporaryMobileDeviceRequests = new Map(); |
| |
|
| | const MobileDevice = { |
| | platform: "server", |
| | validDeviceOs: ["android"], |
| | tablename: "desktop_mobile_devices", |
| | writable: ["approved"], |
| | validators: { |
| | approved: (value) => { |
| | if (typeof value !== "boolean") return "Must be a boolean"; |
| | return null; |
| | }, |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | tempToken: (token = null) => { |
| | try { |
| | if (!token || !TemporaryMobileDeviceRequests.has(token)) return null; |
| | const tokenData = TemporaryMobileDeviceRequests.get(token); |
| | if (tokenData.expiresAt < Date.now()) return null; |
| | return tokenData; |
| | } catch (error) { |
| | return null; |
| | } finally { |
| | TemporaryMobileDeviceRequests.delete(token); |
| | } |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | registerTempToken: function (user = null) { |
| | let tokenData = {}; |
| | if (user) tokenData.userId = user.id; |
| | else tokenData.userId = null; |
| |
|
| | |
| | const createdAt = Date.now(); |
| | tokenData.createdAt = createdAt; |
| | tokenData.expiresAt = createdAt + 3 * 60_000; |
| |
|
| | const tempToken = uuidv4().split("-").slice(0, 3).join(""); |
| | TemporaryMobileDeviceRequests.set(tempToken, tokenData); |
| |
|
| | |
| | this.cleanupExpiredTokens(); |
| | return tempToken; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | cleanupExpiredTokens: function () { |
| | const now = Date.now(); |
| | for (const [token, data] of TemporaryMobileDeviceRequests.entries()) { |
| | if (data.expiresAt < now) TemporaryMobileDeviceRequests.delete(token); |
| | } |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | connectionURL: function (user = null) { |
| | let baseUrl = "/api/mobile"; |
| | if (process.env.NODE_ENV === "production") baseUrl = "/api/mobile"; |
| | else |
| | baseUrl = `http://${ip.address()}:${process.env.SERVER_PORT || 3001}/api/mobile`; |
| |
|
| | const tempToken = this.registerTempToken(user); |
| | baseUrl = `${baseUrl}?t=${tempToken}`; |
| | return baseUrl; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | create: async function ({ deviceOs, deviceName, userId = null }) { |
| | try { |
| | if (!deviceOs || !deviceName) |
| | return { device: null, error: "Device OS and name are required" }; |
| | if (!this.validDeviceOs.includes(deviceOs)) |
| | return { device: null, error: `Invalid device OS - ${deviceOs}` }; |
| |
|
| | const device = await prisma.desktop_mobile_devices.create({ |
| | data: { |
| | deviceName: String(deviceName), |
| | deviceOs: String(deviceOs).toLowerCase(), |
| | token: uuidv4(), |
| | userId: userId ? Number(userId) : null, |
| | }, |
| | }); |
| | return { device, error: null }; |
| | } catch (error) { |
| | console.error("Failed to create mobile device", error); |
| | return { device: null, error: error.message }; |
| | } |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | update: async function (id, updates = {}) { |
| | const device = await this.get({ id: parseInt(id) }); |
| | if (!device) return { device: null, error: "Device not found" }; |
| |
|
| | const validUpdates = {}; |
| | for (const [key, value] of Object.entries(updates)) { |
| | if (!this.writable.includes(key)) continue; |
| | const validation = this.validators[key](value); |
| | if (validation !== null) return { device: null, error: validation }; |
| | validUpdates[key] = value; |
| | } |
| | |
| | if (Object.keys(validUpdates).length === 0) return { device, error: null }; |
| |
|
| | const updatedDevice = await prisma.desktop_mobile_devices.update({ |
| | where: { id: device.id }, |
| | data: validUpdates, |
| | }); |
| | return { device: updatedDevice, error: null }; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | get: async function (clause = {}, include = null) { |
| | try { |
| | const device = await prisma.desktop_mobile_devices.findFirst({ |
| | where: clause, |
| | ...(include !== null ? { include } : {}), |
| | }); |
| | return device; |
| | } catch (error) { |
| | console.error("FAILED TO GET MOBILE DEVICE.", error); |
| | return []; |
| | } |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | delete: async function (id) { |
| | try { |
| | await prisma.desktop_mobile_devices.delete({ |
| | where: { id: parseInt(id) }, |
| | }); |
| | return { success: true, error: null }; |
| | } catch (error) { |
| | console.error("Failed to delete mobile device", error); |
| | return { success: false, error: error.message }; |
| | } |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | where: async function ( |
| | clause = {}, |
| | limit = null, |
| | orderBy = null, |
| | include = null |
| | ) { |
| | try { |
| | const devices = await prisma.desktop_mobile_devices.findMany({ |
| | where: clause, |
| | ...(limit !== null ? { take: limit } : {}), |
| | ...(orderBy !== null ? { orderBy } : {}), |
| | ...(include !== null ? { include } : {}), |
| | }); |
| | return devices; |
| | } catch (error) { |
| | console.error("FAILED TO GET MOBILE DEVICES.", error.message); |
| | return []; |
| | } |
| | }, |
| | }; |
| |
|
| | module.exports = { MobileDevice }; |
| |
|