authoring restrictions

This commit is contained in:
James Shiffer 2020-06-11 10:51:09 -07:00
parent 41718caa46
commit ffa8b5322a
10 changed files with 1786 additions and 29 deletions

View File

@ -6,11 +6,30 @@ A satirical blog with its own lightweight CMS, which all runs on [Sapper](https:
Requires Node.js and MongoDB
Create a MongoDB database for howfeed
Create a MongoDB database for howfeed:
```sh
$ mongo
> use howfeed;
```
Set up `.env.example` as `.env`
Then install dependencies and start a local server:
```sh
npm i
npm run dev
$ npm i
$ npm run dev
```
## Usage
Anyone can sign up for an account, but to designate a certain account as an author so they can publish articles, you will need to set the `author` field to `true` in Mongo:
```sh
$ mongo
> use howfeed;
> db.users.updateOne({username: 'myuser1'}, {$set:{author: true}})
```
Then the user should logout and log back in.

View File

@ -1,5 +1,5 @@
import * as sapper from '@sapper/app';
sapper.start({
target: document.querySelector('#sapper')
target: document.querySelector('#hydrate')
});

File diff suppressed because it is too large Load Diff

View File

@ -56,6 +56,8 @@
{#if !$session.user}
<div class="link"><a href="mailto:the_katze@naver.com">Contact Us</a></div>
{:else}
<div class="link"><a href="/cms">Dashboard</a></div>
<div class="filler"></div>
<div class="link"><a href="/cms/logout">Logout</a></div>
{/if}
</div>

View File

@ -8,7 +8,8 @@ const { Schema } = mongoose;
const UserSchema = new Schema({
username: { type: String, required: true, index: { unique: true } },
password: { type: String, required: true },
realname: { type: String, required: true }
realname: { type: String, required: true },
author: { type: Boolean, default: false }
});

View File

@ -12,9 +12,19 @@
<title>Dashboard | HOWFEED.BIZ</title>
</svelte:head>
<script>
import FakeTweet from '../../components/FakeTweet.svelte';
export let user;
</script>
<div class="content">
{#if user.author}
<h1>HowFeed Publisher Dashboard</h1>
<p><a href="/cms/create">Publish a new article</a></p>
<p><a href="/cms/update">Edit an existing article</a></p>
<p><a href="/cms/delete">Delete an article</a></p>
{:else}
<FakeTweet message="We're watching you" author="Caltrans HQ" verified likes=0 replies=2 date={new Date(2019, 8, 21)} handle="CaltransHQ" avatar="/ct.jpg" />
{/if}
</div>

View File

@ -8,6 +8,7 @@ import mongoose from 'mongoose';
import passport from 'passport';
import { Strategy } from 'passport-local';
import sessionFileStore from 'session-file-store';
import Article from './models/article.js';
import User from './models/user.js';
require('dotenv').config();
@ -52,7 +53,6 @@ passport.use(new Strategy((username, password, done) => {
}));
express()
.use(passport.initialize())
.use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: true }))
.use(session({
@ -67,9 +67,11 @@ express()
path: '.sessions'
})
}))
.use(passport.initialize())
.use(passport.session())
.post('/cms/register',
(req, res, next) => {
function(req, res, next) {
if (!req.user) {
next();
} else {
@ -109,6 +111,15 @@ express()
}));
return false;
}
if (!/^[a-z0-9.]+$/i.test(username)) {
res.writeHead(422, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `The username can only contain letters, numbers, and periods.`
}));
return false;
}
try {
const user = await User.findOne({ username: req.body.username });
if (user) {
@ -167,7 +178,27 @@ express()
})
.post('/cms/article',
passport.authenticate('local'),
function(req, res, next) {
if (req.user) {
if (req.user.author) {
next();
} else {
res.writeHead(401, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `You are not designated as an author.`
}));
}
} else {
res.writeHead(401, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `You are not logged in`
}));
}
},
function(req, res, next) {
res.writeHead(200, {
'Content-Type': 'application/json'
@ -175,15 +206,6 @@ express()
res.end(JSON.stringify({
message: `ur a faget lol`
}));
},
function(err, req, res, next) {
// handle error
res.writeHead(err.status || 500, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: err.message
}));
}
)

View File

@ -3,7 +3,9 @@
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1.0'>
<meta name='theme-color' content='#333333'>
<meta name='description' content='HOWFEED.BIZ: Where we break the news.'>
<meta name='keywords' content='news, satire, blog'>
<meta name='theme-color' content='#508FC3'>
%sapper.base%
<link rel='stylesheet' href='global.css'>
<link rel='icon' type='image/png' href='favicon.png'>
@ -11,7 +13,7 @@
%sapper.head%
</head>
<body>
<div id='sapper'>%sapper.html%</div>
<div id='hydrate'>%sapper.html%</div>
%sapper.scripts%
</body>
</html>

BIN
static/ct.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -24,7 +24,7 @@ module.exports = {
options: {
dev,
hydratable: true,
hotReload: false // pending https://github.com/sveltejs/svelte/issues/2377
hotReload: true,
}
}
}
@ -39,7 +39,7 @@ module.exports = {
'process.env.NODE_ENV': JSON.stringify(mode)
}),
].filter(Boolean),
devtool: dev && 'inline-source-map'
devtool: dev && 'inline-source-map',
},
server: {
@ -66,7 +66,7 @@ module.exports = {
mode: process.env.NODE_ENV,
performance: {
hints: false // it doesn't matter if server.js is large
}
},
},
serviceworker: {