const client = global.discord_client const pool = global.db_pool; const crypto = require('crypto'); const execute = async (interaction) => { // If discordID is provided, we need to find the robloxID const [user] = await pool.query('SELECT * FROM users WHERE discordId = ?', [interaction.user.id]); if (!user) return interaction.reply({ content: "User not found", ephemeral: true }); robloxID = user.robloxId; // Check if the user exists if (!robloxID) return interaction.reply({ content: "User not found", ephemeral: true }); const [hub] = await pool.query('SELECT * FROM hubs WHERE discordGuild = ?', [interaction.guild.id]); if (!hub) return interaction.reply({ content: "Hub not found for this guild", ephemeral: true }); const productName = interaction.options.getString("product-name"); // try catch try and find the product based on partial product name, parse everything in uppercase to make things easier const [product] = await pool.query('SELECT * FROM products WHERE UPPER(name) LIKE ? AND hubId = ?', [`%${productName.toUpperCase()}%`, hub.id]); if (!product) return interaction.reply({ content: "Product not found", ephemeral: true }); // Check if the user already owns the product const [purchase] = await pool.query('SELECT * FROM purchases WHERE robloxId = ? AND productId = ?', [robloxID, product.id]); if (!purchase) return interaction.reply({ content: `You don't own \`${product.name}\``, ephemeral: true }); const [auth] = await pool.query('SELECT * FROM fileAuth WHERE owner = ? and product = ?', [robloxID, product.id]); if (auth && auth.expires > Date.now()) return interaction.reply({ content: `Download \`${product.name}\``, ephemeral: true, components: [ { type: 1, components: [ { type: 2, label: 'Download', style: 5, url: `${process.env.BASE_URL}/cdn/${product.file}/${authToken}` } ] } ] }); // Use crypto to generate 32 character auth token const authToken = crypto.randomBytes(16).toString('hex'); // Insert the new auth token into the fileAuth table with an expiration date of 24 hours from now await pool.query('INSERT INTO fileAuth (owner, product, token, expires) VALUES (?, ?, ?, ?)', [robloxID, product.id, authToken, Date.now() + 24 * 60 * 60 * 1000]); // Reply with the download link return interaction.reply({ content: `Download \`${product.name}\``, ephemeral: true, components: [ { type: 1, components: [ { type: 2, label: 'Download', style: 5, url: `${process.env.BASE_URL}/cdn/${product.file}/${authToken}` } ] } ] }); }; module.exports = { execute }