Profile Pictures!

This commit is contained in:
Wingy 2021-09-15 02:41:44 -04:00
parent 8e79266da4
commit 5ac965eac4
19 changed files with 103 additions and 32 deletions

View file

@ -11,6 +11,8 @@ const passport = require('passport')
const fetch = require('node-fetch') const fetch = require('node-fetch')
const express = require('express') const express = require('express')
_CC._ = require('lodash')
const config = require('./config') const config = require('./config')
_CC.config = config _CC.config = config

View file

@ -29,6 +29,7 @@
"express-session": "^1.17.2", "express-session": "^1.17.2",
"get-product-name": "1", "get-product-name": "1",
"jsdom": "^17.0.0", "jsdom": "^17.0.0",
"lodash": "^4.17.20",
"marked": "^3.0.3", "marked": "^3.0.3",
"memdown": "^6.0.0", "memdown": "^6.0.0",
"mkdirp": "^1.0.4", "mkdirp": "^1.0.4",

View file

@ -11,7 +11,7 @@ const SECRET_TOKEN_LIFETIME =
24 * // hours 24 * // hours
7 // days 7 // days
module.exports = (db) => { module.exports = ({ db, ensurePfp }) => {
const router = express.Router() const router = express.Router()
router.get('/', verifyAuth(), (req, res) => { router.get('/', verifyAuth(), (req, res) => {
@ -25,15 +25,16 @@ module.exports = (db) => {
router.post('/add', verifyAuth(), async (req, res) => { router.post('/add', verifyAuth(), async (req, res) => {
if (!req.user.admin) return res.redirect('/') if (!req.user.admin) return res.redirect('/')
const username = req.body.newUserUsername.trim()
await db.put({ await db.put({
_id: req.body.newUserUsername.trim(), _id: username,
admin: false, admin: false,
wishlist: [], wishlist: [],
signupToken: nanoid(SECRET_TOKEN_LENGTH), signupToken: nanoid(SECRET_TOKEN_LENGTH),
expiry: new Date().getTime() + SECRET_TOKEN_LIFETIME expiry: new Date().getTime() + SECRET_TOKEN_LIFETIME
}) })
await ensurePfp(username)
res.redirect(`/admin-settings/edit/${req.body.newUserUsername.trim()}`) res.redirect(`/admin-settings/edit/${req.body.newUserUsername.trim()}`)
}) })

View file

@ -1,8 +1,24 @@
const publicRoute = require('../middlewares/publicRoute') const publicRoute = require('../middlewares/publicRoute')
const express = require('express') const express = require('express')
const path = require('path') const path = require('path')
const fs = require('fs/promises')
module.exports = ({ db, config }) => { module.exports = ({ db, config }) => {
async function ensurePfp (username) {
const user = await db.get(username)
console.log(user)
if (user.pfp) return
const { rows } = await db.allDocs({ include_docs: true })
const unfilteredPool = await fs.readdir('static/img/default-pfps')
const filteredPool = unfilteredPool.filter(file => !rows.find(row => row.doc.pfp === `${_CC.config.base}img/default-pfps/${file}`))
const pool = filteredPool.length ? filteredPool : unfilteredPool
user.pfp = `${_CC.config.base}img/default-pfps/${_CC._.sample(pool)}`
await db.put(user)
}
const router = express.Router() const router = express.Router()
router.use('/', express.static(path.join(__dirname, '../static'))) router.use('/', express.static(path.join(__dirname, '../static')))
@ -26,7 +42,7 @@ module.exports = ({ db, config }) => {
router.use('/setup', require('./setup')(db)) router.use('/setup', require('./setup')(db))
router.use('/login', require('./login')()) router.use('/login', require('./login')({ ensurePfp }))
router.use('/logout', require('./logout')()) router.use('/logout', require('./logout')())
router.use('/resetpw', require('./resetpw')(db)) router.use('/resetpw', require('./resetpw')(db))
router.use('/confirm-account', require('./confirm-account')(db)) router.use('/confirm-account', require('./confirm-account')(db))
@ -34,9 +50,9 @@ module.exports = ({ db, config }) => {
router.use('/wishlist', require('./wishlist')(db)) router.use('/wishlist', require('./wishlist')(db))
router.use('/supported-sites', require('./supported-sites')()) router.use('/supported-sites', require('./supported-sites')())
router.use('/profile', require('./profile')(db)) router.use('/profile', require('./profile')({ db, ensurePfp }))
router.use('/admin-settings', require('./adminSettings')(db)) router.use('/admin-settings', require('./adminSettings')({ db, ensurePfp }))
router.use('/manifest.json', require('./manifest.json')({ config })) router.use('/manifest.json', require('./manifest.json')({ config }))

View file

@ -2,10 +2,20 @@ const verifyAuth = require('../../middlewares/verifyAuth')
const bcrypt = require('bcrypt-nodejs') const bcrypt = require('bcrypt-nodejs')
const express = require('express') const express = require('express')
module.exports = (db) => { module.exports = ({ db, ensurePfp }) => {
const router = express.Router() const router = express.Router()
router.get('/', verifyAuth(), (req, res) => res.render('profile', { title: `Profile Settings - ${req.user._id}` })) router.get('/', verifyAuth(), async (req, res) => {
await ensurePfp(req.user._id)
res.render('profile', { title: `Profile Settings - ${req.user._id}` })
})
router.post('/pfp', verifyAuth(), async (req, res) => {
req.user.pfp = req.body.image
await db.put(req.user)
if (!req.user.pfp) await ensurePfp(req.user._id)
req.flash('success', 'Saved profile picture!')
res.redirect(`${_CC.config.base}profile`)
})
router.post('/', verifyAuth(), (req, res) => { router.post('/', verifyAuth(), (req, res) => {
if (req.body.oldPassword && req.body.newPassword) { if (req.body.oldPassword && req.body.newPassword) {
bcrypt.compare(req.body.oldPassword, req.user.password, (err, correct) => { bcrypt.compare(req.body.oldPassword, req.user.password, (err, correct) => {

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

View file

@ -0,0 +1,20 @@
extends layout.pug
block content
form(method='POST')
.field
label.label Old Password (Required if changing password)
.control.has-icons-left
input.input(type='password', name='oldPassword', placeholder='pa$$word!')
span.icon.is-small.is-left
i.fas.fa-lock
.field
label.label New Password (Leave blank if not changing password)
.control.has-icons-left
input.input(type='password', name='newPassword', placeholder='pa$$word!')
span.icon.is-small.is-left
i.fas.fa-lock
.field
.control
input.button.is-primary(type='submit' value='Save')

View file

@ -1,20 +1,31 @@
extends layout.pug extends layout.pug
block content block content
form(method='POST') h2 Profile
.field div(style='margin-top: 1em;')
label.label Old Password (Required if changing password) .columns(style='margin-top: 1em;')
.control.has-icons-left .column.is-narrow
input.input(type='password', name='oldPassword', placeholder='pa$$word!') .box
span.icon.is-small.is-left .columns
i.fas.fa-lock .column
.field figure.image.is-square(style='display: inline-block; width: 90%;')
label.label New Password (Leave blank if not changing password) img.is-rounded(src=req.user.pfp, style='object-fit: cover;')
.control.has-icons-left .column.is-narrow
input.input(type='password', name='newPassword', placeholder='pa$$word!') .column
span.icon.is-small.is-left span.is-size-3= req.user._id
i.fas.fa-lock br
.field br
.control form(action=`${_CC.config.base}profile/pfp`, method='POST')
input.button.is-primary(type='submit' value='Save') label.label Image URL
.field.has-addons
.control
input.input(name='image', value=req.user.pfp)
.control
button.button.is-primary(type='submit')
span.icon
i.fas.fa-save
h2 Security
a.button.is-primary(href=`${_CC.config.base}profile/password`)
span.icon
i.fas.fa-shield-alt
span Change Password

View file

@ -6,14 +6,24 @@ block content
li li
a(href=`${_CC.config.base}wishlist/${req.user._id}`) a(href=`${_CC.config.base}wishlist/${req.user._id}`)
.box .box
span=req.user._id .columns
span : ???/??? .column.is-1(style='overflow: hidden;')
progress.progress(value=1, max=1) figure.image.is-square.is-fullwidth.is-marginless(style='display: inline-block;')
img.is-rounded.is-fullwidth(src=req.user.pfp, style='object-fit: cover;')
.column
span=req.user._id
span : ???/???
progress.progress(value=1, max=1)
each user in users each user in users
if req.user._id !== user.id if req.user._id !== user.id
li li
a(href=`${_CC.config.base}wishlist/${user.id}`) a(href=`${_CC.config.base}wishlist/${user.id}`)
.box .box
span= user.id .columns
span : #{totals(user.doc.wishlist).pledged}/#{user.doc.wishlist.length} .column.is-1(style='overflow: hidden;')
progress.progress.is-info(value=totals(user.doc.wishlist).pledged, max=user.doc.wishlist.length) figure.image.is-square.is-fullwidth.is-marginless(style='display: inline-block;')
img.is-rounded.is-fullwidth(src=user.doc.pfp, style='object-fit: cover;')
.column
span= user.id
span : #{totals(user.doc.wishlist).pledged}/#{user.doc.wishlist.length}
progress.progress.is-info(value=totals(user.doc.wishlist).pledged, max=user.doc.wishlist.length)

View file

@ -2700,7 +2700,7 @@
"resolved" "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" "resolved" "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz"
"version" "4.4.2" "version" "4.4.2"
"lodash@^4.15.0", "lodash@^4.17.19": "lodash@^4.15.0", "lodash@^4.17.19", "lodash@^4.17.20":
"integrity" "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" "integrity" "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
"resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz" "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz"
"version" "4.17.20" "version" "4.17.20"