Add files via upload

This commit is contained in:
Akif Yüce 2022-02-26 21:12:54 +03:00 committed by GitHub
parent 651840ab65
commit 8609e9bddd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 3107 additions and 0 deletions

30
index.js Normal file
View File

@ -0,0 +1,30 @@
const express = require('express');
const bodyParser = require('body-parser');
const path = require("path");
const fs = require("fs");
const session = require('express-session');
const error = require("./errors/error.js")
const app = express();
app.use(session({ secret: 'secret', resave: true, saveUninitialized: true }));
app.use(express.static(path.join(__dirname, "public")));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json());
app.set('views', path.join(__dirname, 'views'));
app.set("view engine", "ejs");
//Temp:
app.get("/", (req, res) => res.redirect("/index"));
for (const type of fs.readdirSync("./routes"))
for (const file of fs.readdirSync("./routes/" + type))
app[type](`/${file.replace(".js", "")}*`, require(`./routes/${type}/${file}`))
app.get('*', (req, res) => error(res, 404, "We have not got this page."));
app.post('*', (req, res) => error(res, 404, "We have not got this page."));
const port = process.env.PORT || 3000;
app.listen(port, () => console.log("SERVER ON PORT:", port));

BIN
json.sqlite Normal file

Binary file not shown.

2309
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "akf-forum",
"version": "2.0.0",
"description": "A Node.js based forum software",
"main": "index.js",
"scripts": {
"start": "node index.js",
"restart": "node reset.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Akif9748/akf-forum.git"
},
"author": "Akif9748",
"license": "GPL-3.0-or-later",
"bugs": {
"url": "https://github.com/Akif9748/akf-forum/issues"
},
"homepage": "https://github.com/Akif9748/akf-forum#readme",
"dependencies": {
"body-parser": "^1.19.2",
"ejs": "^3.1.6",
"express": "^4.17.3",
"express-session": "^1.17.2",
"quick.db": "^7.1.3"
}
}

117
public/css/styles.css Normal file
View File

@ -0,0 +1,117 @@
img.yuvarlak {
border-radius: 50%;
height: 30px;
width: 30px;
object-fit: cover;
}
img.logo {
width: 266px;
height: 75px;
display: inline;
}
textarea {
font-family: monospace;
background-color: #262626;
border: 2px solid #444444;
color: #BCBCBC;
width: auto;
height: auto;
cursor: pointer;
}
p {
font-size: 25px;
}
hr {
border-color: #444444;
border: 0;
border-top: 1px solid #eee;
margin: 20px 0;
}
body,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: monospace;
background: #262626;
color: #bcbcbc;
max-width: 69rem;
margin: auto;
margin-top: 10px;
/* funny number */
}
a:link {
color: #5f87af;
}
a:hover {
color: #af5f5f;
}
a:visited {
color: #8787af;
}
a:active {
color: #af5f5f;
}
pre {
background-color: #1c1c1c;
padding: 1em;
border: 0;
}
h1,
h2,
h3,
h4,
h5 {
margin-bottom: 0.1rem;
}
hr {
border-color: #444444;
}
button, input {
font-family: monospace;
background-color: #262626;
border: 2px solid #444444;
color: #BCBCBC;
width: auto;
height: 30px;
}
button.buyuk {
width: 150px;
height: 50px;
}
input {
width: 75%;
cursor: pointer;
color: #bcbcbc;
}
button:hover {
background-color: #BCBCBC;
color: #262626;
}
.mainpage {
padding: 10px;
float: right;
}

BIN
public/images/favicon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
public/images/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
public/images/guest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
public/images/logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

4
reset.js Normal file
View File

@ -0,0 +1,4 @@
const { set } = require("quick.db");
set("users", new Array());
set("threads", new Array());
set("secret", new Object());

View File

@ -0,0 +1,10 @@
const { User } = require("../../classes/index");
module.exports = (req, res) => {
if (!req.session.loggedin) return res.redirect('/login');
const user = new User().getId(req.session.userid)
res.render("openThread", { user })
}

12
routes/get/index.js Normal file
View File

@ -0,0 +1,12 @@
const { User } = require("../../classes/index");
const { get } = require("quick.db")
module.exports = (req, res) => {
if (!req.session.loggedin) return res.redirect('/login');
const mem = process.memoryUsage().heapUsed / Math.pow(2, 20);
const users = get("users").length;
const threads = get("threads").length;
const user = new User().getId(req.session.userid)
res.render("index", { mem, user, users, threads })
}

