202 lines
4.8 KiB
Lua
202 lines
4.8 KiB
Lua
local fs = require "fs"
|
|
local json = require "json"
|
|
local utils = require "./utils"
|
|
local foppy = require "./foppy"
|
|
|
|
local authors = {}
|
|
package.loaded["authors"] = authors
|
|
|
|
do
|
|
authors.from_id = function(id, writeable)
|
|
return foppy.open("database/authors/" .. id .. ".json", writeable)
|
|
end
|
|
|
|
authors.id_from_token = function(token, writeable)
|
|
local data = foppy.open("database/tokens/" .. token .. ".json", writeable)
|
|
if not data then
|
|
print("token doesnt exist", token)
|
|
return nil, 404
|
|
end
|
|
|
|
if data.expires <= os.time() then
|
|
data.dead = true
|
|
return nil, 401
|
|
end
|
|
|
|
if data.dead then
|
|
return nil, 401
|
|
end
|
|
|
|
local exists = fs.existsSync("database/authors/" .. data.of .. ".json")
|
|
if not exists then
|
|
data.dead = true
|
|
return nil, 404
|
|
end
|
|
|
|
return data.of
|
|
end
|
|
|
|
authors.id_from_blog = function(blog, writeable)
|
|
local data = foppy.open("database/blogs/" .. blog .. ".json")
|
|
if not data then
|
|
return nil, 404
|
|
end
|
|
|
|
return data.owner
|
|
end
|
|
|
|
local is_right_password = function(id, password)
|
|
local author, code = authors.from_id(id, true)
|
|
if not author then
|
|
return nil, 404
|
|
end
|
|
|
|
-- check salted password with openssl
|
|
local hashed = utils.hash(author.salt .. password)
|
|
if author.password ~= hashed then
|
|
return nil, 401
|
|
end
|
|
|
|
return author
|
|
end
|
|
|
|
authors.auth = function(id, password)
|
|
local author, code = is_right_password(id, password)
|
|
if not author then
|
|
return nil, code
|
|
end
|
|
|
|
local hash, filename
|
|
repeat
|
|
hash = utils.uuid()
|
|
filename = "database/tokens/" .. hash .. ".json"
|
|
until not fs.existsSync(hash)
|
|
|
|
local token_data = json.encode {
|
|
of = id,
|
|
expires = os.time() + 2628000, -- 4 months, approximately.
|
|
dead = false
|
|
}
|
|
|
|
fs.writeFileSync(filename, token_data)
|
|
|
|
print(#author.tokens, hash)
|
|
author.tokens[#author.tokens + 1] = hash
|
|
|
|
foppy.sync("database/authors/" .. id .. ".json")
|
|
|
|
return hash
|
|
end
|
|
|
|
authors.revoke_all_tokens = function(id, password)
|
|
local author, code = is_right_password(id, password)
|
|
|
|
if not author then
|
|
return nil, code
|
|
end
|
|
|
|
for _, v in ipairs(author.tokens) do
|
|
local f = "database/tokens/" .. v .. ".json"
|
|
local token = foppy.open(f, true)
|
|
token.dead = true
|
|
foppy.sync(f, true)
|
|
end
|
|
|
|
author.tokens = {}
|
|
|
|
foppy.sync("database/authors/" .. id .. ".json")
|
|
end
|
|
|
|
authors.change_password = function(id, password, new_password)
|
|
local author, code = is_right_password(id, password)
|
|
|
|
if not author then
|
|
return nil, code
|
|
end
|
|
|
|
author.salt = utils.uuid()
|
|
author.password = utils.data(author.salt .. new_password)
|
|
|
|
foppy.sync("database/authors/" .. id .. ".json")
|
|
end
|
|
|
|
authors.get_available_id = function()
|
|
local id
|
|
repeat
|
|
id = utils.pin()
|
|
until not fs.existsSync("database/authors/" .. id .. ".json")
|
|
|
|
return id
|
|
end
|
|
|
|
authors.create_account = function(password)
|
|
local id = authors.get_available_id()
|
|
local salt = utils.uuid()
|
|
|
|
local account_data = json.encode {
|
|
blogs = {},
|
|
password = utils.hash(salt .. password),
|
|
salt = salt,
|
|
tokens = {}
|
|
}
|
|
|
|
fs.writeFileSync(
|
|
"database/authors/" .. id .. ".json",
|
|
account_data
|
|
)
|
|
|
|
return id
|
|
end
|
|
end
|
|
|
|
|
|
local blogs = {}
|
|
package.loaded["blogs"] = blogs
|
|
|
|
do
|
|
blogs.from_handle = function(handle)
|
|
return foppy.open(
|
|
"database/blogs/" .. handle .. ".json"
|
|
)
|
|
end
|
|
|
|
blogs.new_blog = function(id, handle, title, description)
|
|
assert(handle)
|
|
if blogs.from_handle(handle) then
|
|
return nil, "blog_already_exists"
|
|
end
|
|
|
|
local author = authors.from_id(id, true)
|
|
assert(author)
|
|
|
|
if not utils.is_valid_handle(handle) then
|
|
return nil, "blog_handle_invalid"
|
|
end
|
|
|
|
local blog = {
|
|
owner = id,
|
|
title = title or handle,
|
|
handle = handle,
|
|
description = description,
|
|
banner = { source = nil, alt = nil },
|
|
index = {},
|
|
|
|
created_at = os.time(),
|
|
updated_at = os.time()
|
|
}
|
|
|
|
fs.writeFileSync(
|
|
"database/blogs/" .. handle .. ".json",
|
|
json.encode(blog)
|
|
)
|
|
|
|
author.blogs[#author.blogs + 1] = handle
|
|
|
|
return blog
|
|
end
|
|
end
|
|
|
|
return {
|
|
authors = authors,
|
|
blogs = blogs,
|
|
}
|