Giftwrap: Share a list with a link

Access controlBeginner+39 -0

Click a line to select it, or press and drag down the changes to select a block (Shift-click works too). Then name the weakness and submit the finding. Each finding is marked as soon as you submit it. On the keyboard, Tab to a file's changes, move with the arrow keys, hold Shift to select a block, and press Enter to flag it.

routes/share.jsadded+32-0
routes/share.js
@@ -0,0 +1,32 @@
1+const express = require('express')
2+
3+const { getList, getListsByOwner, saveList } = require('../lib/lists')
4+const { requireUser } = require('../lib/auth')
5+
6+const router = express.Router()
7+
8+router.post('/lists/:id/share', requireUser, async (req, res) => {
9+ const link = `${req.protocol}://${req.get('host')}/share/${req.params.id}`
10+ res.render('share', { link })
11+})
12+
13+router.get('/share/:id', async (req, res) => {
14+ const list = await getList(req.params.id)
15+ if (!list) return res.status(404).render('error', { message: 'List not found.' })
16+ res.render('lists/edit', { list, canEdit: true })
17+})
18+
19+router.post('/share/:id', async (req, res) => {
20+ const list = await getList(req.params.id)
21+ await saveList(req.params.id, { ...list, ...req.body })
22+ res.redirect(`/share/${req.params.id}`)
23+})
24+
25+router.get('/share/:id/family', async (req, res) => {
26+ const list = await getList(req.params.id)
27+ if (!list) return res.status(404).render('error', { message: 'List not found.' })
28+ const lists = await getListsByOwner(list.ownerId)
29+ res.render('share-family', { owner: list.ownerName, lists })
30+})
31+
32+module.exports = router
lib/tokens.jsadded+7-0
lib/tokens.js
@@ -0,0 +1,7 @@
1+const crypto = require('crypto')
2+
3+function shareToken() {
4+ return crypto.randomBytes(24).toString('base64url')
5+}
6+
7+module.exports = { shareToken }

This challenge is Training Content. We encourage you to discuss it and to publish your own write-ups and videos of it.