1
routes/get/login.js Normal file
View File

@ -0,0 +1 @@
module.exports = (req,res)=> res.render("login");

1
routes/get/register.js Normal file
View File

@ -0,0 +1 @@
module.exports = (req,res)=> res.render("register");

23
routes/get/threads.js Normal file
View File

@ -0,0 +1,23 @@
const { Thread, Message, User } = require("../../classes/index");
const db = require("quick.db");
const error = require("../../errors/error.js")
module.exports = (req,res) =>{
if (!req.session.loggedin) return res.redirect('/login');
const id = req.url.slice(9);
const user = new User().getId(req.session.userid);
if (!id) {
const threads = db.get("threads").slice(0, 10)
const links = threads.map(thread => "/threads/" + threads.indexOf(thread))
return res.render("threads", { threads, links, user })
}
const thread = new Thread().getId(id);
if (thread)
res.render("thread", { thread, user })
else
error(res, 404, "We have not got this thread.");
}

28
routes/get/users.js Normal file
View File

@ -0,0 +1,28 @@
const { Thread, Message, User } = require("../../classes/index");
const db = require("quick.db");
const error = require("../../errors/error.js")
module.exports = (req,res) =>{
if (!req.session.loggedin) return res.redirect('/login');
const user = new User().getId(req.session.userid)
const id = req.url.slice(7);
if (!id) {
const users = db.get("users").slice(0, 10);
const links = users.map(user => "/users/" + user.id)
return res.render("users", { users, links, user })
}
const member = new User().getId(id);
if (member)
res.render("user", { user, member })
else
error(res, 404, "We have not got this user.");
}

View File

@ -0,0 +1,12 @@
const { User, Thread } = require("../../classes/index");
module.exports = (req, res) => {
if (!req.session.loggedin) return res.redirect('/login');
const info = req.body;
const thread = new Thread(info.title, info.content, new User().getId(req.session.userid)).takeId();
thread.write()
res.redirect('/threads/' + thread.id);
}

29
routes/post/login.js Normal file
View File

@ -0,0 +1,29 @@
const db = require("quick.db");
const error = require("../../errors/error.js")
module.exports = (req, res) => {
let username = req.body.username;
let password = req.body.password;
if (username && password) {
const user = db.get("secret." + username)
if (user) {
// Authenticate the user
if (user.key !== password) return error(res, 404, 'Incorrect Password!')
req.session.loggedin = true;
req.session.username = username;
req.session.userid = user.id;
res.redirect('/');
} else
error(res, 404, 'Incorrect Username and/or Password!')
} else
error(res, 404, "You forgot entering some values")
}

31
routes/post/register.js Normal file
View File

@ -0,0 +1,31 @@
const db = require("quick.db");
const error = require("../../errors/error.js")
const { User } = require("../../classes/index");
module.exports = (req, res) => {
let username = req.body.username;
let password = req.body.password;
if (username && password) {
const user = db.get("secret." + username)
if (user) {
error(res, 404, `We have got an user named ${username}!`)
} else {
let avatar = req.body.avatar || "/images/guest.png"
const user2 = new User(req.body.username, avatar).takeId()
db.set("secret." + username, { id: user2.id, key: password })
req.session.loggedin = true;
req.session.username = username;
req.session.userid = user2.id;
user2.write()
res.redirect('/');
}
} else
error(res, 404, "You forgot entering some values")
}

19
routes/post/threads.js Normal file
View File

@ -0,0 +1,19 @@
const { Thread, Message, User } = require("../../classes/index");
const error = require("../../errors/error.js")
module.exports = (req, res) => {
if (!req.session.loggedin) return res.redirect('/login');
const id = req.url.slice(9);
const thread = new Thread().getId(id);
if (thread) {
thread.push(new Message(req.body.content, new User().getId(req.session.userid)))
thread.write();
res.redirect('/threads/' + id);
}
else
error(res, 404, "We have not got this thread.");
}

36
views/error.ejs Normal file
View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= type %></title>
<meta name="description" content="Akf-forum has not got this page!">
<meta name="author" content="Akif9748">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body >
<!-- Navbar: -->
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a><br>
<button class="buyuk"
onclick="window.location.href = '/'">MAIN PAGE</button>
<hr>
<!-- Navbar end -->
<h1><%= type %></h1>
<h2><%= error %></h2>
</body>
</html>

