This application will allow users to upload markdown files. Users will have a list of uploaded files. Clicking on one of these files will display it in the browser as html with a default style template. Users can also edit their files live in the browser.
In short, it is a markdown repository with visualizing capabilities similar to what VSCode can do, as well as editing functionality.
The App is deployed on Vercel, at markdown-reader.vercel.app, and the actual deployment repository as of right now is AITDeploy, due to this project being developed for one of my classes.
The application will store Users and Files.
- users can have multiple files (via a list of references)
- the File objects themselves will have references to the user that created them , the actual file binary, as well as metadata about upload-data (more metadata could be added in later iterations)
User {
username: //,
hash: //hashed password,
files: [] // a list of references to files owned by user
//possibly add email later
}
File {
name: //fileName for user reference,
owner: //reference to user that created the file,
data: //binary data of actual markdown file (possibly encrypted),
}
The database service used is MongoDB Atlas, connected to with Mongoose.
- as a non-registered user, I can register an account with username and password
- as a user, I can log in
- as a user, I can view my uploaded files
- as a user, I can upload new files
- as a user, I can delete an uploaded file
- as a user, I can edit my files in the app and save changes
-
NextJS
- I think I have a decent working understanding of the fundamentals of the App Router, Data Fetching, and Middleware, and I shall be adding details here as I learn.
- Next uses file based routing using folders nested in
app
. Each folder has a correspondinglayout.ts
(where components are rendered),page.tsx
(where the actual jsx is created), andtemplate.ts
(which is a more dynamic layout). - There is also an option to write route handlers, which basically perform express functionality.
- Middleware is configured in a
middleware.ts
file, which runs before components are rendered. Next providesNextRequest
andNextResponse
types, which build upon the built inRequest
andResponse
browser API's.- IMPORTANT FACT I DID NOT REALIZE BEFORE: middleware runs as an "edge function", which means that it uses vercel's edge runtime, which is a trimmed down version of node. As such, not every node module is supported here, so it's very important to be mindful of this when writing middleware.
- There are two kinds of components, server and client, which come with different advantages and drawbacks. Main difference is that server side components are rendered exclusively on the server (either statically at build time or dynamically at request time, depending on the functionality), so they don't have access to browser api's, async functions, and standard hooks (
useState, useEffect
). Client components on the other hand can be rendered on the client (like normal React), so they have access to these apis. Furthermore, server components do not rerender without a request or redirect, while client components do. - There is also something called a server action, which allows you to post forms to routes without actual api endpoints. That means that in a form's
action
prop, I can simply pass in an async function that runs on the server, without creating a route for the execution of that code. It can also most of what api-routes can do, just without needing an actual endpoint. Pretty neat! (although can be buggy, even though Next says they are stable - they are NOT)
-
JWT Authentication with Jose
- I have decided to give up NextAuthJs, as I kept running into issue after issue.
- I will be using a simple username-password jwt based authentication sytem.
- User can register an account with username and password.
- The user logs in with username and password and, if successful, receives a jwt token that authenticates him.
- The token stores his mongodb
ObjectID
, and username. - Currently, there is no protection against CSRF or any mechanism to revoke the token, or any plans to implement this.
- The library I will be using for JSON web tokens is
jose
, because it runs on the edge runtime, which allows me to use it in middleware
- Jose specific information:
- the library provides standard functions to encode and decode JWT tokens like
decodeJWT, encodeJWT
and so forth - i assigned this rubric 2 points as it involved both using the library and understanding what token based authentication is
- the library provides standard functions to encode and decode JWT tokens like
-
Showdown: Server Side
- The actual markdown to html parser.
- This one is very straightfoward to use. Pass in the markdown, get back the html.
-
Universal Cookie: Client Side
- Library to modify client side cookies.
- It works very similarly to next's built in
cookie()
function. - I used this because the built in
document.cookie
does not parse cookies for you, and I am also weary of accessing the dom directly when using react.
-
NextJS
-
Jose/JWT Authentication
-
Universal cookie
-
Showdown