364 lines
10 KiB
Lua
364 lines
10 KiB
Lua
local user = nil
|
|
local domains = {}
|
|
local tlds = {}
|
|
local authToken = nil
|
|
|
|
local userInfo = gurt.select('#user-info')
|
|
local domainsList = gurt.select('#domains-list')
|
|
local logArea = gurt.select('#log-area')
|
|
local inviteModal = gurt.select('#invite-modal')
|
|
local tldSelector = gurt.select('#tld-selector')
|
|
|
|
local logMessages = {}
|
|
|
|
local function addLog(message)
|
|
table.insert(logMessages, Time.format(Time.now(), '%H:%M:%S') .. ' - ' .. message)
|
|
if #logMessages > 50 then
|
|
table.remove(logMessages, 1)
|
|
end
|
|
logArea.text = table.concat(logMessages, '\n')
|
|
end
|
|
|
|
local function showError(elementId, message)
|
|
local element = gurt.select('#' .. elementId)
|
|
|
|
element.text = message
|
|
element.classList:remove('hidden')
|
|
end
|
|
|
|
local function hideError(elementId)
|
|
local element = gurt.select('#' .. elementId)
|
|
|
|
element.classList:add('hidden')
|
|
end
|
|
|
|
local function showModal(modalId)
|
|
local modal = gurt.select('#' .. modalId)
|
|
|
|
modal.classList:remove('hidden')
|
|
end
|
|
|
|
local function hideModal(modalId)
|
|
local modal = gurt.select('#' .. modalId)
|
|
|
|
modal.classList:add('hidden')
|
|
end
|
|
|
|
local function makeRequest(url, options)
|
|
options = options or {}
|
|
if authToken then
|
|
options.headers = options.headers or {}
|
|
options.headers.Authorization = 'Bearer ' .. authToken
|
|
end
|
|
return fetch(url, options)
|
|
end
|
|
|
|
local function checkAuth()
|
|
authToken = gurt.crumbs.get("auth_token")
|
|
|
|
if authToken then
|
|
addLog('Found auth token, checking validity...')
|
|
local response = makeRequest('gurt://localhost:4878/auth/me')
|
|
print(table.tostring(response))
|
|
if response:ok() then
|
|
user = response:json()
|
|
addLog('Authentication successful for user: ' .. user.username)
|
|
updateUserInfo()
|
|
loadDomains()
|
|
loadTLDs()
|
|
else
|
|
addLog('Token invalid, redirecting to login...')
|
|
--gurt.crumbs.delete('auth_token')
|
|
--gurt.location.goto('../')
|
|
end
|
|
else
|
|
addLog('No auth token found, redirecting to login...')
|
|
gurt.location.goto('../')
|
|
end
|
|
end
|
|
|
|
local function logout()
|
|
gurt.crumbs.delete('auth_token')
|
|
addLog('Logged out successfully')
|
|
gurt.location.goto("../")
|
|
end
|
|
|
|
local function loadDomains()
|
|
addLog('Loading domains...')
|
|
local response = makeRequest('gurt://localhost:4878/domains?page=1&size=100')
|
|
|
|
if response:ok() then
|
|
local data = response:json()
|
|
domains = data.domains or {}
|
|
addLog('Loaded ' .. #domains .. ' domains')
|
|
renderDomains()
|
|
else
|
|
addLog('Failed to load domains: ' .. response:text())
|
|
end
|
|
end
|
|
|
|
local function loadTLDs()
|
|
addLog('Loading available TLDs...')
|
|
local response = fetch('gurt://localhost:4878/tlds')
|
|
|
|
if response:ok() then
|
|
tlds = response:json()
|
|
addLog('Loaded ' .. #tlds .. ' TLDs')
|
|
renderTLDSelector()
|
|
else
|
|
addLog('Failed to load TLDs: ' .. response:text())
|
|
end
|
|
end
|
|
|
|
local function submitDomain(name, tld, ip)
|
|
hideError('domain-error')
|
|
addLog('Submitting domain: ' .. name .. '.' .. tld)
|
|
|
|
local response = makeRequest('gurt://localhost:4878/domain', {
|
|
method = 'POST',
|
|
headers = { ['Content-Type'] = 'application/json' },
|
|
body = JSON.stringify({ name = name, tld = tld, ip = ip })
|
|
})
|
|
|
|
if response:ok() then
|
|
local data = response:json()
|
|
addLog('Domain submitted successfully: ' .. data.domain)
|
|
|
|
-- Update user registrations remaining
|
|
user.registrations_remaining = user.registrations_remaining - 1
|
|
updateUserInfo()
|
|
|
|
-- Clear form
|
|
gurt.select('#domain-name').text = ''
|
|
gurt.select('#domain-ip').text = ''
|
|
|
|
-- Refresh domains list
|
|
loadDomains()
|
|
else
|
|
local error = response:text()
|
|
showError('domain-error', 'Domain submission failed: ' .. error)
|
|
addLog('Domain submission failed: ' .. error)
|
|
end
|
|
end
|
|
|
|
local function createInvite()
|
|
addLog('Creating invite code...')
|
|
local response = makeRequest('gurt://localhost:4878/auth/invite', { method = 'POST' })
|
|
|
|
if response:ok() then
|
|
local data = response:json()
|
|
local inviteCode = data.invite_code
|
|
gurt.select('#invite-code-display').text = inviteCode
|
|
addLog('Invite code created: ' .. inviteCode)
|
|
showModal('invite-modal')
|
|
else
|
|
addLog('Failed to create invite: ' .. response:text())
|
|
end
|
|
end
|
|
|
|
local function redeemInvite(code)
|
|
hideError('redeem-error')
|
|
addLog('Redeeming invite code: ' .. code)
|
|
|
|
local response = makeRequest('gurt://localhost:4878/auth/redeem-invite', {
|
|
method = 'POST',
|
|
headers = { ['Content-Type'] = 'application/json' },
|
|
body = JSON.stringify({ invite_code = code })
|
|
})
|
|
|
|
if response:ok() then
|
|
local data = response:json()
|
|
addLog('Invite redeemed: +' .. data.registrations_added .. ' registrations')
|
|
|
|
-- Update user info
|
|
user.registrations_remaining = user.registrations_remaining + data.registrations_added
|
|
updateUserInfo()
|
|
|
|
-- Clear form
|
|
gurt.select('#invite-code-input').text = ''
|
|
else
|
|
local error = response:text()
|
|
showError('redeem-error', 'Failed to redeem invite: ' .. error)
|
|
addLog('Failed to redeem invite: ' .. error)
|
|
end
|
|
end
|
|
|
|
-- UI rendering functions
|
|
local function updateUserInfo()
|
|
if user then
|
|
userInfo.text = 'Welcome, ' .. user.username .. ' | Registrations remaining: ' .. user.registrations_remaining
|
|
end
|
|
end
|
|
|
|
local function renderTLDSelector()
|
|
tldSelector.text = ''
|
|
for i, tld in ipairs(tlds) do
|
|
local option = gurt.create('div', {
|
|
text = '.' .. tld,
|
|
style = 'tld-option',
|
|
['data-tld'] = tld
|
|
})
|
|
|
|
option:on('click', function()
|
|
-- Clear previous selection
|
|
local options = gurt.selectAll('.tld-option')
|
|
for j = 1, #options do
|
|
options[j].classList:remove('tld-selected')
|
|
end
|
|
|
|
-- Select this option
|
|
option.classList:add('tld-selected')
|
|
end)
|
|
|
|
tldSelector:append(option)
|
|
end
|
|
end
|
|
|
|
local function renderDomains()
|
|
domainsList.text = ''
|
|
|
|
if #domains == 0 then
|
|
local emptyMessage = gurt.create('div', {
|
|
text = 'No domains registered yet. Submit your first domain below!',
|
|
style = 'text-center text-[#6b7280] py-8'
|
|
})
|
|
domainsList:append(emptyMessage)
|
|
return
|
|
end
|
|
|
|
for i, domain in ipairs(domains) do
|
|
local domainItem = gurt.create('div', {
|
|
style = 'domain-item'
|
|
})
|
|
|
|
local domainInfo = gurt.create('div', {})
|
|
|
|
local domainName = gurt.create('div', {
|
|
text = domain.name .. '.' .. domain.tld,
|
|
style = 'font-bold text-lg'
|
|
})
|
|
|
|
local domainIP = gurt.create('div', {
|
|
text = 'IP: ' .. domain.ip,
|
|
style = 'text-[#6b7280]'
|
|
})
|
|
|
|
domainInfo:append(domainName)
|
|
domainInfo:append(domainIP)
|
|
|
|
local actions = gurt.create('div', {
|
|
style = 'flex gap-2'
|
|
})
|
|
|
|
-- Update IP button
|
|
local updateBtn = gurt.create('button', {
|
|
text = 'Update IP',
|
|
style = 'secondary-btn'
|
|
})
|
|
|
|
updateBtn:on('click', function()
|
|
local newIP = prompt('Enter new IP address for ' .. domain.name .. '.' .. domain.tld .. ':')
|
|
if newIP and newIP ~= '' then
|
|
updateDomainIP(domain.name, domain.tld, newIP)
|
|
end
|
|
end)
|
|
|
|
-- Delete button
|
|
local deleteBtn = gurt.create('button', { text = 'Delete', style = 'danger-btn' })
|
|
|
|
deleteBtn:on('click', function()
|
|
if confirm('Are you sure you want to delete ' .. domain.name .. '.' .. domain.tld .. '?') then
|
|
deleteDomain(domain.name, domain.tld)
|
|
end
|
|
end)
|
|
|
|
actions:append(updateBtn)
|
|
actions:append(deleteBtn)
|
|
|
|
domainItem:append(domainInfo)
|
|
domainItem:append(actions)
|
|
domainsList:append(domainItem)
|
|
end
|
|
end
|
|
|
|
local function updateDomainIP(name, tld, ip)
|
|
addLog('Updating IP for ' .. name .. '.' .. tld .. ' to ' .. ip)
|
|
|
|
local response = makeRequest('gurt://localhost:4878/domain/' .. name .. '/' .. tld, {
|
|
method = 'PUT',
|
|
headers = { ['Content-Type'] = 'application/json' },
|
|
body = JSON.stringify({ ip = ip })
|
|
})
|
|
|
|
if response:ok() then
|
|
addLog('Domain IP updated successfully')
|
|
loadDomains()
|
|
else
|
|
addLog('Failed to update domain IP: ' .. response:text())
|
|
end
|
|
end
|
|
|
|
local function deleteDomain(name, tld)
|
|
addLog('Deleting domain: ' .. name .. '.' .. tld)
|
|
|
|
local response = makeRequest('gurt://localhost:4878/domain/' .. name .. '/' .. tld, {
|
|
method = 'DELETE'
|
|
})
|
|
|
|
if response:ok() then
|
|
addLog('Domain deleted successfully')
|
|
loadDomains()
|
|
else
|
|
addLog('Failed to delete domain: ' .. response:text())
|
|
end
|
|
end
|
|
|
|
-- Event handlers
|
|
gurt.select('#logout-btn'):on('click', logout)
|
|
|
|
gurt.select('#submit-domain-btn'):on('click', function()
|
|
local name = gurt.select('#domain-name').text
|
|
local ip = gurt.select('#domain-ip').text
|
|
local selectedTLD = gurt.select('.tld-selected')
|
|
|
|
if not name or name == '' then
|
|
showError('domain-error', 'Domain name is required')
|
|
return
|
|
end
|
|
|
|
if not ip or ip == '' then
|
|
showError('domain-error', 'IP address is required')
|
|
return
|
|
end
|
|
|
|
if not selectedTLD then
|
|
showError('domain-error', 'Please select a TLD')
|
|
return
|
|
end
|
|
|
|
local tld = selectedTLD:getAttribute('data-tld')
|
|
submitDomain(name, tld, ip)
|
|
end)
|
|
|
|
gurt.select('#create-invite-btn'):on('click', createInvite)
|
|
|
|
gurt.select('#redeem-invite-btn'):on('click', function()
|
|
local code = gurt.select('#invite-code-input').text
|
|
if code and code ~= '' then
|
|
redeemInvite(code)
|
|
end
|
|
end)
|
|
|
|
gurt.select('#close-invite-modal'):on('click', function()
|
|
hideModal('invite-modal')
|
|
end)
|
|
|
|
gurt.select('#copy-invite-code'):on('click', function()
|
|
local inviteCode = gurt.select('#invite-code-display').text
|
|
Clipboard.write(inviteCode)
|
|
addLog('Invite code copied to clipboard')
|
|
end)
|
|
|
|
-- Initialize
|
|
addLog('Dashboard initialized')
|
|
checkAuth() |