52
views/index.ejs Normal file
View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Main page!</title>
<meta name="description" content="Akf-forum!">
<meta name="author" content="Akif9748">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body>
<!-- Navbar: -->
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a>
<br> <button class="buyuk" onclick="window.location.href = '/threads'">THREADS</button>
<button class="buyuk" onclick="window.location.href = '/search'">SEARCH</button>
<button class="buyuk" onclick="window.location.href = '/users'">USERS</button>
<button class="buyuk" onclick="window.location.href = '/createThread/'">OPEN THREAD</button>
<h1 style="display:inline; float:right;"><a href=<%=user.getLink() %>> <%= user.name %></a>
<img class="yuvarlak" src=<%=user.avatar %> alt=<%= user.name %>>
</h1>
<hr>
<!-- Navbar end -->
<h1>Welcome, <a href=<%=user.getLink() %>> <%= user.name %></a>
<img class="yuvarlak" src=<%=user.avatar %> alt=<%= user.name %>>
</h1>
<br>
<h1>Statics:</h1>
<ul>
<li>
<h3>User count: <b> <%= users %> </b></h3>
</li>
<li>
<h3>Thread count: <b> <%= threads %></b></h3>
</li>
<li>
<h3>Memory usage: <b> <%= mem.toFixed(2); %> MB </b></h3>
</li>
</ul>
</body>
</html>

35
views/login.ejs Normal file
View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>LOGIN</title>
<meta name="description" content="Akf-forum!">
<meta name="author" content="Akif9748">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body>
<!-- Navbar: -->
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a>
<br>
<button class="buyuk" onclick="window.location.href = '/register'">REGISTER PAGE</button>
<hr>
<h1>Login</h1>
<hr>
<form action="/login" method="post">
<input type="text" name="username" placeholder="Username" id="username" required>
<input type="password" name="password" placeholder="Password" id="password" required>
<input type="submit" value="Login">
</form>
</body>
</html>

47
views/openThread.ejs Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Open Thread</title>
<meta name="description" content="Akf-forum!">
<meta name="author" content="Akif9748">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body>
<!-- Navbar: -->
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a>
<br> <button class="buyuk" onclick="window.location.href = '/threads'">THREADS</button>
<button class="buyuk" onclick="window.location.href = '/search'">SEARCH</button>
<button class="buyuk" onclick="window.location.href = '/users'">USERS</button>
<h1 style="display:inline; float:right;"><a href=<%=user.getLink() %>> <%= user.name %></a>
<img class="yuvarlak" src=<%=user.avatar %> alt=<%= user.name %>>
</h1>
<hr>
<!-- Navbar end -->
<form action="/createThread/" method="POST">
<h2>Title:</h2>
<input name="title"></input>
<hr>
<h2>Content:</h2>
<textarea rows="4" cols="50" name="content"></textarea>
<hr>
<button class = "buyuk" type="submit">Open Thread!</button>
</form>
</body>
</html>

43
views/register.ejs Normal file
View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Register</title>
<meta name="description" content="Akf-forum!">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body>
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a>
<br>
<button class="buyuk" onclick="window.location.href = '/login'">LOGIN PAGE</button>
<hr>
<h1>Register</h1>
<hr>
<form action="/register" method="post">
<input type="text" name="username" placeholder="Username" id="username" required>
<input type="password" name="password" placeholder="Password" id="password" required>
<input type="text" name="avatar" placeholder="Avatar URL" id="avatar">
<input type="submit" value="Register">
</form>
</body>
</html>

87
views/thread.ejs Normal file
View File

@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
<%= thread.title %>
</title>
<meta name="description" content="Akf-forum!">
<meta name="author" content="Akif9748">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body>
<!-- Navbar: -->
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a>
<br> <button class="buyuk" onclick="window.location.href = '/threads'">THREADS</button>
<button class="buyuk" onclick="window.location.href = '/search'">SEARCH</button>
<button class="buyuk" onclick="window.location.href = '/users'">USERS</button>
<button class="buyuk" onclick="window.location.href = '/createThread/'">OPEN THREAD</button>
<h1 style="display:inline; float:right;"><a href=<%=user.getLink() %>> <%= user.name %></a>
<img class="yuvarlak" src=<%=user.avatar %> alt=<%= user.name %>>
</h1>
<hr>
<!-- Navbar end -->
<h1 style="font-size: 35px;">
<%= thread.title %>
</h1>
<div style="border: 2px solid #444444; padding: 5px;">
<h2>
<img class="yuvarlak" src=<%=thread.author.avatar %> alt=<%= thread.author.name %>>
<a style=" color: #bcbcbc; " href=<%= "/users/"+ thread.author.id %>> <%= thread.author.name %></a>:
</h2>
<p>
<%= thread.content %>
</p>
<h3 style=" text-align:right;">
<%=new Date(thread.time).toLocaleString() %>
</h3>
</div>
<br>
<% thread.messages.forEach(message=>{ %>
<div style="border: 2px solid #444444; padding: 5px;">
<h2>
<img class="yuvarlak" src=<%=message.author.avatar %> alt=<%= message.author.name %>>
<a style=" color: #bcbcbc; " href=<%= "/users/"+ message.author.id %>> <%= message.author.name %></a>:
</h2>
<h2>
<%= message.content %>
</h2>
<h3 style=" text-align:right;">
<%=new Date(message.time).toLocaleString() %>
</h3>
</div>
<br>
<% }); %>
<hr>
<form action="/threads/<%= thread.id %>" method="POST">
<textarea rows="4" cols="50" name="content"></textarea>
<br>
<button class="button" type="submit">Send!</button>
</form>
</body>
</html>

