153 Internship Report
153 Internship Report
on
Web Development
submitted in partial fulfillment for the reward of degree
BACHELOR OF ENGINEERING
In
By
This is to certify that the internship titled “Web Development” is the work
carried out by MOHAMMAD ADNAN bearing roll no. 160120733153, a student of
B.E. (CSE) of Chaitanya Bharathi Institute of Technology(A), Hyderabad, affiliated to
Osmania University, Hyderabad, Telangana, India, during the academic year 2022-
2023.
Place:
Date:
2
DECLARATION
MOHAMMAD ADNAN
Place: Hyderabad
Date: 10-01-2022
3
Table of Contents
1. INTRODUCTION 6
1.1 Problem Definition including the significance and objective 6
1.2 Methodologies 6
1.3 Outline of Result 6
1.4 Future Scope of Project
2. REQUIREMENT SPECIFICATION 8
2.1 Concepts Required 8
3. 11
3.1 WD201 Levels 11
12
4
ABSTRACT
The Web development 101 course is for beginners in programming & web development,
who are looking forward to build a robust foundation in computational thinking. And the
continuation of the course is another course called Web development 201, which is Server-
side programming with Node.js.
A web-based tool called To-do List enables you to efficiently keep track of when your work
is due, which may help you prioritize and do excellent work.
For the front end, which is the user interface, HTML, CSS, and JavaScript are used. The
backend development of this to-do application, which connects to the database and makes
requests and responses with the server, was created using NodeJS.
5
ACKNOWLEDGEMENTS
We have taken efforts in this project. However, it would not have been
possible without the kind support and help of many individuals. I would like to
extend my sincere thanks to all of them who helped us in completing the project,
specifically to Dr. Rama Devi mam CSE Dept.HOD. It has been a great honor
and a privilege to undergo training and internship at Pupilfirst. We are highly
indebted to our mentors for their guidance and constant supervision as well as
for providing necessary information regarding the project and also for their support
in completing the project. My thanks and appreciations also go to my colleagues in
developing the project and people who have willingly helped me out with their
abilities and guidance.
6
1. INTRODUCTION
1.2. Methodology
There are numerous ways to go about creating a website. I've learned the fundamentals
of Node.js and database applications utilizing Sequelize through my project, which I
carried out step-by-step. I created a to-do application based on NodeJS. The projects'
GitHub connections have been provided for each level, and at levels 7 and 8, apps have
been deployed as web services using render software which is Paas used to render the
web application .
7
2. REQUIRED CONCEPTS
1. HTML :
HTML stands for Hyper Text Markup Language. It is the standard markup
language for creating Web pages. HTML describes the structure of a Web page.HTML
consists of a series of elements. HTML elements tell the browser how to display the
content.HTML elements label pieces of content such as "this is a heading", "this is a
paragraph", "this is a link".
2. CSS:
CSS stands for Cascading Style Sheet. CSS is used to define styles for your web
pages, including the design, layout and variations in display for different devices and screen
sizes.
3. JavaScript:
JavaScript is a Programming Language, that runs on the end user's browser, and
allows us to calculate, manipulate and validate data. Where HTML and CSS are
languages that give structure and style to web pages, JavaScript improves the user
experience of the web page by converting it from a static page into an interactive one.
4. NODEJS:
Node.js is a runtime environment for writing server-side JavaScript applications. Node.js is
open-source and completely free, it's used by thousands of developers around the world. Node
is often used to build back-end services that communicate with client-side applications.
5. EXPRESSJS:
Express.js is a fast and lightweight framework, used majorly for web application
development. Express is built on top of Node.js. It is designed to develop websites, web apps, &
API‟s easily. With that being said, let's create our first ever Express application.
6. POSTGRE SQL:
PostgreSQL is one of the most advanced general-purpose object-relational
database management system and is open-source. Being an open-source software, its
source code is available under PostgreSQL license, a liberal open source license.
Anyone with the right skills is free to use, modify, & distribute Postgre SQL in any form.
8
3. WD-201 LEVELS
LEVEL - 2:
Create a new file called package.json and manually enter the configuration.
Use the npm CLI, to generate one for us automatically.
npm website – used for finding packages, creating profiles, and managing other
aspects of our npm usage.
CLI or a Command Line Interface (CLI) – used to interact with npm and is run
from a Terminal/Command Prompt.
npm registry – used as the public database of JavaScript
software/dependencies.
9
LEVEL - 3:
Due today
Due later
Over due
Above functions have to be created
LEVEL-4:
LEVEL-5:
10
LEVEL-6:
Express.js is a fast and lightweight framework, used majorly for web application
development. Express is built on top of Node.js. It is designed to develop
websites, web apps, & API‟s easily.
The app.listen() function tells the server to start listening for connections on a
particular port, in this case, port 3000.
we've defined the route to delete a To-Do by its id (DELETE /todos/:id). You have
to complete the implementation for that.
Also write tests for this DELETE /todos/:id endpoint using JEST.
LEVEL-7:
LEVEL-8:
Add a new EJS template todos.ejs in the views folder. This will have the UI for
listing all to-dos in three sections. Import this partial todos.ejs to the main index.ejs
template to render the list of to-dos. This is similar to how header.ejs was imported
to index.ejs to show the application title.
Todo items should be fetched from the database and rendered in different
sections.
Display the count of items in each section after the title (Overdue, Due Today, Due
Later)
Contains a header h1 tag with the title of the applicatio
11
LEVEL-9:
LEVEL - 10:
12
4. IMPLEMENTATION OF TO-DO
1.
Install NVM, NPM
curl -sL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh -o
install_nvm.sh
nvm install -lts
2.
Create Package.json
A new directory has to be created first.
npm init
npm config set init-author-name "Jane Doe" --location=global
npm config set init-author-email "[email protected]" --location=global
package.json:
{
"name": "todo-manager",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon -e js,ejs",
"start:prod": "node index.js",
"pretest": "NODE_ENV=test npx sequelize-cli db:drop && NODE_ENV=test npx
sequelize-cli db:create",
"test": "NODE_ENV=test jest --detectOpenHandles",
"prepare": "husky install"
},
"lint-staged": {
"*.js": [
"eslint",
"prettier --write ."
]
},
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.0",
"connect-ensure-login": "^0.1.1",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.6",
"ejs": "^3.1.8",
"express": "^4.18.1",
"express-session": "^1.17.3",
13
"passport": "^0.6.0",
"passport-local": "^1.0.0",
"pg": "^8.8.0",
"sequelize": "^6.23.0",
"tiny-csrf": "^1.1.3"
},
"devDependencies": {
"cheerio": "^1.0.0-rc.12",
"eslint": "^8.24.0",
"husky": "^8.0.1",
"jest": "^29.1.1",
"lint-staged": "^13.0.3",
"nodemon": "^2.0.20",
"prettier": "^2.7.1",
"sequelize-cli": "^6.4.1",
"supertest": "^6.2.4"
}
}
3.
Create Event Loop, Overdue, Duetoday, Completed Functions
setTimeout(() => {
// callback function
}, milliseconds);
__tests__/todo.js:
const db = require("../models/index");
const app = require("../app");
let server;
let agent;
afterAll(async () => {
try {
await db.sequelize.close();
await server.close();
14
} catch (error) {
console.log(error);
}
});
test("Creates a todo and responds with json at /todos POST endpoint", async () => {
const response = await agent.post("/todos").send({
title: "Buy Chocolate",
dueDate: new Date().toISOString(),
completed: false,
});
expect(response.statusCode).toBe(200);
expect(response.header["content-type"]).toBe(
"application/json; charset=utf-8"
);
const parsedResponse = JSON.parse(response.text);
expect(parsedResponse.id).toBeDefined();
});
test("Fetches all todos in the database using /todos endpoint", async () => {
await agent.post("/todos").send({
title: "Buy xbox",
dueDate: new Date().toISOString(),
completed: false,
});
await agent.post("/todos").send({
title: "Buy ps3",
dueDate: new Date().toISOString(),
completed: false,
15
});
const response = await agent.get("/todos");
const parsedResponse = JSON.parse(response.text);
expect(parsedResponse.length).toBe(4);
expect(parsedResponse[3]["title"]).toBe("Buy ps3");
});
test("Deletes a todo with the given ID if it exists and sends a boolean response", async
() => {
// FILL IN YOUR CODE HERE
const response = await agent.post("/todos").send({
title: "Buy xbox",
dueDate: new Date().toISOString(),
completed: false,
});
const parsedResponse = JSON.parse(response.text);
const todoID = parsedResponse.id;
4.
Create husky to add a pre-commit hook to our project.
16
5.
Connect Postgre Sql with NodeJS and create Models
Index.js:
// eslint-disable-next-line no-undef
app.listen(process.env.PORT || 3000, () => {
console.log("Started express server at port 3000");
});
Todo.js:
function extractCsrfToken(res) {
var $ = cheerio.load(res.text);
return $("[name=_csrf]").val();
}
17
afterAll(async () => {
try {
await db.sequelize.close();
await server.close();
} catch (error) {
console.log(error);
}
});
18
test("A test for marking a todo as complete", async () => {
const agent = request.agent(server);
await login(agent, "[email protected]", "12345678");
let res = await agent.get("/todos");
let csrfToken = extractCsrfToken(res);
await agent.post("/todos").send({
title: "Completed Studying for Mids ",
dueDate: new Date().toISOString(),
completed: false,
_csrf: csrfToken,
});
19
.set("Accept", "application/json");
const parsedGroupedResponse = JSON.parse(groupedTodosResponse.text);
const dueTodayCount = parsedGroupedResponse.dueToday.length;
const latestTodo = parsedGroupedResponse.dueToday[dueTodayCount - 1];
20
res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);
//Additional Changes
//One of the user cannot mark as complete or incomplete a todo of another user
test("One of the user cannot mark as complete or incomplete a todo of another user",
async () => {
//creating UserA account
let res = await agent.get("/signup");
let csrfToken = extractCsrfToken(res);
res = await agent.post("/users").send({
firstName: "test",
lastName: "User A",
email: "[email protected]",
password: "123456789",
_csrf: csrfToken,
});
//create Todo from UserA account
res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);
res = await agent.post("/todos").send({
title: "Buy the necessary Stationary",
dueDate: new Date().toISOString(),
completed: false,
_csrf: csrfToken,
});
const idOfTodoFromUserA1 = res.id;
//Signout UserA
await agent.get("/signout");
//Create UserB account
res = await agent.get("/signup");
csrfToken = extractCsrfToken(res);
res = await agent.post("/users").send({
firstName: "test",
lastName: "User B",
email: "[email protected]",
password: "123456",
_csrf: csrfToken,
21
});
//Try markAsComplete on UserA Todo from UserB account
res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);
const markCompleteResponse = await agent
.put(`/todos/${idOfTodoFromUserA1}`)
.send({
_csrf: csrfToken,
completed: true,
});
expect(markCompleteResponse.statusCode).toBe(422);
//Try markAsIncomplete on UserA Todo from UserB account
res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);
const markIncompleteResponse11 = await agent
.put(`/todos/${idOfTodoFromUserA1}`)
.send({
_csrf: csrfToken,
completed: false,
});
expect(markIncompleteResponse11.statusCode).toBe(422);
});
22
const idOfTodoFromUserA2 = res.id;
//Signing out from UserA
await agent.get("/signout");
//Creating an UserB account
res = await agent.get("/signup");
csrfToken = extractCsrfToken(res);
res = await agent.post("/users").send({
firstName: "Test",
lastName: "User D",
email: "[email protected]",
password: "12345678",
_csrf: csrfToken,
});
6.
Express module installed Via NPM
app.js:
23
const LocalStratergy = require("passport-local");
app.use(
session({
secret: "my-super-secret-key-2837428907583420",
cookie: {
maxAge: 24 * 60 * 60 * 1000,
},
})
);
passport.use(
new LocalStratergy(
{
usernameField: "email",
passwordField: "password",
},
(username, password, done) => {
User.findOne({ where: { email: username } })
.then(async (user) => {
const result = await bcrypt.compare(password, user.password);
if (result) {
return done(null, user);
} else {
return done(null, false, { message: "Password is invalid!!!" });
}
})
.catch(() => {
return done(null, false, { message: "EmailID is invalid" });
});
}
)
);
24
//serializing the user
passport.serializeUser((user, done) => {
console.log("Serialize use in session", user.id);
done(null, user.id);
});
app.get("/todos",
connectEnsureLogin.ensureLoggedIn(),
async function (request, response) {
try {
const userName = request.user.firstName + " " + request.user.lastName;
const loggedIn = request.user.id;
const overDue = await Todo.overDue(loggedIn);
const dueToday = await Todo.dueToday(loggedIn);
const dueLater = await Todo.dueLater(loggedIn);
const completedItems = await Todo.completedItemsAre(loggedIn);
if (request.accepts("html")) {
response.render("todos", {
title: "To-Do Manager",
userName,
25
overDue,
dueToday,
dueLater,
completedItems,
csrfToken: request.csrfToken(),
});
} else {
response.json({
overDue,dueToday,dueLater,completedItems,
});
}
} catch (err1) {
console.log(err1);
return response.status(422).json(err1);
}
}
);
26
}
});
} catch (errori) {
request.flash("error", errori.message);
return response.redirect("/signup");
}
});
27
return response.json(todo1);
} catch (error2) {
console.log(error2);
return response.status(422).json(error2);
}
}
);
28
//Route for deleting
app.delete("/todos/:id",
connectEnsureLogin.ensureLoggedIn(),
async function (req, resp) {
console.log("Delete a todo with a particular id : ", req.params.id);
// FILL IN YOUR CODE HERE
try {
const res = await Todo.remove(req.params.id, req.user.id);
return res.json({ success: res === 1 });
} catch (error1) {
console.log(error1);
return resp.status(422).json(error1);
}
}
);
module.exports = app;
7.
Creating EJS Template:
Header.ejs:
Index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="<%= csrfToken %>">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="./css/style.css">
<title><%= title %></title>
</head>
<body>
<div class="grid grid-cols-6 my-10">
<div class="col-start-3 col-span-2">
<%- include('header.ejs') %>
<p class="py-3">Welcome to My Todo Manager</p>
<p class="py-3">Are you new here?<a class="text-blue-700" href="/signup">sign-
up</a></p>
<p class="py-3">Do you already have an account?<a class="text-blue-600"
29
href="/login">sign-in</a></p>
</div>
</div>
</body>
</html>
Todos.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="<%= csrfToken %>">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="./css/style.css">
<title><%= title %></title>
<style>
#bt{
border-radius: 50px;
}
</style>
<script>
var token = document.querySelector('meta[name="csrf-
token"]').getAttribute("content");
function deleteATodo(id) {
fetch(`/todos/${id}`, {
method: "delete",
headers: {"Content-Type":"application/json"},
body: JSON.stringify({
"_csrf":token
})
}).then((res)=>{
if (res.ok) {
window.location.reload();
}
}).catch((err2)=> console.error(err2))
}
function updateATodo(id, status) {
fetch(`/todos/${id}`, {
method: "put",
headers: {"Content-Type":"application/json"},
body: JSON.stringify({
"_csrf":token,
30
"completed":status
})
}).then((res)=>{
if (res.ok) {
window.location.reload();
}
}).catch((err1)=> console.error(err1))
}
</script>
</head>
<body>
<div class="grid grid-cols-6">
<div class="col-start-3 col-span-2">
<%- include('header.ejs') %>
<p class="text-gray-600 my-1">Hello <%= userName %></p>
<a class="text-green-600" href="/signout">sign out</a>
<form action="/todos" method="post">
<input type="hidden" name="_csrf" value="<%= csrfToken %>" />
<div class="flex gap-2 py-4">
<div class="flex-auto">
<input type="text" name="title" placeholder="What's next?" class="border
border-gray-300 text-gray-900 w-full rounded p-3 text-sm" required />
</div>
<div class="flex-auto">
<input type="date" name="dueDate" class="border border-gray-300 text-
gray-900 w-full rounded p-2 text-sm leading-4" />
</div>
<div class="flex-none">
<button type="submit" id="bt" class="bg-green-600 text-white px-5 py-1.5
rounded mr-2 mb-2">Add Todo</button>
</div>
</div>
</form>
<div>
<% if (messages && messages.error && messages.error.length > 0) { %>
<% for(var i=0; i<messages.error.length; i++) { %>
<p class="bg-red-100 my-3 list-none rounded px-4 py-2"><%=
messages.error[i] %></p>
<% } %>
<% } %>
</div>
<div>
<%- include('todo.ejs', {title: "Overdue", data: overDue}) %>
<%- include('todo.ejs', {title: "Due Today", data: dueToday}) %>
<%- include('todo.ejs', {title: "Due Later", data: dueLater}) %>
<%- include('todo.ejs', {title: "Completed Items", data: completedItems}) %>
</div>
</div>
</div>
</body>
</html>
31
8.
Deploying Application Online using render:
Render is a PaaS that lets companies build, deliver, monitor and scale apps.
Update Production inside the Config.json
config.json:
{
"development": {
"username": "postgres",
"password": "postgres",
"database": "wd-todo-dev",
"host": "127.0.0.1",
"dialect": "postgres"
},
"test": {
"username": "postgres",
"password": "postgres",
"database": "wd-todo-test",
"host": "127.0.0.1",
"dialect": "postgres"
},
"production": {
"use_env_variable": "DATABASE_URL",
"dialect": "postgres"
}
}
32
5. RESULTS / OUTPUTS AND DISCUSSIONS
Home page:
User Authentication:
33
2. Log In Page:
34
After Adding into Todos list:
35
6. CONCLUSIONS / RECOMMENDATIONS
6.1 CONCLUSIONS:
That list of things you have to complete is one of the core time
management tools. It places all of your duties in one location. From there,
you may order them by importance and focus on the most crucial ones first
and no one can access it other that the user because it checks for the
authentication.
6.3 REFERENCES
36