forked from ITwrxOrg/Forget-Me-Not
91 lines
4.0 KiB
Nim
91 lines
4.0 KiB
Nim
#[Copyright 2025 ITwrx.
|
|
This file is part of Forget-Me-Not.
|
|
Forget-Me-Not is released under the GNU Affero General Public License 3.0.
|
|
See COPYING or <https://www.gnu.org/licenses/> for details.]#
|
|
|
|
import guildenstern/[epolldispatcher, httpserver], sqliteral
|
|
import "templates/error404.nimf", "templates/error500.nimf", "templates/reminders.nimf", "templates/reminder_create.nimf", "templates/reminder_update.nimf", "templates/login.nimf"
|
|
import helpers/db, helpers/global, helpers/form, helpers/auth
|
|
import models/reminder
|
|
import post_handlers/reminder_post_handler, post_handlers/login_post_handler, post_handlers/send_reminders_post_handler
|
|
|
|
db1.openDatabase(APP_NAME & ".db", [RemindersSchema, UsersSchema, SessionsSchema]);
|
|
var allReminders{.threadvar.}: seq[Reminder]
|
|
|
|
#uncomment, add creds to dev/create_user and compile+run once to add new admin user.
|
|
#import dev/create_user
|
|
#createNewUser()
|
|
|
|
proc handleGet() =
|
|
{.gcsafe.}:
|
|
try:
|
|
let uri = getUri()
|
|
#overwrite cookie in browser when reply is performed, so form won't keep showing old input to this visitor if they don't POST again and also refresh for some reason.
|
|
var cookieHeader: string
|
|
if APP_MODE == "dev":
|
|
cookieHeader = "Set-Cookie: form_result=" & "" & ";" & "HttpOnly;" & "path=/;" & "SameSite=Lax;"
|
|
else:
|
|
cookieHeader = "Set-Cookie: form_result=" & "" & ";" & "HttpOnly;" & "Secure=true;" & "path=/;" & "SameSite=Lax;"
|
|
if uri == "/login":
|
|
reply(loginTemplate(setVisitorCsrfToken(), getCookieFormResult()), [cookieHeader])
|
|
if isAuthdAdmin():
|
|
allReminders = getAllReminders()
|
|
for reminder in allReminders:
|
|
if "/reminder/" & $reminder.id & "/update" == uri:
|
|
reply(reminderUpdateTemplate(reminder.id, getUserPageCsrfToken(), getFormResult()), [cookieHeader])
|
|
case uri:
|
|
of "/":
|
|
reply(remindersTemplate(allReminders, getUserPageCsrfToken(), getFormResult()), [cookieHeader])
|
|
of "/create-reminder":
|
|
reply(reminderCreateTemplate(getUserPageCsrfToken(), getFormResult()), [cookieHeader])
|
|
of "/500":
|
|
reply(error500Template(getUserPageCsrfToken(), getFormResult()), [cookieHeader])
|
|
else:
|
|
reply(error404Template(getUserPageCsrfToken()), [cookieHeader])
|
|
else:
|
|
reply(Http302, [location("/login"), cookieHeader])
|
|
except Exception as e:
|
|
echo e.msg
|
|
|
|
proc handlePost() =
|
|
{.gcsafe.}:
|
|
try:
|
|
let uri = getUri()
|
|
if uri == "/send-reminders":
|
|
sendRemindersPostHandler()
|
|
let fr = getFormResult()
|
|
if uri == "/login":
|
|
if isValidVisitorCsrfToken(formInput("csrf_token")):
|
|
loginPostHandler()
|
|
else:
|
|
discard assignGeneralErrorFR("CSRF Token Validation Failure. Please try again (or report successive failures).")
|
|
setFR()
|
|
reply(Http302, [location("/login")])
|
|
else:
|
|
if isAuthdAdminPost():
|
|
if isValidUserCsrfToken(formInput("csrf_token")):
|
|
case uri
|
|
of "/reminder/create":
|
|
reminderCreatePostHandler()
|
|
of "/reminder/update":
|
|
reminderUpdatePostHandler()
|
|
of "/reminder/delete":
|
|
reminderDeletePostHandler()
|
|
else:
|
|
reply(error404Template(getUserPageCsrfToken()), ["Content-Type: text/html"])
|
|
else:
|
|
discard assignGeneralErrorFR("CSRF Token Validation Failure. Please try again (or report successive failures).")
|
|
setFR()
|
|
reply(Http302, [locationBack()])
|
|
else:
|
|
reply(Http302, [location("/login")])
|
|
|
|
except Exception as e:
|
|
echo e.msg
|
|
|
|
let getserver = newHttpServer(handleGet, headerfields = ["cookie", "cookie"])
|
|
let postserver = newHttpServer(handlePost, loglevel = INFO, headerfields = ["origin", "cookie", "referer"])
|
|
if not epolldispatcher.start(getserver, 8096): quit()
|
|
if not epolldispatcher.start(postserver, 8097, threadpoolsize = 20): quit()
|
|
joinThreads(getserver.thread, postserver.thread)
|