44
views/threads.ejs Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Main page!</title>
<meta name="description" content="Akf-forum!">
<meta name="author" content="Akif9748">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body>
<!-- Navbar: -->
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a>
<br>
<button class="buyuk" onclick="window.location.href = '/search'">SEARCH</button>
<button class="buyuk" onclick="window.location.href = '/users'">USERS</button>
<button class="buyuk" onclick="window.location.href = '/createThread/'">OPEN THREAD</button>
<h1 style="display:inline; float:right;"><a href=<%=user.getLink() %>> <%= user.name %></a>
<img class="yuvarlak" src=<%=user.avatar %> alt=<%= user.name %>>
</h1>
<hr>
<!-- Navbar end -->
<h1>Threads:</h1>
<ul>
<% threads.forEach(thread=>{ %>
<li>
<h1><a href=<%=links[threads.indexOf(thread)] %> > <%= thread.title %> by <%= thread.author.name %></a>
</h1>
</li>
<% }); %>
</ul>
</body>
</html>

64
views/user.ejs Normal file
View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
<%= member.name %>
</title>
<meta name="description" content="Akf-forum user page!">
<meta name="author" content="Akif9748">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body>
<!-- Navbar: -->
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a>
<br>
<button class="buyuk" onclick="window.location.href = '/threads'">THREADS</button>
<button class="buyuk" onclick="window.location.href = '/search'">SEARCH</button>
<button class="buyuk" onclick="window.location.href = '/users'">USERS</button>
<button class="buyuk" onclick="window.location.href = '/createThread/'">OPEN THREAD</button>
<h1 style="display:inline; float:right;"><a href=<%=user.getLink() %>> <%= user.name %></a>
<img class="yuvarlak" src=<%=user.avatar %> alt=<%= user.name %>>
</h1>
<hr>
<!-- Navbar end -->
<h1>Avatar:</h1>
<img style="width:256px;height:256px;" src=<%=member.avatar %> alt=<%= member.name %>>
<hr>
<h1>Name:</h1>
<p>
<%= member.name %>
</p>
<hr>
<h1>Created at:</h1>
<p>
<%= new Date(member.time).toLocaleString() %>
</p>
</body>
</html>

46
views/users.ejs Normal file
View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/css/styles.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Users!</title>
<meta name="description" content="Akf-forum users!">
<meta name="author" content="Akif9748">
<link rel="icon" type="image/x-icon" href="/images/favicon.jpg">
</head>
<body>
<!-- Navbar: -->
<a href="/"><img class="logo" src="/images/logo.jpg" alt="AKF-FORUM"></a>
<br>
<button class="buyuk" onclick="window.location.href = '/threads'">THREADS</button>
<button class="buyuk" onclick="window.location.href = '/search'">SEARCH</button>
<button class="buyuk" onclick="window.location.href = '/createThread/'">OPEN THREAD</button>
<h1 style="display:inline; float:right;"><a href=<%=user.getLink() %>> <%= user.name %></a>
<img class="yuvarlak" src=<%=user.avatar %> alt=<%= user.name %>>
</h1>
<hr>
<!-- Navbar end -->
<h1>USERS:</h1>
<ul>
<% users.forEach(user=>{ %>
<li>
<h1><a href=<%=links[user.id] %> > <%= user.name %></a>
<img class="yuvarlak" src=<%=user.avatar %> alt=<%= user.name %>>
</h1>
</li>
<% }); %>
</ul>
</body>
</html>