mirror of
https://codeberg.org/tacerus/teddit.git
synced 2024-11-22 14:59:26 +01:00
add dark theme and preferences
This commit is contained in:
parent
3edde76303
commit
5e52297481
3
app.js
3
app.js
@ -42,6 +42,7 @@ const pug = require('pug')
|
||||
const path = require('path')
|
||||
const compression = require('compression')
|
||||
const express = require('express')
|
||||
const cookieParser = require('cookie-parser')
|
||||
const r = require('redis')
|
||||
const redis = r.createClient()
|
||||
const helmet = require('helmet')
|
||||
@ -86,6 +87,8 @@ if(use_compression) {
|
||||
app.use(compression())
|
||||
}
|
||||
|
||||
app.use(cookieParser())
|
||||
|
||||
if(use_view_cache) {
|
||||
app.set('view cache', true)
|
||||
}
|
||||
|
257
dist/css/styles.css
vendored
257
dist/css/styles.css
vendored
@ -2,7 +2,10 @@
|
||||
--sm-font: 0.666rem;
|
||||
--lightgray: #f5f5f5;
|
||||
--whitebg: #ffffff;
|
||||
--darkbg: #0F0F0F;
|
||||
--darkbglight: #252525;
|
||||
--linkcolor: #000bac;
|
||||
--darklinkcolor: #599bff;
|
||||
--graytext: #6f6f6f;
|
||||
}
|
||||
* {
|
||||
@ -10,6 +13,200 @@
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
/* Move themes to the beginning of the file to avoid themes flickering. */
|
||||
/* DARK THEME */
|
||||
body.dark {
|
||||
background: var(--darkbg);
|
||||
color: #cacaca;
|
||||
}
|
||||
body.dark nav {
|
||||
background: #1f1f1f;
|
||||
}
|
||||
body.dark .top-links a {
|
||||
background: var(--darkbg);
|
||||
color: #bfbfbf;
|
||||
}
|
||||
body.dark header {
|
||||
background: var(--darkbglight);
|
||||
color: #f1f1f1;
|
||||
}
|
||||
body.dark #post header div a {
|
||||
color: var(--darklinkcolor);
|
||||
text-decoration: none;
|
||||
}
|
||||
body.dark a {
|
||||
color: #f5f5f5;
|
||||
}
|
||||
body.dark a:hover, body.dark a:focus {
|
||||
color: #3d8aff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
body.dark #post header div a:hover,
|
||||
body.dark #post header div a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
body.dark input[type="submit"]:hover,
|
||||
body.dark input[type="submit"]:focus,
|
||||
body.dark .btn:hover,
|
||||
body.dark .btn:focus {
|
||||
background: white;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
body.dark form legend {
|
||||
border-bottom: 1px solid #353535;
|
||||
}
|
||||
body.dark #post .title a {
|
||||
color: var(--darklinkcolor);
|
||||
}
|
||||
body.dark #post .submitted {
|
||||
color: #a5a5a5;
|
||||
}
|
||||
body.dark #post .usertext-body {
|
||||
background: #0a0a0a;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
body.dark #post .infobar {
|
||||
background-color: #d2d2d2;
|
||||
color: #2f2f2f;
|
||||
}
|
||||
body.dark #post .infobar a {
|
||||
color: #0356d4;
|
||||
}
|
||||
body.dark header .tabmenu li a {
|
||||
background: #3e3e3e;
|
||||
}
|
||||
body.dark header .tabmenu li a:hover, body.dark header .tabmenu li a:focus {
|
||||
text-decoration: underline;
|
||||
color: white;
|
||||
}
|
||||
body.dark #search {
|
||||
color: #d2d2d2;
|
||||
}
|
||||
body.dark .md {
|
||||
color: #dadada;
|
||||
}
|
||||
body.dark .md blockquote, body.dark .md del {
|
||||
color: #777777;
|
||||
}
|
||||
body.dark .md code, body.dark .md pre {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
body.dark .comment .body blockquote {
|
||||
background: #313131;
|
||||
color: #afafaf;
|
||||
border-color: #464646;
|
||||
}
|
||||
body.dark .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
border-left: 1px solid #545454;
|
||||
}
|
||||
body.dark .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
/* Is there any better way to do this??? send help naow */
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbg);
|
||||
}
|
||||
body.dark .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--darkbglight);
|
||||
}
|
||||
body.dark .comment .meta .created a {
|
||||
color: #7b7b7b;
|
||||
}
|
||||
body.dark .comment details summary {
|
||||
color: #868686;
|
||||
}
|
||||
body.dark .comment details summary::-webkit-details-marker,
|
||||
body.dark .comment details summary::marker {
|
||||
color: #868686;
|
||||
}
|
||||
body.dark #links .link .entry .title a h2 {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
body.dark #links .link .image .no-image,
|
||||
body.dark #user .entry .image .no-image {
|
||||
filter: opacity(0.5);
|
||||
}
|
||||
body.dark #links .link .upvotes {
|
||||
color: #858585;
|
||||
}
|
||||
body.dark .upvotes .arrow,
|
||||
body.dark .score .arrow {
|
||||
filter: opacity(0.5);
|
||||
}
|
||||
body.dark #links .link .entry .meta a {
|
||||
color: #c7c7c7;
|
||||
}
|
||||
body.dark .content .bottom img {
|
||||
filter: invert(1);
|
||||
}
|
||||
body.dark .container .content {
|
||||
border: 1px solid #5e5e5e;
|
||||
}
|
||||
body.dark input[type="submit"],
|
||||
body.dark .btn {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
a {
|
||||
color: var(--linkcolor);
|
||||
text-decoration: none;
|
||||
@ -33,7 +230,7 @@ a:hover, a:focus {
|
||||
background: url(/css/sprite.png?v=1);
|
||||
background-position: -84px -1654px;
|
||||
background-repeat: no-repeat;
|
||||
margin: 4px 0px 0px 0px;
|
||||
margin: 2px 0px 2px 0px;
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
display: block;
|
||||
@ -121,6 +318,15 @@ nav .settings a:hover,nav .settings a:focus {
|
||||
line-height: 1.4;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
form legend {
|
||||
border-bottom: 1px solid #e3e3e3;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.container .content p.notice {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.container .content p.version {
|
||||
text-align: right;
|
||||
color: #4f4f4f;
|
||||
@ -137,7 +343,7 @@ header {
|
||||
width: 100%;
|
||||
padding-top: 15px;
|
||||
margin-bottom: 21px;
|
||||
margin-top: 14px;
|
||||
margin-top: 2px;
|
||||
background: gainsboro;
|
||||
}
|
||||
header a {
|
||||
@ -196,7 +402,27 @@ header .tabmenu li.active a {
|
||||
border-radius: 3px;
|
||||
font-weight: bold;
|
||||
}
|
||||
/*SUBREDDIT LINKS*/
|
||||
input[type="submit"],
|
||||
.btn {
|
||||
padding: 3px;
|
||||
margin-top: 7px;
|
||||
margin-right: 10px;
|
||||
border-radius: 0px;
|
||||
border: 1px solid #a5a5a5;
|
||||
background: white;
|
||||
color: #464646;
|
||||
font-size: 13px;
|
||||
}
|
||||
input[type="submit"]:focus,
|
||||
input[type="submit"]:hover,
|
||||
.btn:focus,
|
||||
.btn:hover {
|
||||
background: #4c4c4c;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
/* SUBREDDIT LINKS */
|
||||
#links {
|
||||
float: left;
|
||||
width: 100%;
|
||||
@ -327,7 +553,7 @@ header .tabmenu li.active a {
|
||||
#links.search .link .meta a.comments {
|
||||
margin-left: 0px;
|
||||
}
|
||||
/*COMMENTS*/
|
||||
/* COMMENTS */
|
||||
.comment {
|
||||
font-size: 0.83rem;
|
||||
}
|
||||
@ -473,7 +699,7 @@ header .tabmenu li.active a {
|
||||
.comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment .comment {
|
||||
background: var(--lightgray);
|
||||
}
|
||||
/*POST*/
|
||||
/* POST */
|
||||
#post .info {
|
||||
float: left;
|
||||
width: 100%;
|
||||
@ -635,7 +861,7 @@ header .tabmenu li.active a {
|
||||
#post .gallery .item small {
|
||||
font-size: 10px;
|
||||
}
|
||||
/*USER*/
|
||||
/* USER */
|
||||
#user .entries {
|
||||
float: left;
|
||||
width: 80%;
|
||||
@ -804,7 +1030,7 @@ header .tabmenu li.active a {
|
||||
#user .entries .entry a.context {
|
||||
margin-right: 10px;
|
||||
}
|
||||
/*SEARCH*/
|
||||
/* SEARCH */
|
||||
#search {
|
||||
margin-left: 30px;
|
||||
margin-bottom: 50px;
|
||||
@ -841,20 +1067,7 @@ header .tabmenu li.active a {
|
||||
border-radius: 0px;
|
||||
margin-bottom: 11px;
|
||||
}
|
||||
#search input[type="submit"] {
|
||||
padding: 3px;
|
||||
margin-top: 7px;
|
||||
border-radius: 0px;
|
||||
border: 1px solid #a5a5a5;
|
||||
background: white;
|
||||
color: #464646;
|
||||
}
|
||||
#search input[type="submit"]:focus, #search input[type="submit"]:hover {
|
||||
background: #4c4c4c;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
/*REDDIT STYLES*/
|
||||
/* REDDIT STYLES */
|
||||
.md .md-spoiler-text {
|
||||
border-radius:2px;
|
||||
transition:background ease-out 1s;
|
||||
@ -1065,7 +1278,7 @@ code {
|
||||
font-size:1em;
|
||||
line-height:1.25em;
|
||||
}
|
||||
/*Fix spoiler texts not showing without JS*/
|
||||
/* Fix spoiler texts not showing without JS */
|
||||
.md .md-spoiler-text:not(.revealed):active,.md .md-spoiler-text:not(.revealed):focus,.md .md-spoiler-text:not(.revealed):hover {
|
||||
color: black;
|
||||
background: #fff0;
|
||||
|
95
node_modules/cookie-parser/HISTORY.md
generated
vendored
Normal file
95
node_modules/cookie-parser/HISTORY.md
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
1.4.5 / 2020-03-14
|
||||
==================
|
||||
|
||||
* deps: cookie@0.4.0
|
||||
|
||||
1.4.4 / 2019-02-12
|
||||
==================
|
||||
|
||||
* perf: normalize `secret` argument only once
|
||||
|
||||
1.4.3 / 2016-05-26
|
||||
==================
|
||||
|
||||
* deps: cookie@0.3.1
|
||||
- perf: use for loop in parse
|
||||
|
||||
1.4.2 / 2016-05-20
|
||||
==================
|
||||
|
||||
* deps: cookie@0.2.4
|
||||
- perf: enable strict mode
|
||||
- perf: use for loop in parse
|
||||
- perf: use string concatenation for serialization
|
||||
|
||||
1.4.1 / 2016-01-11
|
||||
==================
|
||||
|
||||
* deps: cookie@0.2.3
|
||||
* perf: enable strict mode
|
||||
|
||||
1.4.0 / 2015-09-18
|
||||
==================
|
||||
|
||||
* Accept array of secrets in addition to a single secret
|
||||
* Fix `JSONCookie` to return `undefined` for non-string arguments
|
||||
* Fix `signedCookie` to return `undefined` for non-string arguments
|
||||
* deps: cookie@0.2.2
|
||||
|
||||
1.3.5 / 2015-05-19
|
||||
==================
|
||||
|
||||
* deps: cookie@0.1.3
|
||||
- Slight optimizations
|
||||
|
||||
1.3.4 / 2015-02-15
|
||||
==================
|
||||
|
||||
* deps: cookie-signature@1.0.6
|
||||
|
||||
1.3.3 / 2014-09-05
|
||||
==================
|
||||
|
||||
* deps: cookie-signature@1.0.5
|
||||
|
||||
1.3.2 / 2014-06-26
|
||||
==================
|
||||
|
||||
* deps: cookie-signature@1.0.4
|
||||
- fix for timing attacks
|
||||
|
||||
1.3.1 / 2014-06-17
|
||||
==================
|
||||
|
||||
* actually export `signedCookie`
|
||||
|
||||
1.3.0 / 2014-06-17
|
||||
==================
|
||||
|
||||
* add `signedCookie` export for single cookie unsigning
|
||||
|
||||
1.2.0 / 2014-06-17
|
||||
==================
|
||||
|
||||
* export parsing functions
|
||||
* `req.cookies` and `req.signedCookies` are now plain objects
|
||||
* slightly faster parsing of many cookies
|
||||
|
||||
1.1.0 / 2014-05-12
|
||||
==================
|
||||
|
||||
* Support for NodeJS version 0.8
|
||||
* deps: cookie@0.1.2
|
||||
- Fix for maxAge == 0
|
||||
- made compat with expires field
|
||||
- tweak maxAge NaN error message
|
||||
|
||||
1.0.1 / 2014-02-20
|
||||
==================
|
||||
|
||||
* add missing dependencies
|
||||
|
||||
1.0.0 / 2014-02-15
|
||||
==================
|
||||
|
||||
* Genesis from `connect`
|
23
node_modules/cookie-parser/LICENSE
generated
vendored
Normal file
23
node_modules/cookie-parser/LICENSE
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
|
||||
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
102
node_modules/cookie-parser/README.md
generated
vendored
Normal file
102
node_modules/cookie-parser/README.md
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
# cookie-parser
|
||||
|
||||
[![NPM Version][npm-version-image]][npm-url]
|
||||
[![NPM Downloads][npm-downloads-image]][npm-url]
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
Parse `Cookie` header and populate `req.cookies` with an object keyed by the
|
||||
cookie names. Optionally you may enable signed cookie support by passing a
|
||||
`secret` string, which assigns `req.secret` so it may be used by other
|
||||
middleware.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ npm install cookie-parser
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var express = require('express')
|
||||
var cookieParser = require('cookie-parser')
|
||||
|
||||
var app = express()
|
||||
app.use(cookieParser())
|
||||
```
|
||||
|
||||
### cookieParser(secret, options)
|
||||
|
||||
- `secret` a string or array used for signing cookies. This is optional and if
|
||||
not specified, will not parse signed cookies. If a string is provided, this
|
||||
is used as the secret. If an array is provided, an attempt will be made to
|
||||
unsign the cookie with each secret in order.
|
||||
- `options` an object that is passed to `cookie.parse` as the second option. Se
|
||||
[cookie](https://www.npmjs.org/package/cookie) for more information.
|
||||
- `decode` a function to decode the value of the cookie
|
||||
|
||||
### cookieParser.JSONCookie(str)
|
||||
|
||||
Parse a cookie value as a JSON cookie. This will return the parsed JSON value
|
||||
if it was a JSON cookie, otherwise, it will return the passed value.
|
||||
|
||||
### cookieParser.JSONCookies(cookies)
|
||||
|
||||
Given an object, this will iterate over the keys and call `JSONCookie` on each
|
||||
value, replacing the original value with the parsed value. This returns the
|
||||
same object that was passed in.
|
||||
|
||||
### cookieParser.signedCookie(str, secret)
|
||||
|
||||
Parse a cookie value as a signed cookie. This will return the parsed unsigned
|
||||
value if it was a signed cookie and the signature was valid. If the value was
|
||||
not signed, the original value is returned. If the value was signed but the
|
||||
signature could not be validated, `false` is returned.
|
||||
|
||||
The `secret` argument can be an array or string. If a string is provided, this
|
||||
is used as the secret. If an array is provided, an attempt will be made to
|
||||
unsign the cookie with each secret in order.
|
||||
|
||||
### cookieParser.signedCookies(cookies, secret)
|
||||
|
||||
Given an object, this will iterate over the keys and check if any value is a
|
||||
signed cookie. If it is a signed cookie and the signature is valid, the key
|
||||
will be deleted from the object and added to the new object that is returned.
|
||||
|
||||
The `secret` argument can be an array or string. If a string is provided, this
|
||||
is used as the secret. If an array is provided, an attempt will be made to
|
||||
unsign the cookie with each secret in order.
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
var express = require('express')
|
||||
var cookieParser = require('cookie-parser')
|
||||
|
||||
var app = express()
|
||||
app.use(cookieParser())
|
||||
|
||||
app.get('/', function (req, res) {
|
||||
// Cookies that have not been signed
|
||||
console.log('Cookies: ', req.cookies)
|
||||
|
||||
// Cookies that have been signed
|
||||
console.log('Signed Cookies: ', req.signedCookies)
|
||||
})
|
||||
|
||||
app.listen(8080)
|
||||
|
||||
// curl command that sends an HTTP request with two cookies
|
||||
// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
|
||||
```
|
||||
|
||||
### [MIT Licensed](LICENSE)
|
||||
|
||||
[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
|
||||
[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
|
||||
[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
|
||||
[npm-url]: https://npmjs.org/package/cookie-parser
|
||||
[npm-version-image]: https://badgen.net/npm/v/cookie-parser
|
||||
[travis-image]: https://badgen.net/travis/expressjs/cookie-parser/master
|
||||
[travis-url]: https://travis-ci.org/expressjs/cookie-parser
|
182
node_modules/cookie-parser/index.js
generated
vendored
Normal file
182
node_modules/cookie-parser/index.js
generated
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
/*!
|
||||
* cookie-parser
|
||||
* Copyright(c) 2014 TJ Holowaychuk
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var cookie = require('cookie')
|
||||
var signature = require('cookie-signature')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = cookieParser
|
||||
module.exports.JSONCookie = JSONCookie
|
||||
module.exports.JSONCookies = JSONCookies
|
||||
module.exports.signedCookie = signedCookie
|
||||
module.exports.signedCookies = signedCookies
|
||||
|
||||
/**
|
||||
* Parse Cookie header and populate `req.cookies`
|
||||
* with an object keyed by the cookie names.
|
||||
*
|
||||
* @param {string|array} [secret] A string (or array of strings) representing cookie signing secret(s).
|
||||
* @param {Object} [options]
|
||||
* @return {Function}
|
||||
* @public
|
||||
*/
|
||||
|
||||
function cookieParser (secret, options) {
|
||||
var secrets = !secret || Array.isArray(secret)
|
||||
? (secret || [])
|
||||
: [secret]
|
||||
|
||||
return function cookieParser (req, res, next) {
|
||||
if (req.cookies) {
|
||||
return next()
|
||||
}
|
||||
|
||||
var cookies = req.headers.cookie
|
||||
|
||||
req.secret = secrets[0]
|
||||
req.cookies = Object.create(null)
|
||||
req.signedCookies = Object.create(null)
|
||||
|
||||
// no cookies
|
||||
if (!cookies) {
|
||||
return next()
|
||||
}
|
||||
|
||||
req.cookies = cookie.parse(cookies, options)
|
||||
|
||||
// parse signed cookies
|
||||
if (secrets.length !== 0) {
|
||||
req.signedCookies = signedCookies(req.cookies, secrets)
|
||||
req.signedCookies = JSONCookies(req.signedCookies)
|
||||
}
|
||||
|
||||
// parse JSON cookies
|
||||
req.cookies = JSONCookies(req.cookies)
|
||||
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON cookie string.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Object} Parsed object or undefined if not json cookie
|
||||
* @public
|
||||
*/
|
||||
|
||||
function JSONCookie (str) {
|
||||
if (typeof str !== 'string' || str.substr(0, 2) !== 'j:') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(str.slice(2))
|
||||
} catch (err) {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON cookies.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
* @public
|
||||
*/
|
||||
|
||||
function JSONCookies (obj) {
|
||||
var cookies = Object.keys(obj)
|
||||
var key
|
||||
var val
|
||||
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
key = cookies[i]
|
||||
val = JSONCookie(obj[key])
|
||||
|
||||
if (val) {
|
||||
obj[key] = val
|
||||
}
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a signed cookie string, return the decoded value.
|
||||
*
|
||||
* @param {String} str signed cookie string
|
||||
* @param {string|array} secret
|
||||
* @return {String} decoded value
|
||||
* @public
|
||||
*/
|
||||
|
||||
function signedCookie (str, secret) {
|
||||
if (typeof str !== 'string') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (str.substr(0, 2) !== 's:') {
|
||||
return str
|
||||
}
|
||||
|
||||
var secrets = !secret || Array.isArray(secret)
|
||||
? (secret || [])
|
||||
: [secret]
|
||||
|
||||
for (var i = 0; i < secrets.length; i++) {
|
||||
var val = signature.unsign(str.slice(2), secrets[i])
|
||||
|
||||
if (val !== false) {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse signed cookies, returning an object containing the decoded key/value
|
||||
* pairs, while removing the signed key from obj.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {string|array} secret
|
||||
* @return {Object}
|
||||
* @public
|
||||
*/
|
||||
|
||||
function signedCookies (obj, secret) {
|
||||
var cookies = Object.keys(obj)
|
||||
var dec
|
||||
var key
|
||||
var ret = Object.create(null)
|
||||
var val
|
||||
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
key = cookies[i]
|
||||
val = obj[key]
|
||||
dec = signedCookie(val, secret)
|
||||
|
||||
if (val !== dec) {
|
||||
ret[key] = dec
|
||||
delete obj[key]
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
85
node_modules/cookie-parser/package.json
generated
vendored
Normal file
85
node_modules/cookie-parser/package.json
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
{
|
||||
"_from": "cookie-parser",
|
||||
"_id": "cookie-parser@1.4.5",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
|
||||
"_location": "/cookie-parser",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "cookie-parser",
|
||||
"name": "cookie-parser",
|
||||
"escapedName": "cookie-parser",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
|
||||
"_shasum": "3e572d4b7c0c80f9c61daf604e4336831b5d1d49",
|
||||
"_spec": "cookie-parser",
|
||||
"_where": "/home/teddit/site",
|
||||
"author": {
|
||||
"name": "TJ Holowaychuk",
|
||||
"email": "tj@vision-media.ca",
|
||||
"url": "http://tjholowaychuk.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/expressjs/cookie-parser/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Douglas Christopher Wilson",
|
||||
"email": "doug@somethingdoug.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Parse HTTP request cookies",
|
||||
"devDependencies": {
|
||||
"eslint": "6.8.0",
|
||||
"eslint-config-standard": "14.1.0",
|
||||
"eslint-plugin-import": "2.20.1",
|
||||
"eslint-plugin-markdown": "1.0.2",
|
||||
"eslint-plugin-node": "11.0.0",
|
||||
"eslint-plugin-promise": "4.2.1",
|
||||
"eslint-plugin-standard": "4.0.1",
|
||||
"istanbul": "0.4.5",
|
||||
"mocha": "7.1.0",
|
||||
"supertest": "4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"HISTORY.md",
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/expressjs/cookie-parser#readme",
|
||||
"keywords": [
|
||||
"cookie",
|
||||
"middleware"
|
||||
],
|
||||
"license": "MIT",
|
||||
"name": "cookie-parser",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/expressjs/cookie-parser.git"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --plugin markdown --ext js,md .",
|
||||
"test": "mocha --reporter spec --bail --check-leaks test/",
|
||||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
|
||||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
|
||||
},
|
||||
"version": "1.4.5"
|
||||
}
|
11
package-lock.json
generated
11
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "teddit",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -233,6 +233,15 @@
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||
},
|
||||
"cookie-parser": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
|
||||
"integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
|
||||
"requires": {
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6"
|
||||
}
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
|
@ -5,6 +5,7 @@
|
||||
"main": "app.js",
|
||||
"dependencies": {
|
||||
"compression": "^1.7.4",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"express": "^4.17.1",
|
||||
"fs": "^0.0.1-security",
|
||||
"helmet": "^4.2.0",
|
||||
|
161
routes.js
161
routes.js
@ -29,7 +29,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error('Error getting the frontpage key from redis.', error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log('Got frontpage key from redis.');
|
||||
@ -38,7 +38,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
return res.render('index', {
|
||||
json: processed_json,
|
||||
sortby: 'hot',
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
} else {
|
||||
@ -50,7 +51,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.setex(key, setexs.frontpage, JSON.stringify(json), (error) => {
|
||||
if(error) {
|
||||
console.error('Error setting the frontpage key to redis.', error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
console.log('Fetched the frontpage from reddit API.');
|
||||
(async () => {
|
||||
@ -58,7 +59,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
return res.render('index', {
|
||||
json: processed_json,
|
||||
sortby: 'hot',
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
}
|
||||
@ -67,7 +69,11 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
} else {
|
||||
console.error(`Something went wrong while fetching data from reddit API. ${result.status} – ${result.statusText}`)
|
||||
console.error(reddit_api_error_text)
|
||||
return res.render('index', { json: null, http_status_code: result.status })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('Error fetching the frontpage JSON file.', error)
|
||||
@ -77,11 +83,16 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
})
|
||||
|
||||
app.get('/about', (req, res, next) => {
|
||||
return res.render('about')
|
||||
return res.render('about', { user_preferences: req.cookies })
|
||||
})
|
||||
|
||||
app.get('/preferences', (req, res, next) => {
|
||||
return res.render('preferences')
|
||||
return res.render('preferences', { user_preferences: req.cookies })
|
||||
})
|
||||
|
||||
app.get('/resetprefs', (req, res, next) => {
|
||||
res.clearCookie('theme')
|
||||
return res.redirect('/preferences')
|
||||
})
|
||||
|
||||
app.get('/search', (req, res, next) => {
|
||||
@ -150,7 +161,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error('Error getting the frontpage with sortby key from redis.', error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log('Got frontpage with sortyby key from redis.');
|
||||
@ -159,7 +170,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
return res.render('index', {
|
||||
json: processed_json,
|
||||
sortby: sortby,
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
} else {
|
||||
@ -171,7 +183,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.setex(key, setexs.frontpage, JSON.stringify(json), (error) => {
|
||||
if(error) {
|
||||
console.error('Error setting the frontpage with sortby key to redis.', error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
console.log('Fetched the frontpage with sortby from reddit API.');
|
||||
(async () => {
|
||||
@ -179,7 +191,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
return res.render('index', {
|
||||
json: processed_json,
|
||||
sortby: sortby,
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
}
|
||||
@ -188,7 +201,11 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
} else {
|
||||
console.error(`Something went wrong while fetching data from reddit API. ${result.status} – ${result.statusText}`)
|
||||
console.error(reddit_api_error_text)
|
||||
return res.render('index', { json: null, http_status_code: result.status })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('Error fetching the frontpage with sortby JSON file.', error)
|
||||
@ -229,7 +246,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error('Error getting the search key from redis.', error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log('Got search key from redis.');
|
||||
@ -242,7 +259,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
nsfw: nsfw,
|
||||
subreddit: subreddit,
|
||||
sortby: sortby,
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
} else {
|
||||
@ -254,7 +272,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.setex(key, setexs.searches, JSON.stringify(json), (error) => {
|
||||
if(error) {
|
||||
console.error('Error setting the searches key to redis.', error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
console.log('Fetched search results from reddit API.');
|
||||
(async () => {
|
||||
@ -266,7 +284,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
nsfw: nsfw,
|
||||
subreddit: subreddit,
|
||||
sortby: sortby,
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
}
|
||||
@ -275,7 +294,11 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
} else {
|
||||
console.error(`Something went wrong while fetching data from reddit API. ${result.status} – ${result.statusText}`)
|
||||
console.error(reddit_api_error_text)
|
||||
return res.render('index', { json: null, http_status_code: result.status })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('Error fetching the frontpage JSON file.', error)
|
||||
@ -323,7 +346,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${subreddit} key from redis.`, error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log(`Got /r/${subreddit} key from redis.`);
|
||||
@ -335,10 +358,16 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
subreddit: subreddit,
|
||||
subreddit_front: (!before && !after) ? true : false,
|
||||
sortby: sortby,
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
} else {
|
||||
return res.render('subreddit', { json: null, error: true, data: processed_json })
|
||||
return res.render('subreddit', {
|
||||
json: null,
|
||||
error: true,
|
||||
data: processed_json,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
})()
|
||||
} else {
|
||||
@ -350,7 +379,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.setex(key, setexs.subreddit, JSON.stringify(json), (error) => {
|
||||
if(error) {
|
||||
console.error(`Error setting the ${subreddit} key to redis.`, error)
|
||||
return res.render('subreddit', { json: null })
|
||||
return res.render('subreddit', { json: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
console.log(`Fetched the JSON from reddit.com/r/${subreddit}.`);
|
||||
(async () => {
|
||||
@ -360,7 +389,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
subreddit: subreddit,
|
||||
subreddit_front: (!before && !after) ? true : false,
|
||||
sortby: sortby,
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
}
|
||||
@ -373,7 +403,11 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
console.error(`Something went wrong while fetching data from reddit API. ${result.status} – ${result.statusText}`)
|
||||
console.error(reddit_api_error_text)
|
||||
}
|
||||
return res.render('index', { json: null, http_status_code: result.status })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error(`Error fetching the JSON file from reddit.com/r/${subreddit}.`, error)
|
||||
@ -402,7 +436,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.get(comments_url, (error, json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${comments_url} key from redis.`, error)
|
||||
return res.render('index', { post: null })
|
||||
return res.render('index', { post: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log(`Got ${comments_url} key from redis.`);
|
||||
@ -415,21 +449,22 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
comments: finalized_json.comments,
|
||||
viewing_comment: viewing_comment,
|
||||
post_url: post_url,
|
||||
subreddit: subreddit
|
||||
subreddit: subreddit,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
} else {
|
||||
let key = `morechildren:${post_url};1`
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${key} key from redis.`, error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log(`Got ${key} key from redis.`);
|
||||
redis.get(post_url, (error, post_json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${post_url} key from redis.`, error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(post_json) {
|
||||
redis.get(`morechildren_ids:${post_url}`, (error, morechildren_ids) => {
|
||||
@ -446,7 +481,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
viewing_comment: false,
|
||||
post_url: post_url,
|
||||
subreddit: req.params.subreddit,
|
||||
more_comments_page: 1
|
||||
more_comments_page: 1,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
})
|
||||
@ -465,7 +501,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.setex(comments_url, setexs.posts, JSON.stringify(json), (error) => {
|
||||
if(error) {
|
||||
console.error(`Error setting the ${comments_url} key to redis.`, error)
|
||||
return res.render('post', { post: null })
|
||||
return res.render('post', { post: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
console.log(`Fetched the JSON from reddit.com${comments_url}.`);
|
||||
(async () => {
|
||||
@ -476,7 +512,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
comments: finalized_json.comments,
|
||||
viewing_comment: viewing_comment,
|
||||
post_url: post_url,
|
||||
subreddit: subreddit
|
||||
subreddit: subreddit,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
}
|
||||
@ -489,7 +526,12 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
console.error(`Something went wrong while fetching data from reddit API. ${result.status} – ${result.statusText}`)
|
||||
console.error(reddit_api_error_text)
|
||||
}
|
||||
return res.render('index', { json: null, http_status_code: result.status, http_statustext: result.statusText })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
http_statustext: result.statusText,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error(`Error fetching the JSON file from reddit.com${comments_url}.`, error)
|
||||
@ -551,7 +593,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the user ${key} key from redis.`, error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log(`Got user ${user} key from redis.`);
|
||||
@ -560,7 +602,8 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
return res.render('user', {
|
||||
data: processed_json,
|
||||
sortby: sortby,
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
} else {
|
||||
@ -579,14 +622,15 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.setex(key, setexs.user, JSON.stringify(user_data), (error) => {
|
||||
if(error) {
|
||||
console.error(`Error setting the user ${key} key to redis.`, error)
|
||||
return res.render('index', { post: null })
|
||||
return res.render('index', { post: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
(async () => {
|
||||
let processed_json = await processJsonUser(user_data, true, after, before)
|
||||
return res.render('user', {
|
||||
data: processed_json,
|
||||
sortby: sortby,
|
||||
past: past
|
||||
past: past,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})()
|
||||
}
|
||||
@ -595,11 +639,19 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
} else {
|
||||
console.error(`Something went wrong while fetching data from reddit API. ${result.status} – ${result.statusText}`)
|
||||
console.error(reddit_api_error_text)
|
||||
return res.render('index', { json: null, http_status_code: result.status })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error(`Error fetching the overview JSON file from reddit.com/u/${user}`, error)
|
||||
return res.render('index', { json: null, http_status_code: result.status })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
@ -609,7 +661,12 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
console.error(`Something went wrong while fetching data from reddit API. ${result.status} – ${result.statusText}`)
|
||||
console.error(reddit_api_error_text)
|
||||
}
|
||||
return res.render('index', { json: null, http_status_code: result.status, http_statustext: result.statusText })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
http_statustext: result.statusText,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error(`Error fetching the about JSON file from reddit.com/u/${user}`, error)
|
||||
@ -623,13 +680,19 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
* POSTS
|
||||
*/
|
||||
|
||||
app.post('/saveprefs', (req, res, next) => {
|
||||
let theme = req.body.theme
|
||||
res.cookie('theme', theme, { maxAge: 900000, httpOnly: true })
|
||||
return res.redirect('/preferences')
|
||||
})
|
||||
|
||||
app.post('/r/:subreddit/comments/:id/:snippet', (req, res, next) => {
|
||||
/* morechildren route */
|
||||
let all_ids = req.body.all_ids
|
||||
let post_url = req.body.url
|
||||
|
||||
if(!all_ids || !post_url || !post_url.startsWith('/r/')) {
|
||||
return res.render('index', null)
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
let post_id = post_url.split('/')[4]
|
||||
let ids_to_show = ''
|
||||
@ -645,7 +708,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${key} key from redis.`, error)
|
||||
return res.render('index', { json: null })
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log(`Redirecting to ${post_url} with cursor...`);
|
||||
@ -661,11 +724,11 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
redis.setex(key, setexs.posts, JSON.stringify(comments), (error) => {
|
||||
if(error) {
|
||||
console.error(`Error setting the ${key} key to redis.`, error)
|
||||
return res.render('post', { post: null })
|
||||
return res.render('post', { post: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
redis.setex(`morechildren_ids:${post_url}`, setexs.posts, JSON.stringify(all_ids))
|
||||
console.log(`Fetched the JSON from reddit API (endpoint "morechildren") with url: ${url}.`);
|
||||
console.log(`Redirecting to ${post_url} with cursor...`);
|
||||
console.log(`Fetched the JSON from reddit API (endpoint "morechildren") with url: ${url}.`)
|
||||
console.log(`Redirecting to ${post_url} with cursor...`)
|
||||
return res.redirect(`${post_url}?cursor=${page}&page=${page}`)
|
||||
}
|
||||
})
|
||||
@ -673,11 +736,19 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
} else {
|
||||
console.error(`Something went wrong while fetching data from reddit API. ${result.status} – ${result.statusText}`)
|
||||
console.error(reddit_api_error_text)
|
||||
return res.render('index', { json: null, http_status_code: result.status })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log(`Error fetching the JSON from reddit API (endpoint "morechildren") with url: ${url}.`, error)
|
||||
return res.render('index', { json: null, http_status_code: result.status })
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -3,7 +3,7 @@ html
|
||||
head
|
||||
title about - teddit
|
||||
include includes/head.pug
|
||||
body
|
||||
body(class=""+ user_preferences.theme +"")
|
||||
include includes/topbar.pug
|
||||
.container
|
||||
.content
|
||||
|
@ -3,7 +3,7 @@ html
|
||||
head
|
||||
title teddit
|
||||
include includes/head.pug
|
||||
body
|
||||
body(class=""+ user_preferences.theme +"")
|
||||
include includes/topbar.pug
|
||||
if json === null
|
||||
h2 error
|
||||
|
@ -3,7 +3,7 @@ html
|
||||
head
|
||||
title #{post.title} : #{subreddit}
|
||||
include includes/head.pug
|
||||
body
|
||||
body(class=""+ user_preferences.theme +"")
|
||||
include includes/topbar.pug
|
||||
if post === null
|
||||
h1 Error occured
|
||||
|
@ -3,9 +3,21 @@ html
|
||||
head
|
||||
title preferences - teddit
|
||||
include includes/head.pug
|
||||
body
|
||||
body(class=""+ user_preferences.theme +"")
|
||||
include includes/topbar.pug
|
||||
.container
|
||||
.content
|
||||
h1 Preferences
|
||||
p nothing here yet
|
||||
form(action="/saveprefs", method="POST")
|
||||
legend Display
|
||||
label(for="theme") Theme:
|
||||
select(id="theme", name="theme")
|
||||
if(!user_preferences.theme || user_preferences.theme == '')
|
||||
option(value="", selected="selected") White
|
||||
option(value="dark") Dark
|
||||
if(user_preferences.theme === 'dark')
|
||||
option(value="") White
|
||||
option(value="dark", selected="selected") Dark
|
||||
p(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
|
||||
|
@ -3,7 +3,7 @@ html
|
||||
head
|
||||
title search results for #{q}
|
||||
include includes/head.pug
|
||||
body
|
||||
body(class=""+ user_preferences.theme +"")
|
||||
include includes/topbar.pug
|
||||
#search
|
||||
form(action="/r/" + subreddit + "/search", method="GET")
|
||||
|
@ -3,7 +3,7 @@ html
|
||||
head
|
||||
title /r/#{subreddit}
|
||||
include includes/head.pug
|
||||
body
|
||||
body(class=""+ user_preferences.theme +"")
|
||||
include includes/topbar.pug
|
||||
if json === null
|
||||
h1 Error occured
|
||||
|
@ -3,7 +3,7 @@ html
|
||||
head
|
||||
title overview for #{data.username}
|
||||
include includes/head.pug
|
||||
body
|
||||
body(class=""+ user_preferences.theme +"")
|
||||
include includes/topbar.pug
|
||||
if user === null
|
||||
h1 Error occured
|
||||
|
Loading…
Reference in New Issue
Block a user