Merge pull request #40 from maxall41/better-validation
server: Better validation using celebrate
This commit is contained in:
commit
056a2bd3ce
14 changed files with 451 additions and 297 deletions
|
@ -1,4 +1,4 @@
|
||||||
import { marked, Lexer } from 'marked'
|
import { marked } from 'marked'
|
||||||
import Highlight, { defaultProps, Language, } from 'prism-react-renderer'
|
import Highlight, { defaultProps, Language, } from 'prism-react-renderer'
|
||||||
import { renderToStaticMarkup } from 'react-dom/server'
|
import { renderToStaticMarkup } from 'react-dom/server'
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ const renderMarkdown: NextApiHandler = async (req, res) => {
|
||||||
Authorization: `Bearer ${req.cookies["drift-token"]}`
|
Authorization: `Bearer ${req.cookies["drift-token"]}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log(file.status)
|
if (file.status
|
||||||
if (file.status !== 200) {
|
!== 200) {
|
||||||
return res.status(404).json({ error: "File not found" })
|
return res.status(404).json({ error: "File not found" })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ const getRawFile = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
res.setHeader("Cache-Control", "s-maxage=86400")
|
res.setHeader("Cache-Control", "s-maxage=86400")
|
||||||
if (file.ok) {
|
if (file.ok) {
|
||||||
const json = await file.json()
|
const json = await file.json()
|
||||||
console.log(json)
|
|
||||||
const data = json
|
const data = json
|
||||||
const { title, content } = data
|
const { title, content } = data
|
||||||
// serve the file raw as plain text
|
// serve the file raw as plain text
|
||||||
|
|
|
@ -21,8 +21,8 @@ export const getStaticPaths: GetStaticPaths = async () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const json = await posts.json()
|
const json = await posts.json()
|
||||||
const filtered = json.filter((post: any) => post.visibility === "public" || post.visibility === "unlisted")
|
const filtered = json.filter((post: Post) => post.visibility === "public" || post.visibility === "unlisted")
|
||||||
const paths = filtered.map((post: any) => ({
|
const paths = filtered.map((post: Post) => ({
|
||||||
params: { id: post.id }
|
params: { id: post.id }
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^5.0.1",
|
"bcrypt": "^5.0.1",
|
||||||
"body-parser": "^1.18.2",
|
"body-parser": "^1.18.2",
|
||||||
|
"celebrate": "^15.0.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
"express": "^4.16.2",
|
"express": "^4.16.2",
|
||||||
|
@ -40,6 +41,7 @@
|
||||||
"@types/node": "^17.0.21",
|
"@types/node": "^17.0.21",
|
||||||
"@types/react-dom": "^17.0.14",
|
"@types/react-dom": "^17.0.14",
|
||||||
"ts-node": "^10.6.0",
|
"ts-node": "^10.6.0",
|
||||||
|
"tsconfig-paths": "^3.14.1",
|
||||||
"tslint": "^6.1.3",
|
"tslint": "^6.1.3",
|
||||||
"typescript": "^4.6.2"
|
"typescript": "^4.6.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@ import * as express from 'express';
|
||||||
import * as bodyParser from 'body-parser';
|
import * as bodyParser from 'body-parser';
|
||||||
import * as errorhandler from 'strong-error-handler';
|
import * as errorhandler from 'strong-error-handler';
|
||||||
import * as cors from 'cors';
|
import * as cors from 'cors';
|
||||||
import { posts, users, auth, files } from './routes';
|
import { posts, users, auth, files } from '@routes/index';
|
||||||
|
import { errors } from 'celebrate'
|
||||||
|
|
||||||
export const app = express();
|
export const app = express();
|
||||||
|
|
||||||
|
@ -19,7 +20,10 @@ app.use("/posts", posts)
|
||||||
app.use("/users", users)
|
app.use("/users", users)
|
||||||
app.use("/files", files)
|
app.use("/files", files)
|
||||||
|
|
||||||
|
app.use(errors());
|
||||||
|
|
||||||
app.use(errorhandler({
|
app.use(errorhandler({
|
||||||
debug: process.env.ENV !== 'production',
|
debug: process.env.ENV !== 'production',
|
||||||
log: true,
|
log: true,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { marked, Lexer } from 'marked'
|
import { marked } from 'marked'
|
||||||
import Highlight, { defaultProps, Language, } from 'prism-react-renderer'
|
import Highlight, { defaultProps, Language, } from 'prism-react-renderer'
|
||||||
import { renderToStaticMarkup } from 'react-dom/server'
|
import { renderToStaticMarkup } from 'react-dom/server'
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { Router } from 'express'
|
import { Router } from 'express'
|
||||||
import { genSalt, hash, compare } from "bcrypt"
|
import { genSalt, hash, compare } from "bcrypt"
|
||||||
import { User } from '../lib/models/User'
|
import { User } from '@lib/models/User'
|
||||||
import { sign } from 'jsonwebtoken'
|
import { sign } from 'jsonwebtoken'
|
||||||
import config from '../lib/config'
|
import config from '@lib/config'
|
||||||
import jwt from '../lib/middleware/jwt'
|
import jwt from '@lib/middleware/jwt'
|
||||||
|
import { celebrate, Joi } from 'celebrate'
|
||||||
|
|
||||||
const NO_EMPTY_SPACE_REGEX = /^\S*$/
|
const NO_EMPTY_SPACE_REGEX = /^\S*$/
|
||||||
|
|
||||||
|
@ -24,45 +25,64 @@ const validateAuthPayload = (username: string, password: string, serverPassword?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auth.post('/signup', async (req, res, next) => {
|
auth.post('/signup',
|
||||||
|
celebrate({
|
||||||
|
body: {
|
||||||
|
username: Joi.string().required(),
|
||||||
|
password: Joi.string().required(),
|
||||||
|
serverPassword: Joi.string().required().allow('', null),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
validateAuthPayload(req.body.username, req.body.password, req.body.serverPassword)
|
validateAuthPayload(req.body.username, req.body.password, req.body.serverPassword)
|
||||||
|
|
||||||
const username = req.body.username.toLowerCase();
|
const username = req.body.username.toLowerCase();
|
||||||
|
|
||||||
const existingUser = await User.findOne({ where: { username: username } })
|
const existingUser = await User.findOne({
|
||||||
|
where: { username: username },
|
||||||
|
});
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
throw new Error("Username already exists")
|
throw new Error("Username already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
const salt = await genSalt(10)
|
const salt = await genSalt(10);
|
||||||
const user = {
|
const user = {
|
||||||
username: username as string,
|
username: username as string,
|
||||||
password: await hash(req.body.password, salt)
|
password: await hash(req.body.password, salt),
|
||||||
}
|
};
|
||||||
|
|
||||||
const created_user = await User.create(user);
|
const created_user = await User.create(user);
|
||||||
|
|
||||||
const token = generateAccessToken(created_user.id);
|
const token = generateAccessToken(created_user.id);
|
||||||
|
|
||||||
res.status(201).json({ token: token, userId: created_user.id })
|
res.status(201).json({ token: token, userId: created_user.id });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
auth.post('/signin', async (req, res, next) => {
|
auth.post(
|
||||||
const error = "User does not exist or password is incorrect"
|
"/signin",
|
||||||
|
celebrate({
|
||||||
|
body: {
|
||||||
|
username: Joi.string().required(),
|
||||||
|
password: Joi.string().required(),
|
||||||
|
serverPassword: Joi.string().required().allow('', null),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (req, res, next) => {
|
||||||
|
const error = "User does not exist or password is incorrect";
|
||||||
const errorToThrow = new Error(error);
|
const errorToThrow = new Error(error);
|
||||||
try {
|
try {
|
||||||
if (!req.body.username || !req.body.password) {
|
if (!req.body.username || !req.body.password) {
|
||||||
throw errorToThrow
|
throw errorToThrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
const username = req.body.username.toLowerCase();
|
const username = req.body.username.toLowerCase();
|
||||||
const user = await User.findOne({ where: { username: username } });
|
const user = await User.findOne({ where: { username: username } });
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw errorToThrow
|
throw errorToThrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
const password_valid = await compare(req.body.password, user.password);
|
const password_valid = await compare(req.body.password, user.password);
|
||||||
|
@ -70,33 +90,32 @@ auth.post('/signin', async (req, res, next) => {
|
||||||
const token = generateAccessToken(user.id);
|
const token = generateAccessToken(user.id);
|
||||||
res.status(200).json({ token: token, userId: user.id });
|
res.status(200).json({ token: token, userId: user.id });
|
||||||
} else {
|
} else {
|
||||||
throw errorToThrow
|
throw errorToThrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
auth.get('/requires-passcode', async (req, res, next) => {
|
auth.get("/requires-passcode", async (req, res, next) => {
|
||||||
if (requiresServerPassword) {
|
if (requiresServerPassword) {
|
||||||
res.status(200).json({ requiresPasscode: true });
|
res.status(200).json({ requiresPasscode: true });
|
||||||
} else {
|
} else {
|
||||||
res.status(200).json({ requiresPasscode: false });
|
res.status(200).json({ requiresPasscode: false });
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
function generateAccessToken(id: string) {
|
function generateAccessToken(id: string) {
|
||||||
return sign({ id: id }, config.jwt_secret, { expiresIn: '2d' });
|
return sign({ id: id }, config.jwt_secret, { expiresIn: "2d" });
|
||||||
}
|
}
|
||||||
|
|
||||||
auth.get("/verify-token", jwt, async (req, res, next) => {
|
auth.get("/verify-token", jwt, async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
message: "You are authenticated"
|
message: "You are authenticated",
|
||||||
})
|
});
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
import { Router } from 'express'
|
import { celebrate, Joi } from "celebrate";
|
||||||
import secretKey from '../lib/middleware/secret-key';
|
import { Router } from "express";
|
||||||
import { File } from '../lib/models/File'
|
import { File } from "@lib/models/File";
|
||||||
|
import secretKey from "@lib/middleware/secret-key";
|
||||||
|
|
||||||
export const files = Router()
|
export const files = Router();
|
||||||
|
|
||||||
files.get("/raw/:id", secretKey, async (req, res, next) => {
|
files.get("/raw/:id",
|
||||||
|
celebrate({
|
||||||
|
params: {
|
||||||
|
id: Joi.string().required(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
secretKey,
|
||||||
|
async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const file = await File.findOne({
|
const file = await File.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
@ -13,7 +21,6 @@ files.get("/raw/:id", secretKey, async (req, res, next) => {
|
||||||
attributes: ["title", "content"],
|
attributes: ["title", "content"],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return res.status(404).json({ error: "File not found" })
|
return res.status(404).json({ error: "File not found" })
|
||||||
}
|
}
|
||||||
|
@ -31,10 +38,17 @@ files.get("/raw/:id", secretKey, async (req, res, next) => {
|
||||||
catch (e) {
|
catch (e) {
|
||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
files.get("/html/:id", async (req, res, next) => {
|
files.get("/html/:id",
|
||||||
|
celebrate({
|
||||||
|
params: {
|
||||||
|
id: Joi.string().required(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const file = await File.findOne({
|
const file = await File.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
@ -54,4 +68,5 @@ files.get("/html/:id", async (req, res, next) => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error)
|
next(error)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export { auth } from './auth';
|
export { auth } from "./auth";
|
||||||
export { posts } from './posts';
|
export { posts } from "./posts";
|
||||||
export { users } from './users';
|
export { users } from "./users";
|
||||||
export { files } from './files';
|
export { files } from "./files";
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
import { Router } from 'express'
|
import { Router } from "express";
|
||||||
// import { Movie } from '../models/Post'
|
import { celebrate, Joi } from "celebrate";
|
||||||
import { File } from '../lib/models/File'
|
import { File } from '@lib/models/File'
|
||||||
import { Post } from '../lib/models/Post';
|
import { Post } from '@lib/models/Post';
|
||||||
import jwt, { UserJwtRequest } from '../lib/middleware/jwt';
|
import jwt, { UserJwtRequest } from '@lib/middleware/jwt';
|
||||||
import * as crypto from "crypto";
|
import * as crypto from "crypto";
|
||||||
import { User } from '../lib/models/User';
|
import { User } from '@lib/models/User';
|
||||||
import secretKey from '../lib/middleware/secret-key';
|
import secretKey from '@lib/middleware/secret-key';
|
||||||
import markdown from '../lib/render-markdown';
|
import markdown from '@lib/render-markdown';
|
||||||
|
|
||||||
export const posts = Router()
|
export const posts = Router();
|
||||||
|
|
||||||
posts.post('/create', jwt, async (req, res, next) => {
|
const postVisibilitySchema = (value: string) => {
|
||||||
|
if (value === 'public' || value === 'private') {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid post visibility');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
posts.post(
|
||||||
|
"/create",
|
||||||
|
jwt,
|
||||||
|
celebrate({
|
||||||
|
body: {
|
||||||
|
title: Joi.string().required(),
|
||||||
|
files: Joi.any().required(),
|
||||||
|
visibility: Joi.string().custom(postVisibilitySchema, 'valid visibility').required(),
|
||||||
|
userId: Joi.string().required(),
|
||||||
|
password: Joi.string().optional(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
if (!req.body.files) {
|
|
||||||
throw new Error("Please provide files.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!req.body.title) {
|
|
||||||
throw new Error("Please provide a title.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!req.body.userId) {
|
|
||||||
throw new Error("No user id provided.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!req.body.visibility) {
|
|
||||||
throw new Error("Please provide a visibility.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body.visibility === 'protected' && !req.body.password) {
|
|
||||||
throw new Error("Please provide a password.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let hashedPassword: string = ''
|
let hashedPassword: string = ''
|
||||||
if (req.body.visibility === 'protected') {
|
if (req.body.visibility === 'protected') {
|
||||||
hashedPassword = crypto.createHash('sha256').update(req.body.password).digest('hex');
|
hashedPassword = crypto.createHash('sha256').update(req.body.password).digest('hex');
|
||||||
|
@ -46,24 +46,7 @@ posts.post('/create', jwt, async (req, res, next) => {
|
||||||
await newPost.save()
|
await newPost.save()
|
||||||
await newPost.$add('users', req.body.userId);
|
await newPost.$add('users', req.body.userId);
|
||||||
const newFiles = await Promise.all(req.body.files.map(async (file) => {
|
const newFiles = await Promise.all(req.body.files.map(async (file) => {
|
||||||
const renderAsMarkdown = ['markdown', 'md', 'mdown', 'mkdn', 'mkd', 'mdwn', 'mdtxt', 'mdtext', 'text', '']
|
const html = getHtmlFromFile(file);
|
||||||
const fileType = () => {
|
|
||||||
const pathParts = file.title.split(".")
|
|
||||||
const language = pathParts.length > 1 ? pathParts[pathParts.length - 1] : ""
|
|
||||||
return language
|
|
||||||
}
|
|
||||||
const type = fileType()
|
|
||||||
let contentToRender: string = (file.content || '');
|
|
||||||
|
|
||||||
if (!renderAsMarkdown.includes(type)) {
|
|
||||||
contentToRender =
|
|
||||||
`~~~${type}
|
|
||||||
${file.content}
|
|
||||||
~~~`
|
|
||||||
} else {
|
|
||||||
contentToRender = '\n' + file.content;
|
|
||||||
}
|
|
||||||
const html = markdown(contentToRender)
|
|
||||||
const newFile = new File({
|
const newFile = new File({
|
||||||
title: file.title,
|
title: file.title,
|
||||||
content: file.content,
|
content: file.content,
|
||||||
|
@ -86,13 +69,15 @@ ${file.content}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
posts.get("/", secretKey, async (req, res, next) => {
|
posts.get("/", secretKey, async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const posts = await Post.findAll({
|
const posts = await Post.findAll({
|
||||||
attributes: ["id", "title", "visibility", "createdAt"],
|
attributes: ["id", "title", "visibility", "createdAt"],
|
||||||
})
|
})
|
||||||
|
|
||||||
res.json(posts);
|
res.json(posts);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next(e);
|
next(e);
|
||||||
|
@ -128,30 +113,48 @@ posts.get("/mine", jwt, secretKey, async (req: UserJwtRequest, res, next) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
posts.get("/:id", async (req, res, next) => {
|
posts.get(
|
||||||
|
"/:id",
|
||||||
|
celebrate({
|
||||||
|
params: {
|
||||||
|
id: Joi.string().required(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (req: UserJwtRequest, res, next) => {
|
||||||
try {
|
try {
|
||||||
const post = await Post.findOne({
|
const post = await Post.findOne({
|
||||||
where: {
|
where: {
|
||||||
id: req.params.id
|
id: req.params.id,
|
||||||
},
|
},
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: File,
|
model: File,
|
||||||
as: "files",
|
as: "files",
|
||||||
attributes: ["id", "title", "content", "sha", "createdAt", "updatedAt"],
|
attributes: [
|
||||||
|
"id",
|
||||||
|
"title",
|
||||||
|
"content",
|
||||||
|
"sha",
|
||||||
|
"createdAt",
|
||||||
|
"updatedAt",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: User,
|
model: User,
|
||||||
as: "users",
|
as: "users",
|
||||||
attributes: ["id", "username"],
|
attributes: ["id", "username"],
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
})
|
});
|
||||||
|
|
||||||
if (!post) {
|
if (!post) {
|
||||||
throw new Error("Post not found.")
|
return res.status(404).json({ error: "Post not found" })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if public or unlisted, cache
|
||||||
|
if (post.visibility === 'public' || post.visibility === 'unlisted') {
|
||||||
|
res.set('Cache-Control', 'public, max-age=4800')
|
||||||
|
}
|
||||||
|
|
||||||
if (post.visibility === 'public' || post?.visibility === 'unlisted') {
|
if (post.visibility === 'public' || post?.visibility === 'unlisted') {
|
||||||
secretKey(req, res, () => {
|
secretKey(req, res, () => {
|
||||||
|
@ -179,4 +182,28 @@ posts.get("/:id", async (req, res, next) => {
|
||||||
catch (e) {
|
catch (e) {
|
||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function getHtmlFromFile(file: any) {
|
||||||
|
const renderAsMarkdown = ['markdown', 'md', 'mdown', 'mkdn', 'mkd', 'mdwn', 'mdtxt', 'mdtext', 'text', ''];
|
||||||
|
const fileType = () => {
|
||||||
|
const pathParts = file.title.split(".");
|
||||||
|
const language = pathParts.length > 1 ? pathParts[pathParts.length - 1] : "";
|
||||||
|
return language;
|
||||||
|
};
|
||||||
|
const type = fileType();
|
||||||
|
let contentToRender: string = (file.content || '');
|
||||||
|
|
||||||
|
if (!renderAsMarkdown.includes(type)) {
|
||||||
|
contentToRender =
|
||||||
|
`~~~${type}
|
||||||
|
${file.content}
|
||||||
|
~~~`;
|
||||||
|
} else {
|
||||||
|
contentToRender = '\n' + file.content;
|
||||||
|
}
|
||||||
|
const html = markdown(contentToRender);
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import { Router } from 'express'
|
import { Router } from "express";
|
||||||
// import { Movie } from '../models/Post'
|
// import jwt from "@lib/middleware/jwt";
|
||||||
import { User } from '../lib/models/User'
|
// import { User } from "@lib/models/User";
|
||||||
import jwt from '../lib/middleware/jwt'
|
|
||||||
|
|
||||||
export const users = Router()
|
export const users = Router();
|
||||||
|
|
||||||
users.get('/', jwt, async (req, res, next) => {
|
|
||||||
try {
|
|
||||||
const allUsers = await User.findAll()
|
|
||||||
res.json(allUsers)
|
|
||||||
} catch (error) {
|
|
||||||
next(error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
// users.get("/", jwt, async (req, res, next) => {
|
||||||
|
// try {
|
||||||
|
// const allUsers = await User.findAll();
|
||||||
|
// res.json(allUsers);
|
||||||
|
// } catch (error) {
|
||||||
|
// next(error);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
|
@ -14,7 +14,16 @@
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strictPropertyInitialization": true,
|
"strictPropertyInitialization": true,
|
||||||
"outDir": "dist"
|
"outDir": "dist",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@routes/*": ["./src/routes/*"],
|
||||||
|
"@lib/*": ["./src/lib/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ts-node": {
|
||||||
|
// Do not forget to `npm i -D tsconfig-paths`
|
||||||
|
"require": ["tsconfig-paths/register"]
|
||||||
},
|
},
|
||||||
"include": ["index.ts", "src/**/*.ts"],
|
"include": ["index.ts", "src/**/*.ts"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
|
|
|
@ -35,6 +35,18 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@cspotcode/source-map-consumer" "0.8.0"
|
"@cspotcode/source-map-consumer" "0.8.0"
|
||||||
|
|
||||||
|
"@hapi/hoek@^9.0.0":
|
||||||
|
version "9.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.1.tgz#9551142a1980503752536b5050fd99f4a7f13b17"
|
||||||
|
integrity sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw==
|
||||||
|
|
||||||
|
"@hapi/topo@^5.0.0":
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012"
|
||||||
|
integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/hoek" "^9.0.0"
|
||||||
|
|
||||||
"@mapbox/node-pre-gyp@^1.0.0":
|
"@mapbox/node-pre-gyp@^1.0.0":
|
||||||
version "1.0.8"
|
version "1.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz#32abc8a5c624bc4e46c43d84dfb8b26d33a96f58"
|
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz#32abc8a5c624bc4e46c43d84dfb8b26d33a96f58"
|
||||||
|
@ -50,6 +62,23 @@
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tar "^6.1.11"
|
tar "^6.1.11"
|
||||||
|
|
||||||
|
"@sideway/address@^4.1.3":
|
||||||
|
version "4.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.3.tgz#d93cce5d45c5daec92ad76db492cc2ee3c64ab27"
|
||||||
|
integrity sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/hoek" "^9.0.0"
|
||||||
|
|
||||||
|
"@sideway/formula@^3.0.0":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c"
|
||||||
|
integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==
|
||||||
|
|
||||||
|
"@sideway/pinpoint@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
|
||||||
|
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
|
||||||
|
|
||||||
"@sindresorhus/is@^0.14.0":
|
"@sindresorhus/is@^0.14.0":
|
||||||
version "0.14.0"
|
version "0.14.0"
|
||||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
|
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
|
||||||
|
@ -150,6 +179,11 @@
|
||||||
"@types/qs" "*"
|
"@types/qs" "*"
|
||||||
"@types/serve-static" "*"
|
"@types/serve-static" "*"
|
||||||
|
|
||||||
|
"@types/json5@^0.0.29":
|
||||||
|
version "0.0.29"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||||
|
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||||
|
|
||||||
"@types/jsonwebtoken@^8.5.8":
|
"@types/jsonwebtoken@^8.5.8":
|
||||||
version "8.5.8"
|
version "8.5.8"
|
||||||
resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz#01b39711eb844777b7af1d1f2b4cf22fda1c0c44"
|
resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz#01b39711eb844777b7af1d1f2b4cf22fda1c0c44"
|
||||||
|
@ -506,6 +540,15 @@ caseless@~0.12.0:
|
||||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||||
|
|
||||||
|
celebrate@^15.0.1:
|
||||||
|
version "15.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/celebrate/-/celebrate-15.0.1.tgz#767fa6268f7446b473ea69cd6326ce4dffee4d1e"
|
||||||
|
integrity sha512-K2y221k10u+K2t9w25802qXh8h1mVWZf+6pl7zHdlhhwzrOSQFnnw+GsR8k17oyn4Y3fVErBGsO/+CeW8N7aRQ==
|
||||||
|
dependencies:
|
||||||
|
escape-html "1.0.3"
|
||||||
|
joi "17.x.x"
|
||||||
|
lodash "4.17.x"
|
||||||
|
|
||||||
chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.2:
|
chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.2:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||||
|
@ -858,7 +901,7 @@ escape-goat@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
|
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
|
||||||
integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
|
integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
|
||||||
|
|
||||||
escape-html@~1.0.3:
|
escape-html@1.0.3, escape-html@~1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||||
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
|
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
|
||||||
|
@ -1413,6 +1456,17 @@ jake@^10.6.1:
|
||||||
filelist "^1.0.1"
|
filelist "^1.0.1"
|
||||||
minimatch "^3.0.4"
|
minimatch "^3.0.4"
|
||||||
|
|
||||||
|
joi@17.x.x:
|
||||||
|
version "17.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/joi/-/joi-17.6.0.tgz#0bb54f2f006c09a96e75ce687957bd04290054b2"
|
||||||
|
integrity sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/hoek" "^9.0.0"
|
||||||
|
"@hapi/topo" "^5.0.0"
|
||||||
|
"@sideway/address" "^4.1.3"
|
||||||
|
"@sideway/formula" "^3.0.0"
|
||||||
|
"@sideway/pinpoint" "^2.0.0"
|
||||||
|
|
||||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||||
|
@ -1458,6 +1512,13 @@ json-stringify-safe@~5.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||||
|
|
||||||
|
json5@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
|
||||||
|
integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
|
||||||
|
dependencies:
|
||||||
|
minimist "^1.2.0"
|
||||||
|
|
||||||
jsonwebtoken@^8.1.0, jsonwebtoken@^8.5.1:
|
jsonwebtoken@^8.1.0, jsonwebtoken@^8.5.1:
|
||||||
version "8.5.1"
|
version "8.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
|
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
|
||||||
|
@ -1557,7 +1618,7 @@ lodash.once@^4.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
||||||
|
|
||||||
lodash@^4.17.20, lodash@^4.17.21:
|
lodash@4.17.x, lodash@^4.17.20, lodash@^4.17.21:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
@ -1687,6 +1748,11 @@ minimist@^1.2.0, minimist@^1.2.5:
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||||
|
|
||||||
|
minimist@^1.2.6:
|
||||||
|
version "1.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
|
||||||
minipass@^3.0.0:
|
minipass@^3.0.0:
|
||||||
version "3.1.6"
|
version "3.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee"
|
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee"
|
||||||
|
@ -2385,6 +2451,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex "^5.0.1"
|
ansi-regex "^5.0.1"
|
||||||
|
|
||||||
|
strip-bom@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||||
|
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
|
||||||
|
|
||||||
strip-final-newline@^2.0.0:
|
strip-final-newline@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||||
|
@ -2515,6 +2586,16 @@ ts-node@^10.6.0:
|
||||||
v8-compile-cache-lib "^3.0.0"
|
v8-compile-cache-lib "^3.0.0"
|
||||||
yn "3.1.1"
|
yn "3.1.1"
|
||||||
|
|
||||||
|
tsconfig-paths@^3.14.1:
|
||||||
|
version "3.14.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
|
||||||
|
integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/json5" "^0.0.29"
|
||||||
|
json5 "^1.0.1"
|
||||||
|
minimist "^1.2.6"
|
||||||
|
strip-bom "^3.0.0"
|
||||||
|
|
||||||
tslib@^1.13.0, tslib@^1.8.1:
|
tslib@^1.13.0, tslib@^1.8.1:
|
||||||
version "1.14.1"
|
version "1.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
|
|
Loading…
Reference in a new issue