Add usage of SECRET_KEY to secure API routes

This commit is contained in:
Max Leiter 2022-03-21 17:42:37 -07:00
parent 90fa28ad65
commit d30c34deec
No known key found for this signature in database
GPG key ID: A3512F2F2F17EBDA
8 changed files with 58 additions and 64 deletions

View file

@ -5,9 +5,11 @@ const getRawFile = async (req: NextApiRequest, res: NextApiResponse) => {
const file = await fetch(`${process.env.API_URL}/files/raw/${id}`, { const file = await fetch(`${process.env.API_URL}/files/raw/${id}`, {
headers: { headers: {
'Accept': 'text/plain', 'Accept': 'text/plain',
'x-secret-key': process.env.SECRET_KEY || '' 'x-secret-key': process.env.SECRET_KEY || '',
'Authorization': `Bearer ${req.cookies['drift-token']}`,
} }
}) })
res.setHeader("Content-Type", "text/plain") res.setHeader("Content-Type", "text/plain")
res.setHeader('Cache-Control', 's-maxage=86400'); res.setHeader('Cache-Control', 's-maxage=86400');

View file

@ -1,24 +0,0 @@
import { NextApiRequest, NextApiResponse } from "next"
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.headers['x-secret-key'] !== process.env.SECRET_KEY) {
return res.status(401).send('Unauthorized')
}
const { path } = req.query
if (!path || typeof path !== 'string') {
return res.status(400).json({
error: "Missing path"
})
}
try {
await res.unstable_revalidate(path)
return res.json({ revalidated: true })
} catch (err) {
// If there was an error, Next.js will continue
// to show the last successfully generated page
return res.status(500).send('Error revalidating')
}
}

View file

@ -31,14 +31,24 @@ export const getServerSideProps: GetServerSideProps = async ({ req }) => {
} }
} }
const posts = await fetch('http://localhost:3000/server-api/users/mine', { const posts = await fetch(process.env.API_URL + `/posts/mine`, {
method: "GET", method: "GET",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": `Bearer ${driftToken}` "Authorization": `Bearer ${driftToken}`,
"x-secret-key": process.env.SECRET_KEY || ''
} }
}) })
if (!posts.ok || posts.status !== 200) {
return {
redirect: {
destination: '/',
permanent: false,
}
}
}
return { return {
props: { props: {
posts: await posts.json(), posts: await posts.json(),

View file

@ -92,7 +92,8 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
method: "GET", method: "GET",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": `Bearer ${driftToken}` "Authorization": `Bearer ${driftToken}`,
"x-secret-key": process.env.SECRET_KEY || "",
} }
}) })

View file

@ -38,7 +38,7 @@ export class Post extends Model {
@BelongsToMany(() => User, () => PostAuthor) @BelongsToMany(() => User, () => PostAuthor)
users?: User[]; users?: User[];
@HasMany(() => File) @HasMany(() => File, { constraints: false })
files?: File[]; files?: File[];
@CreatedAt @CreatedAt

View file

@ -1,6 +1,5 @@
import { Router } from 'express' import { Router } from 'express'
import secretKey from '../lib/middleware/secret-key'; import secretKey from '../lib/middleware/secret-key';
// import { Movie } from '../models/Post'
import { File } from '../lib/models/File' import { File } from '../lib/models/File'
export const files = Router() export const files = Router()
@ -13,7 +12,16 @@ files.get("/raw/:id", secretKey, async (req, res, next) => {
}, },
attributes: ["title", "content"], attributes: ["title", "content"],
}) })
res.json(file);
// TODO: JWT-checkraw files
if (file?.post?.visibility === "private") {
// jwt(req as UserJwtRequest, res, () => {
// res.json(file);
// })
res.json(file);
} else {
res.json(file);
}
} }
catch (e) { catch (e) {
next(e); next(e);

View file

@ -69,6 +69,35 @@ posts.get("/", secretKey, async (req, res, next) => {
} }
}); });
posts.get("/mine", jwt, secretKey, async (req: UserJwtRequest, res, next) => {
if (!req.user) {
return res.status(401).json({ error: "Unauthorized" })
}
try {
const user = await User.findByPk(req.user.id, {
include: [
{
model: Post,
as: "posts",
include: [
{
model: File,
as: "files"
}
]
},
],
})
if (!user) {
return res.status(404).json({ error: "User not found" })
}
return res.json(user.posts?.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()))
} catch (error) {
next(error)
}
})
posts.get("/:id", secretKey, async (req, res, next) => { posts.get("/:id", secretKey, async (req, res, next) => {
try { try {
const post = await Post.findOne({ const post = await Post.findOne({
@ -95,7 +124,6 @@ posts.get("/:id", secretKey, async (req, res, next) => {
if (post.visibility === 'public' || post?.visibility === 'unlisted') { if (post.visibility === 'public' || post?.visibility === 'unlisted') {
res.json(post); res.json(post);
} else if (post.visibility === 'private') { } else if (post.visibility === 'private') {
console.log("here")
jwt(req as UserJwtRequest, res, () => { jwt(req as UserJwtRequest, res, () => {
res.json(post); res.json(post);
}) })
@ -107,4 +135,3 @@ posts.get("/:id", secretKey, async (req, res, next) => {
next(e); next(e);
} }
}); });

View file

@ -1,9 +1,7 @@
import { Router } from 'express' import { Router } from 'express'
// import { Movie } from '../models/Post' // import { Movie } from '../models/Post'
import { User } from '../lib/models/User' import { User } from '../lib/models/User'
import { File } from '../lib/models/File' import jwt from '../lib/middleware/jwt'
import jwt, { UserJwtRequest } from '../lib/middleware/jwt'
import { Post } from '../lib/models/Post'
export const users = Router() export const users = Router()
@ -16,31 +14,3 @@ users.get('/', jwt, async (req, res, next) => {
} }
}) })
users.get("/mine", jwt, async (req: UserJwtRequest, res, next) => {
if (!req.user) {
return res.status(401).json({ error: "Unauthorized" })
}
try {
const user = await User.findByPk(req.user.id, {
include: [
{
model: Post,
as: "posts",
include: [
{
model: File,
as: "files"
}
]
},
],
})
if (!user) {
return res.status(404).json({ error: "User not found" })
}
return res.json(user.posts?.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()))
} catch (error) {
next(error)
}
})