diff --git a/SECURITY.md b/SECURITY.md index 000cdd0..a03fca3 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,4 +12,4 @@ ## Reporting a Vulnerability To report a security vulnerability, please do **not** create a GitHub issue, but report a [security vuln on GitHub instead!](https://github.com/Kristify/Kristify/security/advisories). -This lets the maintainers get aware of the vulnerability and talk with the security researched in private. If you believe you found a security vulnerability, please do not talk about it in public! +This lets the maintainers get aware of the vulnerability, and talk with the security researcher in private. If you believe you found a security vulnerability, please do not talk about it in public! diff --git a/kristify.lua b/kristify.lua index 5ca6e0b..f0b0422 100644 --- a/kristify.lua +++ b/kristify.lua @@ -1,163 +1,182 @@ local installation = settings.get("kristify.path") or "kristify" -local owner,repo = "kristify","themes" -local tArgs = {...} +local owner, themeRepo = "kristify", "themes" +local args = { ... } --- Check update -local verPath = fs.combine(installation,"src","version.txt") +-- Check installed version +local versionPath = fs.combine(installation, "src", "version.txt") local version = "0.0.0" -if fs.exists(verPath) then - local file = fs.open(verPath, 'r') +if fs.exists(versionPath) then + local file = fs.open(versionPath, 'r') version = file.readAll() file.close() end -local authenticate = _G._GIT_API_KEY and {Authorization = "Bearer ".._G._GIT_API_KEY} +-- Check upstream version +local authenticate = _G._GIT_API_KEY and { Authorization = "Bearer " .. _G._GIT_API_KEY } local gitAPI = http.get("https://raw.githubusercontent.com/Kristify/Kristify/main/src/version.txt", authenticate) + if gitAPI then - local newV = gitAPI.readAll() - if newV ~= version then - term.setTextColor(colors.orange) - term.write("Update available for Kristify! ") - term.setTextColor(colors.lightGray) - print(version.." (current) --> ".. newV .. " (latest)") - term.setTextColor(colors.white) - print("Run \'kristify.lua -u\' or --update") - sleep(0.8) - end - gitAPI.close() + local upstreamVersion = gitAPI.readAll() + + if upstreamVersion ~= version then + term.setTextColor(colors.orange) + print("Update available for Kristify! ") + term.setTextColor(colors.lightGray) + print(("%s (installed) --> %s (latest)"):format(version, upstreamVersion)) + term.setTextColor(colors.white) + print("Run \'kristify.lua -u\' or --update") + sleep(1) + end + + gitAPI.close() end -- Run Kristify normally -if #tArgs == 0 then - local path = fs.combine(installation,"src","init.lua") - if not fs.exists(path) then +if #args == 0 then + local initPath = fs.combine(installation, "src", "init.lua") + if not fs.exists(initPath) then error("Kristify is not installed correctly!") end if term.isColor() then - local id = shell.openTab(path) + local id = shell.openTab(initPath) multishell.setTitle(id, "Kristify") shell.switchTab(id) else - shell.run(path) + print("Note: Kristify works best with advanced devices, as they have color and multishell") + shell.run(initPath) end end -- Install theme -if tArgs[1] == "--theme" or tArgs[1] == "-t" then +if args[1] == "--theme" or args[1] == "-t" then -- Show current theme - if not tArgs[2] or tArgs[2] == "" then - local name,author = "Unknown","Herobrine" - local path = fs.combine(installation,"data","credits.json") + + if not args[2] or args[2] == "" then + local name, author = "Unknown", "Herobrine" + local path = fs.combine(installation, "data", "credits.json") + if fs.exists(path) then - local file = fs.open(verPath, 'r') + local file = fs.open(versionPath, 'r') local data = file.readAll() + file.close() + data = textutils.unserialiseJSON(data) or {} name = data.name or "Unknown" author = data.author or "Herobrine" - file.close() end term.setTextColor(colors.lightGray) term.write("Theme: ") term.setTextColor(colors.white) - print(name.." by "..author) + print(name .. " by " .. author) else -- Change theme - local file = http.get("https://raw.githubusercontent.com/"..owner..'/'..repo.."/main/"..tArgs[2].."/credits.json") - if not file then printError("The given theme doesn't exist!") return end + + local file = http.get(("https://raw.githubusercontent.com/%s/%s/main/%s/credits.json") + :format(owner, themeRepo, args[2])) + + if not file then + error("The given theme doesn't exist!") + end local data = file.readAll() - data = textutils.unserialiseJSON(data) - if not data then printError("The given theme doesn't exist!") return end - local name = data.name - local author = data.author file.close() - print("Installing "..name.." by "..author) + data = textutils.unserialiseJSON(data) + if not data then + error("The given theme doesn't exist!") + end - local function httpError(response,err,errResponse) - if not response then - errors = true - justinWeHaveAProblem("Request to GitHub denied; Reason: \'.."..err.."..\' (code "..errResponse.getResponseCode()..").") - return false - end - return true + local name = data.name + local author = data.author + + print(("Installing %s theme by %s"):format(name, author)) + + local function httpError(response, err, errResponse) + if not response then + error("Request to GitHub denied; Reason: \'.." .. + err .. "..\' (code " .. errResponse.getResponseCode() .. ").") + end end local function getJSON(response) if not response then return {} end - local tData = response.readAll() + + local rawData = response.readAll() response.close() - return textutils.unserialiseJSON(tData) + return textutils.unserialiseJSON(rawData) end local function generateTree(name) - sURL = "https://api.github.com/repos/"..owner..'/'..repo.."/contents/"..name.."?ref=main" + sURL = "https://api.github.com/repos/" .. owner .. '/' .. themeRepo .. "/contents/" .. name .. "?ref=main" + local function convertItem(item) - if item.type == "file" then - return item.name, item.download_url - elseif item.type == "dir" then - return item.name, generateTree(item.url) - end + if item.type == "file" then + return item.name, item.download_url + elseif item.type == "dir" then + return item.name, generateTree(item.url) + end end - local response,sErr,errResponse = http.get(sURL, authenticate) - httpError(response,sErr,errResponse) + + local response, sErr, errResponse = http.get(sURL, authenticate) + httpError(response, sErr, errResponse) + local tData = getJSON(response) - local tTree = { } - for _,v in pairs(tData) do - local sName,tItem = convertItem(v) - -- Filter stuff that is not needed - if not (sName:sub(1,1) == '.' or sName:find(".md")) then - tTree[sName] = tItem - end + local tTree = {} + + for _, v in pairs(tData) do + local sName, tItem = convertItem(v) + -- Filter stuff that is not needed + if not (sName:sub(1, 1) == '.' or sName:find(".md")) then + tTree[sName] = tItem + end end return tTree end local function downloadBlob(sURL, sPath) - local response,sErr,errResponse = http.get(sURL, authenticate) - if not httpError(response,sErr,errResponse) then + local response, sErr, errResponse = http.get(sURL, authenticate) + if not httpError(response, sErr, errResponse) then return false end local sData = response.readAll() response.close() - local file = fs.open(sPath, 'w') - file.write(sData) - file.close() + local blobFile = fs.open(sPath, 'w') + blobFile.write(sData) + blobFile.close() return true end local theme = generateTree(name) - local function downloadItems(tree,sPath) + local function downloadItems(tree, sPath) sleep(0.3) - for name,item in pairs(tree) do - local nextPath = fs.combine(sPath,name) + + for treeItemName, item in pairs(tree) do + local nextPath = fs.combine(sPath, treeItemName) if type(item) == "table" then - downloadItems(item,nextPath) + downloadItems(item, nextPath) else - downloadBlob(item,nextPath) + downloadBlob(item, nextPath) end end end - local path = fs.combine(installation,"data","pages") + local path = fs.combine(installation, "data", "pages") fs.delete(path) downloadItems(theme, path) end - -elseif tArgs[1] == "--version" or tArgs[1] == "-v" then - print("Kristify v"..version) +elseif args[1] == "--version" or args[1] == "-v" then + print("Kristify v" .. version) term.write("GitHub: Kristify/Kristify made with ") term.setTextColor(colors.red) print("\003") term.setTextColor(colors.white) - -elseif tArgs[1] == "--update" or tArgs[1] == "-u" then - local path = fs.combine(installation,"data") +elseif args[1] == "--update" or args[1] == "-u" then + local path = fs.combine(installation, "data") if fs.exists(path) then fs.delete(".kristify_data_backup") fs.copy(path, ".kristify_data_backup") @@ -168,42 +187,44 @@ error("Holdup. How- eh whatever. You need the http API!") end - local authenticate = _G._GIT_API_KEY and {Authorization = "Bearer ".._G._GIT_API_KEY} - local response,err,errResp = http.get("https://raw.githubusercontent.com/Kristify/kristify/main/installer.lua",authenticate) + local authenticate = _G._GIT_API_KEY and { Authorization = "Bearer " .. _G._GIT_API_KEY } + local response, err, errResp = http.get("https://raw.githubusercontent.com/Kristify/kristify/main/installer.lua", + authenticate) if not response then - error("Couldn't get the install script! Reason: \'"..err.."\' (code "..errResp.getResponseCode()..')') + error("Couldn't get the install script! Reason: \'" .. err .. "\' (code " .. errResp.getResponseCode() .. ')') end local content = response.readAll() response.close() - local path = load(content, "install",'t',_ENV)() + local path = load(content, "install", 't', _ENV)() if fs.exists(".kristify_data_backup") then - fs.delete(fs.combine(path,"data")) - fs.copy(".kristify_data_backup",fs.combine(path,"data")) + fs.delete(fs.combine(path, "data")) + fs.copy(".kristify_data_backup", fs.combine(path, "data")) fs.delete(".kristify_data_backup") end - -elseif tArgs[1] == "--storage" or tArgs[1] == "-s" then +elseif args[1] == "--storage" or args[1] == "-s" then os.queueEvent("kstUpdateProducts") - -elseif tArgs[1] == "--exit" or tArgs[1] == "-e" then + print("Requested storage update.") + os.pullEvent("kristify:storageRefreshed") + print("Refreshed storage.") +elseif args[1] == "--exit" or args[1] == "-e" then os.queueEvent("kristify:exit") - -elseif tArgs[1] == "--nbt" or tArgs[1] == "-n" then + print("Requested kristify exit") +elseif args[1] == "--nbt" or args[1] == "-n" then print("NBT Hash of item #1: ") local data = turtle.getItemDetail(1, true) assert(data, "No data gotten from slot one") print(data.nbt or "No NBT data. Leave the field to `nil` or don't define it.") -elseif tArgs[1] == "--help" or tArgs[1] == "-h" then - print("Usage: "..(tArgs[0] or "kristify.lua").." [flag:]") - print("-u","--update","Updates Kristify.") - print("-v","--version","Shoes the current version.") - print("-t [name]","--theme","Shows or installs a given theme.") +elseif args[1] == "--help" or args[1] == "-h" then + print("Usage: " .. (args[0] or "kristify.lua") .. " [flag:]") + print("-u", "--update", "Updates Kristify.") + print("-v", "--version", "Shoes the current version.") + print("-t [name]", "--theme", "Shows or installs a given theme.") print("-s", "--storage", "Updates the storage.") print("-e", "--exit", "Stops the shop") print("-n", "--nbt", "Gets the NBT hash of the item in slot one")