initial commit
This commit is contained in:
commit
534d1a6d07
132
.gitignore
vendored
Normal file
132
.gitignore
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
cookiesecret.txt
|
||||
mysql_key.txt
|
||||
register.py
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
99
css/logon.css
Normal file
99
css/logon.css
Normal file
@ -0,0 +1,99 @@
|
||||
* {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
body {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
header {
|
||||
background-color: black;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 15vh;
|
||||
box-shadow: 5px 5px 10px rgb(0,0,0,0.3);
|
||||
}
|
||||
h1 {
|
||||
letter-spacing: 1.5vw;
|
||||
font-family: 'system-ui';
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
}
|
||||
main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 75vh;
|
||||
width: 100%;
|
||||
background: url(https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Mountains-1412683.svg/1280px-Mountains-1412683.svg.png) no-repeat center center;
|
||||
background-size: cover;
|
||||
}
|
||||
.form_class {
|
||||
width: 500px;
|
||||
padding: 40px;
|
||||
border-radius: 8px;
|
||||
background-color: white;
|
||||
font-family: 'system-ui';
|
||||
box-shadow: 5px 5px 10px rgb(0,0,0,0.3);
|
||||
}
|
||||
.form_div {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.form_div > label {
|
||||
letter-spacing: 3px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.info_div {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.info_div {
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.field_class {
|
||||
width: 100%;
|
||||
border-radius: 6px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 5px 0px;
|
||||
text-indent: 6px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
font-family: 'system-ui';
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.submit_class {
|
||||
border-style: none;
|
||||
border-radius: 5px;
|
||||
background-color: #FFE6D4;
|
||||
padding: 8px 20px;
|
||||
font-family: 'system-ui';
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .8px;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-top: 10px;
|
||||
box-shadow: 2px 2px 5px rgb(0,0,0,0.2);
|
||||
cursor: pointer;
|
||||
}
|
||||
footer {
|
||||
height: 10vh;
|
||||
background-color: black;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: -5px -5px 10px rgb(0,0,0,0.3);
|
||||
}
|
||||
footer > p {
|
||||
text-align: center;
|
||||
font-family: 'system-ui';
|
||||
letter-spacing: 3px;
|
||||
}
|
||||
footer > p > a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
47
css/main.css
Normal file
47
css/main.css
Normal file
@ -0,0 +1,47 @@
|
||||
* {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
body {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
header {
|
||||
background-color: black;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 15vh;
|
||||
box-shadow: 5px 5px 10px rgb(0,0,0,0.3);
|
||||
}
|
||||
h1 {
|
||||
letter-spacing: 1.5vw;
|
||||
font-family: 'system-ui';
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
}
|
||||
main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 75vh;
|
||||
width: 100%;
|
||||
background: url(https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Mountains-1412683.svg/1280px-Mountains-1412683.svg.png) no-repeat center center;
|
||||
background-size: cover;
|
||||
}
|
||||
.info_div {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.info_div {
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
footer {
|
||||
height: 10vh;
|
||||
background-color: black;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: -5px -5px 10px rgb(0,0,0,0.3);
|
||||
}
|
14
css/style.css
Normal file
14
css/style.css
Normal file
@ -0,0 +1,14 @@
|
||||
* {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: black;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 18px;
|
||||
margin: 10px;
|
||||
}
|
1526
package-lock.json
generated
Normal file
1526
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
package.json
Normal file
10
package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"body-parser": "^1.20.0",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"express": "^4.17.3",
|
||||
"express-fileupload": "^1.3.1",
|
||||
"express-useragent": "^1.0.15",
|
||||
"mysql": "^2.18.1"
|
||||
}
|
||||
}
|
273
server.js
Normal file
273
server.js
Normal file
@ -0,0 +1,273 @@
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const crypto = require("crypto");
|
||||
const express = require("express");
|
||||
const fs = require("fs");
|
||||
const router = express.Router();
|
||||
const redirrouter = express.Router();
|
||||
const app = express();
|
||||
const useragent = require('express-useragent');
|
||||
const fileUpload = require('express-fileupload');
|
||||
const bodyParser = require("body-parser");
|
||||
const cookieParser = require('cookie-parser');
|
||||
const signature = require('cookie-signature')
|
||||
const mysql = require('mysql');
|
||||
|
||||
const con = mysql.createConnection({
|
||||
host: "localhost",
|
||||
user: "root",
|
||||
password: fs.readFileSync("mysql_key.txt").toString()
|
||||
});
|
||||
|
||||
con.connect(function(err) {
|
||||
if (err) throw err;
|
||||
console.log("Connected!");
|
||||
});
|
||||
|
||||
const dir = __dirname + "/"
|
||||
|
||||
const cookiesecret = fs.readFileSync("cookiesecret.txt").toString()
|
||||
|
||||
function SHA256(str) {
|
||||
if(!str)return;
|
||||
return crypto
|
||||
.createHash("sha256")
|
||||
.update(str)
|
||||
.digest("base64");
|
||||
}
|
||||
|
||||
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function genstring(length) {
|
||||
var result = "";
|
||||
var characters =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
||||
var charactersLength = characters.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function clientErrorHandler(err, req, res, next) {
|
||||
if(err) {
|
||||
if (req.xhr) {
|
||||
res.status(200).send({ error: 'Something failed!' });
|
||||
} else {
|
||||
console.log(err);
|
||||
}
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
function getKeyByValue(object, value) {
|
||||
return Object.keys(object).find(key => object[key] === value);
|
||||
}
|
||||
|
||||
function unsign(text,req,res) {
|
||||
let ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress
|
||||
let unsigned = signature.unsign(text,cookiesecret+ip)
|
||||
if(!unsigned) {
|
||||
res.status(400)
|
||||
res.json({"error":"Bad auth cookie set"})
|
||||
}
|
||||
return unsigned
|
||||
}
|
||||
|
||||
app.use(useragent.express());
|
||||
app.use(fileUpload())
|
||||
app.use(bodyParser.json({ limit: "100mb" }));
|
||||
app.use(bodyParser.urlencoded({ limit: "100mb", extended: true }));
|
||||
app.use(clientErrorHandler);
|
||||
app.use(cookieParser(cookiesecret));
|
||||
|
||||
router.get("/",function(req,res) {
|
||||
res.sendFile(dir+"views/index.html")
|
||||
})
|
||||
|
||||
/*
|
||||
|
||||
START /API/*
|
||||
|
||||
*/
|
||||
|
||||
var API_CALLS = {}
|
||||
|
||||
function clear_api_calls() {
|
||||
API_CALLS = {}
|
||||
}
|
||||
setInterval(clear_api_calls, 10000)
|
||||
|
||||
function increaseAPICall(req,res,next) {
|
||||
let ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress
|
||||
if(API_CALLS[ip]==undefined)API_CALLS[ip]=0
|
||||
if(API_CALLS[ip] >= 20) {
|
||||
res.status(429)
|
||||
res.send("You are sending too many api calls!")
|
||||
console.log("rate limiting " + ip);
|
||||
return false
|
||||
}
|
||||
API_CALLS[ip]++;
|
||||
if(next)next()
|
||||
return true
|
||||
}
|
||||
|
||||
router.use("/api/*",async function(req,res,next) {
|
||||
increaseAPICall(req,res,next)
|
||||
})
|
||||
|
||||
router.get("/api/getuser",async function(req,res) {
|
||||
let cookie = req.cookies.AUTH_COOKIE
|
||||
if(!cookie){
|
||||
res.status(400)
|
||||
res.json({"error":"you are not logged in!"})
|
||||
return
|
||||
}
|
||||
let unsigned = unsign(cookie,req,res)
|
||||
|
||||
let values = unsigned.split(" ")
|
||||
let hashed_pw = values[1]
|
||||
let username = values[0]
|
||||
|
||||
for (let i = 0; i < 9999; i++) {
|
||||
hashed_pw = SHA256(hashed_pw)
|
||||
}
|
||||
|
||||
values[1] = hashed_pw
|
||||
|
||||
let sql = `select * from zerotwohub.users where User_Name=? and User_PW=?;`
|
||||
let sent_res = false
|
||||
con.query(sql, values, function (err, result) {
|
||||
if (err) throw err;
|
||||
if(result[0] && result[0].User_Name && result[0].User_Name == username) {
|
||||
res.json({"username":username})
|
||||
} else {
|
||||
res.json({"error":"you are not logged in!"})
|
||||
}
|
||||
sent_res = true
|
||||
});
|
||||
setTimeout(function(){if(!sent_res)res.json({"error":"timeout"})},3000);
|
||||
})
|
||||
|
||||
router.post("/api/post", async function(req,res) {
|
||||
res.send("not implemented yet.")
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
|
||||
END /API/*
|
||||
|
||||
*/
|
||||
|
||||
router.get("/css/*", (request, response) => {
|
||||
if(fs.existsSync(__dirname + request.originalUrl)){
|
||||
response.sendFile(__dirname + request.originalUrl);
|
||||
} else {
|
||||
response.status(404).send("no file with that name found")
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
router.get("/*", (request, response, next) => {
|
||||
let originalUrl = request.originalUrl.split("?").shift()
|
||||
if(fs.existsSync(dir + "views/"+originalUrl+".html")) {
|
||||
return response.sendFile(dir + "views/"+originalUrl+".html");
|
||||
}
|
||||
if(fs.existsSync(dir + "views"+originalUrl)) {
|
||||
return response.sendFile(dir + "views"+originalUrl);
|
||||
}
|
||||
if(fs.existsSync(dir + "views"+originalUrl+".html")) {
|
||||
return response.sendFile(dir + "views"+originalUrl+".html");
|
||||
}
|
||||
if(fs.existsSync(dir + "views"+originalUrl)) {
|
||||
return response.sendFile(dir + "views"+originalUrl);
|
||||
}
|
||||
response.status(200).send("No file with that name found: "+originalUrl)
|
||||
})
|
||||
|
||||
|
||||
|
||||
router.post("/register",async function(req,res) {
|
||||
if(!increaseAPICall(req,res))return;
|
||||
res.status(200)
|
||||
let username = req.body.user
|
||||
username = username.replace(" ","")
|
||||
let password = req.body.pass
|
||||
if(!username) {
|
||||
res.status(400)
|
||||
res.redirect("/register?success=false&reason=username")
|
||||
return
|
||||
}
|
||||
if(!password) {
|
||||
res.status(400)
|
||||
res.redirect("/register?success=false&reason=password")
|
||||
return
|
||||
}
|
||||
let userexistssql = `SELECT User_Name from zerotwohub.users where User_Name = ?`
|
||||
con.query(userexistssql,[username],function(error,result) {
|
||||
if(result && result[0] && result[0].User_Name) {
|
||||
res.status(400)
|
||||
res.redirect("/register?success=false&reason=already_exists")
|
||||
return
|
||||
}
|
||||
let hashed_pw = password;
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
hashed_pw = SHA256(hashed_pw)
|
||||
}
|
||||
let values = [username,hashed_pw]
|
||||
let sql = `INSERT INTO zerotwohub.users (User_Name, User_PW) VALUES (?, ?);`
|
||||
con.query(sql, values, function (err, result) {
|
||||
if (err) throw err;
|
||||
let ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress
|
||||
let setTo = username + " " + SHA256(password)
|
||||
let cookiesigned = signature.sign(setTo, cookiesecret+ip);
|
||||
res.cookie('AUTH_COOKIE',cookiesigned, { maxAge: Math.pow(10,10), httpOnly: true });
|
||||
res.redirect("/user?success=true")
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
router.post("/login",async function(req,res) {
|
||||
let username = req.body.user
|
||||
username = username.replace(" ","")
|
||||
let password = req.body.pass
|
||||
if(!username) {
|
||||
res.status(400)
|
||||
res.send("no username given")
|
||||
return
|
||||
}
|
||||
if(!password) {
|
||||
res.status(400)
|
||||
res.send("no password given")
|
||||
return
|
||||
}
|
||||
let hashed_pw = password;
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
hashed_pw = SHA256(hashed_pw)
|
||||
}
|
||||
|
||||
let userexistssql = `SELECT * from zerotwohub.users where User_Name = ? and User_PW = ?`
|
||||
con.query(userexistssql,[username,hashed_pw],function(error,result) {
|
||||
if(result && result[0] && result[0].User_Name && result[0].User_Name==username && result[0].User_PW && result[0].User_PW == hashed_pw) {
|
||||
let ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress
|
||||
let setTo = username + " " + SHA256(password)
|
||||
let cookiesigned = signature.sign(setTo, cookiesecret+ip);
|
||||
res.cookie('AUTH_COOKIE',cookiesigned, { maxAge: Math.pow(10,10), httpOnly: true });
|
||||
res.redirect("/user?success=true")
|
||||
} else {
|
||||
res.redirect("/login?success=false")
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
app.use(router)
|
||||
|
||||
const httpServer = http.createServer(app);
|
||||
httpServer.listen(25566);
|
27
views/index.html
Normal file
27
views/index.html
Normal file
@ -0,0 +1,27 @@
|
||||
<head>
|
||||
<style media="screen">
|
||||
a {
|
||||
color: red;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<h1>Auth website</h1>
|
||||
</header>
|
||||
<main>
|
||||
<div class="info_div">
|
||||
<p>Do you not have an account? <a href="register">Register now!</a></p>
|
||||
<br>
|
||||
<br>
|
||||
<p>Do you already have an account? <a href="login">Login now!</a></p>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<footer>
|
||||
|
||||
</footer>
|
||||
</body>
|
32
views/login.html
Normal file
32
views/login.html
Normal file
@ -0,0 +1,32 @@
|
||||
<head>
|
||||
<link rel="stylesheet" href="/css/logon.css">
|
||||
<script type="text/javascript">
|
||||
function login() {
|
||||
const user = document.getElementById("user").value
|
||||
const pw = document.getElementById("pass").value
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<h1>Login</h1>
|
||||
</header>
|
||||
<main>
|
||||
<form id="login_form" class="form_class" action="login" method="post">
|
||||
<div class="form_div">
|
||||
<label>Username:</label>
|
||||
<input id="user" class="field_class" name="user" type="text" placeholder="username" autofocus required>
|
||||
<label>Password:</label>
|
||||
<input id="pass" class="field_class" name="pass" type="password" placeholder="password" required>
|
||||
<button class="submit_class" type="submit" form="login_form" onclick="return login()">Login</button>
|
||||
</div>
|
||||
<div class="info_div">
|
||||
<p>Do you not have an account? <a href="register">Register now!</a></p>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
<footer>
|
||||
|
||||
</footer>
|
||||
</body>
|
32
views/register.html
Normal file
32
views/register.html
Normal file
@ -0,0 +1,32 @@
|
||||
<head>
|
||||
<link rel="stylesheet" href="/css/logon.css">
|
||||
<script type="text/javascript">
|
||||
function register() {
|
||||
const user = document.getElementById("user").value
|
||||
const pw = document.getElementById("pass").value
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<h1>Register</h1>
|
||||
</header>
|
||||
<main>
|
||||
<form id="register_form" class="form_class" action="register" method="post">
|
||||
<div class="form_div">
|
||||
<label>Username:</label>
|
||||
<input id="user" class="field_class" name="user" type="text" placeholder="username" autofocus required>
|
||||
<label>Password:</label>
|
||||
<input id="pass" class="field_class" name="pass" type="password" placeholder="password" required>
|
||||
<button class="submit_class" type="submit" form="register_form" onclick="return register()">register</button>
|
||||
</div>
|
||||
<div class="info_div">
|
||||
<p>Do you already have an account? <a href="/login">Login now!</a></p>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
<footer>
|
||||
|
||||
</footer>
|
||||
</body>
|
25
views/user.html
Normal file
25
views/user.html
Normal file
@ -0,0 +1,25 @@
|
||||
<!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">
|
||||
<title>Logged In</title>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
</head>
|
||||
<body onload="setuser()">
|
||||
<h1>Welcome Back!</h1>
|
||||
<h2 id="user">User: USER</h2>
|
||||
<button onclick="location.assign('/')">To Login Page</button><button onclick="location.assign('/register')">To Register Page</button>
|
||||
<script>
|
||||
async function setuser() {
|
||||
let user = await (await fetch("/api/getuser")).json();
|
||||
let username
|
||||
username = user["username"];
|
||||
if(user["error"])username=user["error"];
|
||||
document.getElementById("user").innerText = `User: ${username}`;
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user