Basic registration and login done.
This commit is contained in:
parent
618ffa7029
commit
2af34eb35f
|
@ -1,5 +1,17 @@
|
|||
import SQLDatabase from 'better-sqlite3'
|
||||
|
||||
/**
|
||||
* @typedef {object} User
|
||||
* @param {string} name
|
||||
* @param {string} passbcrypt
|
||||
* @param {number} uidnumber
|
||||
* @param {number} id
|
||||
* @param {number} disabled
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {SQLDatabase.Database}
|
||||
*/
|
||||
export let glauth = undefined
|
||||
|
||||
export function dbInit() {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bcrypt": "^5.0.1",
|
||||
"better-sqlite3": "^7.4.6",
|
||||
"dotenv": "^12.0.3",
|
||||
"express": "^4.17.2",
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import bcrypt from 'bcrypt'
|
||||
import crypto from 'crypto'
|
||||
import { Router } from 'express'
|
||||
import { glauth } from '../libs/database.js'
|
||||
import execawait from '../libs/execawait.js'
|
||||
|
||||
const AUTH = Router()
|
||||
|
@ -7,47 +9,64 @@ let valid = {}
|
|||
|
||||
|
||||
AUTH.post('/register', (req, res) => {
|
||||
const { captcha, password, username } = req.body
|
||||
|
||||
// Was input sent?
|
||||
if(!req.body.username)
|
||||
return(res.send("No username entered!"))
|
||||
|
||||
if(!req.body.password)
|
||||
return(res.send("No password entered!"))
|
||||
|
||||
if(!req.body.password)
|
||||
return(res.send("No captcha entered!"))
|
||||
|
||||
// does the username match the requirements
|
||||
if(!(/^(?=[a-zA-Z0-9]{2,20}$).*$/.test(req.body.username)))
|
||||
return(res.send("Username does not match the requirements"))
|
||||
if (!username || !password || !captcha)
|
||||
return(res.send(`Not entered:${username ? '' : ' username,'}${password ? '' : ' password,'}${captcha ? '' : ' captcha'}`))
|
||||
|
||||
// is captcha valid
|
||||
if(!valid[req.body.captcha])
|
||||
if (!valid[captcha])
|
||||
return(res.send("Invalid captcha!"))
|
||||
|
||||
const captchaAge = Math.abs((valid[req.body.captcha].getTime() - new Date().getTime())/1000)
|
||||
const captchaAge = Math.abs((valid[captcha].getTime() - new Date().getTime())/1000)
|
||||
|
||||
if(captchaAge > 600)
|
||||
if (captchaAge > 600)
|
||||
return(res.send("Invalid captcha!"))
|
||||
|
||||
// expire the captcha
|
||||
delete valid[req.body.captcha]
|
||||
delete valid[captcha]
|
||||
|
||||
// Does user already exist?
|
||||
if(glauth.prepare(`SELECT * FROM users WHERE name = ?`).get(req.body.username))
|
||||
// does the username match the requirements
|
||||
if (!(/^(?=[a-zA-Z0-9]{2,20}$).*$/.test(username)))
|
||||
return(res.send("Username does not match the requirements"))
|
||||
|
||||
if (glauth.prepare(`SELECT * FROM users WHERE name = ?`).get(username))
|
||||
return(res.send("User already exists"))
|
||||
|
||||
// Create the user!
|
||||
glauth.prepare(`
|
||||
INSERT INTO users(
|
||||
name, primarygroup, passsha256
|
||||
) VALUES(?, 0, ?)
|
||||
`).run(req.body.username, crypto.createHash('sha256').update(req.body.password).digest('hex'))
|
||||
bcrypt.hash(password, 10).then(
|
||||
hash => {
|
||||
glauth.prepare(`
|
||||
INSERT INTO users(
|
||||
name, primarygroup, passbcrypt
|
||||
) VALUES(?, 0, ?)
|
||||
`).run(username, hash)
|
||||
|
||||
console.log(`>>> User: ${req.body.username} was succesfully created!`)
|
||||
res.send("Account registered!")
|
||||
res.send("Account registered!")
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
res.end()
|
||||
AUTH.post('/login', (req, res) => {
|
||||
const { password, username } = req.body
|
||||
|
||||
// Was input sent?
|
||||
if (!username || !password )
|
||||
return(res.send(`Not entered:${username ? '' : ' username,'}${password ? '' : ' password'}`))
|
||||
|
||||
const user = glauth.prepare(`SELECT * FROM users WHERE name = ?`).get(username)
|
||||
|
||||
if (!user)
|
||||
return(res.send("User doesn't exist!"))
|
||||
|
||||
bcrypt.compare(password, user.passbcrypt).then(
|
||||
match => {
|
||||
if (!match)
|
||||
return res.send("Password's is incorrect!")
|
||||
|
||||
return res.send("Welcome " + user.name + "!")
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
AUTH.get('/captcha', async (req, res) => {
|
||||
|
@ -58,10 +77,8 @@ AUTH.get('/captcha', async (req, res) => {
|
|||
valid[captcha] = new Date()
|
||||
|
||||
// Send the captcha image
|
||||
res.contentType('image/png');
|
||||
res.sendFile('captcha.png', {
|
||||
root: './'
|
||||
});
|
||||
res.contentType('image/png')
|
||||
.sendFile('captcha.png', { root: './' })
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import AUTH from './auth.js'
|
|||
const ROUTES = Router()
|
||||
|
||||
ROUTES.get('/', (_, res) => res.render("pages/landing.njk"))
|
||||
ROUTES.get('/login', (_, res) => res.render("pages/login.njk"))
|
||||
ROUTES.get('/register', (_, res) => res.render("pages/register.njk"))
|
||||
ROUTES.use('/auth', AUTH)
|
||||
|
||||
export default ROUTES
|
|
@ -196,4 +196,61 @@ img.logo {
|
|||
.buttons > a:hover, .buttons > a:focus {
|
||||
color: var(--surface);
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: fit-content;
|
||||
width: min(100%, 45ch);
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 1rem 0 .5rem 0;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
background-color: var(--grey3);
|
||||
border: .1rem solid var(--grey3);
|
||||
border-radius: .5rem;
|
||||
padding: .25rem .75rem;
|
||||
transition: border-color .3s, background-color .3s, color .3s;
|
||||
}
|
||||
|
||||
input:hover {
|
||||
border-color: var(--grey4);
|
||||
background-color: var(--grey4);
|
||||
}
|
||||
|
||||
input:focus, input:active {
|
||||
border-color: var(--primary);
|
||||
outline: 0 none transparent;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
color: var(--primary);
|
||||
background-color: transparent;
|
||||
border: .1rem solid var(--primary);
|
||||
border-radius: .5rem;
|
||||
|
||||
width: max-content;
|
||||
margin: 1rem 0;
|
||||
padding: .5rem 1.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="submit"]:hover {
|
||||
color: var(--surface);
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
.captcha {
|
||||
display: block;
|
||||
margin: 0 0 .75rem 0;
|
||||
}
|
||||
|
||||
p.hint {
|
||||
font-size: .65rem;
|
||||
}
|
18
views/pages/login.njk
Normal file
18
views/pages/login.njk
Normal file
|
@ -0,0 +1,18 @@
|
|||
{% extends "templates/base.njk" %}
|
||||
|
||||
{% block head %}
|
||||
<title>qwik account manager</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Login to an account</h1>
|
||||
<form action="/auth/login" method="post">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" placeholder="FancyFox89">
|
||||
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" placeholder="VerySecurePassword;PleaseDon'tHackMe!LOL">
|
||||
|
||||
<input type="submit" value="Log in!">
|
||||
</form>
|
||||
{% endblock %}
|
25
views/pages/register.njk
Normal file
25
views/pages/register.njk
Normal file
|
@ -0,0 +1,25 @@
|
|||
{% extends "templates/base.njk" %}
|
||||
|
||||
{% block head %}
|
||||
<title>qwik account manager</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Register account</h1>
|
||||
<form action="/auth/register" method="post">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" placeholder="FancyFox89" autocomplete="off">
|
||||
<p class="hint">The username must be alphanumeric and between 2-20 characters.</p>
|
||||
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" placeholder="VerySecurePassword;PleaseDon'tHackMe!LOL">
|
||||
<p class="hint">There are no formal password requirements, but we recommend making a secure passphrase.</p>
|
||||
|
||||
<label for="captcha">Captcha:</label>
|
||||
<img src="/auth/captcha" class="captcha">
|
||||
<input type="text" id="captcha" name="captcha" placeholder="xxxxxx">
|
||||
<p class="hint">Enter the text you see in the image.</p>
|
||||
|
||||
<input type="submit" value="Register!">
|
||||
</form>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user