diff --git a/README.md b/README.md index 0500f53..ce15d1f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,6 @@ Community instances: ## TODO -* Import/export preferences * User trophies * "other discussions" feature * "Open on reddit" links diff --git a/routes.js b/routes.js index 75aee11..bc4b978 100644 --- a/routes.js +++ b/routes.js @@ -28,6 +28,42 @@ module.exports = (app, redis, fetch, RedditAPI) => { res.clearCookie('subbed_subreddits') return res.redirect('/preferences') }) + + app.get('/import_prefs/:key', (req, res, next) => { + let key = req.params.key + if(!key) + return res.redirect('/') + if(key.length !== 10) + return res.redirect('/') + + key = `prefs_key:${key}` + redis.get(key, (error, json) => { + if(error) { + console.error(`Error getting the preferences import key ${key} from redis.`, error) + return res.render('index', { json: null, user_preferences: req.cookies }) + } + if(json) { + try { + let prefs = JSON.parse(json) + let subbed_subreddits_is_set = false + for(var setting in prefs) { + if(prefs.hasOwnProperty(setting)) { + res.cookie(setting, prefs[setting], { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) + if(setting === 'subbed_subreddits') + subbed_subreddits_is_set = true + } + } + if(!subbed_subreddits_is_set) + res.clearCookie('subbed_subreddits') + return res.redirect('/preferences') + } catch(e) { + console.error(`Error setting imported preferences to the cookies. Key: ${key}.`, error) + } + } else { + return res.redirect('/preferences') + } + }) + }) app.get('/privacy', (req, res, next) => { return res.render('privacypolicy', { user_preferences: req.cookies }) @@ -1224,6 +1260,19 @@ module.exports = (app, redis, fetch, RedditAPI) => { return res.redirect('/preferences') }) + + app.post('/export_prefs', (req, res, next) => { + let r = `${(Math.random().toString(36)+'00000000000000000').slice(2, 10+2).toUpperCase()}` + let key = `prefs_key:${r}` + redis.set(key, JSON.stringify(req.cookies), (error) => { + if(error) { + console.error(`Error saving preferences to redis.`, error) + return res.redirect('/preferences') + } else { + return res.render('preferences', { user_preferences: req.cookies, instance_config: config, preferences_key: r }) + } + }) + }) app.post('/r/:subreddit/comments/:id/:snippet', (req, res, next) => { /* morechildren route */ diff --git a/static/css/styles.css b/static/css/styles.css index 158cc43..ca23764 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -150,6 +150,12 @@ form .setting { margin: 10px 0; width: 100%; } +#export-form { + margin: 60px 0px 0px 0px; +} +#export-form input { + margin: 10px 0px 10px 0px; +} .container .content small.notice { padding-top: 20px; padding-bottom: 5px; diff --git a/views/preferences.pug b/views/preferences.pug index 4d1169a..1ec6fe2 100644 --- a/views/preferences.pug +++ b/views/preferences.pug @@ -67,4 +67,27 @@ html small(class="notice") Preferences are stored client-side using cookies without any personal information. input(type="submit", value="Save preferences") a(href="/resetprefs", class="btn") Reset preferences + form(action="/export_prefs", method="POST", id="export-form") + if preferences_key + details(open) + summary + span Export preferences + .setting + small By exporting your preferences you can transfer your subscribed subreddits and preferences to another device. Or you could create a bookmark if you tend to delete your cookies frequently. + br + input(type="submit", value="Export preferences") + if preferences_key + - var protocol = 'http' + if instance_config.https_enabled === true + - var protocol = 'https' + p Visit this URL to import your preferences: + a(href=`${protocol}://${instance_config.domain}/import_prefs/${preferences_key}`) #{protocol}://#{instance_config.domain}/import_prefs/#{preferences_key} + else + details + summary + span Export preferences + .setting + small By exporting your preferences you can transfer your subscribed subreddits and preferences to another device. Or you could create a bookmark if you tend to delete your cookies frequently. + br + input(type="submit", value="Export preferences") include includes/footer.pug