diff --git a/src/lib/constants.js b/src/lib/constants.js index 5b541d1..beaed1a 100644 --- a/src/lib/constants.js +++ b/src/lib/constants.js @@ -68,6 +68,45 @@ let constants = { feed_disabled_max_age: 2*24*60*60 // 2 days }, + user_settings: [ + { + name: "language", + default: "English (International)", + boolean: false, + replaceEmptyWithDefault: true // set this to false if the control is a checkbox and is not disabled + },{ + name: "show_comments", + default: "", + boolean: true, + replaceEmptyWithDefault: true + },{ + name: "link_hashtags", + default: "", + boolean: true, + replaceEmptyWithDefault: true + },{ + name: "spa", + default: "on", + boolean: true, + replaceEmptyWithDefault: true + },{ + name: "theme", + default: "Classic", + boolean: false, + replaceEmptyWithDefault: true + },{ + name: "caption_side", + default: "Left (Bibliogram)", + boolean: false, + replaceEmptyWithDefault: true + },{ + name: "display_alt", + default: "", + boolean: true, + replaceEmptyWithDefault: true + } + ], + settings: { enable_updater_page: false }, @@ -161,7 +200,7 @@ let constants = { additional_routes: [], - database_version: 3 + database_version: 4 } // Override values from config and export the result diff --git a/src/lib/utils/upgradedb.js b/src/lib/utils/upgradedb.js index 5cc95e6..1416f07 100644 --- a/src/lib/utils/upgradedb.js +++ b/src/lib/utils/upgradedb.js @@ -47,9 +47,20 @@ const deltas = new Map([ db.prepare("CREATE TABLE RequestHistory (type TEXT NOT NULL, success INTEGER NOT NULL, timestamp INTEGER NOT NULL)") .run() })() + }], + // version 3 to version 4 + [4, function() { + db.transaction(() => { + db.prepare("DROP TABLE IF EXISTS UserSettings") + .run() + db.prepare( + "CREATE TABLE UserSettings (token TEXT NOT NULL, created INTEGER NOT NULL, language TEXT NOT NULL, show_comments INTEGER NOT NULL, link_hashtags INTEGER NOT NULL" + +", spa INTEGER NOT NULL, theme TEXT NOT NULL, caption_side TEXT NOT NULL, display_alt INTEGER NOT NULL" + +", PRIMARY KEY (token))" + ) + .run() + })() }] - - ]) module.exports = async function() { diff --git a/src/site/api/settings.js b/src/site/api/settings.js new file mode 100644 index 0000000..3a37316 --- /dev/null +++ b/src/site/api/settings.js @@ -0,0 +1,55 @@ +const constants = require("../../lib/constants") +const {render, redirect} = require("pinski/plugins") +const crypto = require("crypto") +const db = require("../../lib/db") + +module.exports = [ + { + route: "/settings", methods: ["GET"], code: async ({url}) => { + const saved = url.searchParams.has("saved") + return render(200, "pug/settings.pug", {saved}) + } + }, + { + route: "/settings", methods: ["POST"], upload: true, code: async ({body}) => { + const params = new URLSearchParams(body.toString()) + const prepared = {} + for (const setting of constants.user_settings) { + let valueOrDefault + if (params.has(setting.name) && params.get(setting.name) !== "") { + valueOrDefault = params.get(setting.name) + } else if (setting.replaceEmptyWithDefault) { + valueOrDefault = setting.default + } else { + valueOrDefault = "" + } + let valueCorrectType + if (setting.boolean) { + valueCorrectType = +(valueOrDefault !== "") + } else { + valueCorrectType = valueOrDefault + } + prepared[setting.name] = valueCorrectType + } + const checkPrepared = db.prepare("SELECT token FROM UserSettings WHERE token = ?") + do { + prepared.token = crypto.randomBytes(16).toString("hex") + } while (checkPrepared.get(prepared.token)) + prepared.created = Date.now() + db.prepare( + "INSERT INTO UserSettings (token, created, language, show_comments, link_hashtags, spa, theme, caption_side, display_alt)" + +" VALUES (@token, @created, @language, @show_comments, @link_hashtags, @spa, @theme, @caption_side, @display_alt)" + ).run(prepared) + const expires = new Date(Date.now() + 4000*24*60*60*1000).toUTCString() + return { + statusCode: 303, + headers: { + "Location": "/settings?saved=1", + "Set-Cookie": `settings=${prepared.token}; Path=/; Expires=${expires}; SameSite=Strict` + }, + contentType: "text/html", + content: "Redirecting..." + } + } + } +] diff --git a/src/site/pug/settings.pug b/src/site/pug/settings.pug index 9f5c191..e8a83b8 100644 --- a/src/site/pug/settings.pug +++ b/src/site/pug/settings.pug @@ -1,3 +1,5 @@ +//- Needs saved + mixin form-component(id, description) .field-row label.description(for=id)= description @@ -33,8 +35,12 @@ html title Settings | Bibliogram include includes/head body.settings-page + if saved + .status-notice Saved. + script. + history.replaceState(null, "", "/settings") main.settings - form(action="/settings" method="post") + form(action="/settings" method="post" enctype="application/x-www-form-urlencoded") h1 Settings +fieldset("Features") diff --git a/src/site/sass/main.sass b/src/site/sass/main.sass index 1c9ca27..de831c0 100644 --- a/src/site/sass/main.sass +++ b/src/site/sass/main.sass @@ -636,15 +636,23 @@ body .settings-page background-color: #fff4e8 - padding: 0px 10px 50px a, a:visited color: $main-theme-link-color .settings + padding: 0px 10px 50px max-width: 600px margin: 0 auto + .status-notice + padding: 15px + font-size: 24px + line-height: 1 + text-align: center + background-color: #0b420b + color: #fff + .action-container margin-top: 20px display: flex