Initial commit
This commit is contained in:
commit
ffa3b34739
5
.env.template
Normal file
5
.env.template
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Where is the GLAuth sqlite DB located?
|
||||||
|
GLAUTH_DB=""
|
||||||
|
|
||||||
|
# Which port should the server run on?
|
||||||
|
PORT=8080
|
134
.gitignore
vendored
Normal file
134
.gitignore
vendored
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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.*
|
||||||
|
|
||||||
|
|
||||||
|
captcha.png
|
||||||
|
package-lock.json
|
62
README.md
Normal file
62
README.md
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# qwik-register
|
||||||
|
|
||||||
|
## GLAuth installation
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/glauth/glauth.git
|
||||||
|
cd glauth
|
||||||
|
make fast
|
||||||
|
make plugins
|
||||||
|
```
|
||||||
|
|
||||||
|
## GLAuth config
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[ldap]
|
||||||
|
enabled = true
|
||||||
|
listen = "0.0.0.0:3893"
|
||||||
|
|
||||||
|
[ldaps]
|
||||||
|
enabled = false
|
||||||
|
listen = "0.0.0.0:3894"
|
||||||
|
cert = "certs/server.crt"
|
||||||
|
key = "certs/server.key"
|
||||||
|
|
||||||
|
[backend]
|
||||||
|
datastore = "plugin"
|
||||||
|
plugin = "sqlite.so"
|
||||||
|
pluginhandler = "NewSQLiteHandler"
|
||||||
|
baseDN = "dc=glauth,dc=com"
|
||||||
|
database = "users.db"
|
||||||
|
|
||||||
|
nameformat = "cn"
|
||||||
|
groupformat = "ou"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pre database setup
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE users (
|
||||||
|
uidnumber INTEGER PRIMARY KEY autoincrement,
|
||||||
|
id INTEGER,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
primarygroup INTEGER NOT NULL,
|
||||||
|
othergroups TEXT DEFAULT '',
|
||||||
|
givenname TEXT DEFAULT '',
|
||||||
|
sn TEXT DEFAULT '',
|
||||||
|
mail TEXT DEFAULT '',
|
||||||
|
loginshell TYEXT DEFAULT '',
|
||||||
|
homedirectory TEXT DEFAULT '',
|
||||||
|
disabled SMALLINT DEFAULT 0,
|
||||||
|
passsha256 TEXT DEFAULT '',
|
||||||
|
passbcrypt TEXT DEFAULT '',
|
||||||
|
otpsecret TEXT DEFAULT '',
|
||||||
|
yubikey TEXT DEFAULT '',
|
||||||
|
custattr TEXT DEFAULT '{}');
|
||||||
|
|
||||||
|
INSERT INTO groups(name, gidnumber) VALUES('users', 0);
|
||||||
|
INSERT INTO groups(name, gidnumber) VALUES('admins', 10);
|
||||||
|
INSERT INTO groups(name, gidnumber) VALUES('root', 100);
|
||||||
|
|
||||||
|
INSERT INTO includegroups(parentgroupid, includegroupid) VALUES(10, 0);
|
||||||
|
```
|
93
captcha.sh
Executable file
93
captcha.sh
Executable file
|
@ -0,0 +1,93 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script is an example captcha script.
|
||||||
|
# It takes the text to recognize in the captcha image as a parameter.
|
||||||
|
# It return the image binary as a result. ejabberd support PNG, JPEG and GIF.
|
||||||
|
|
||||||
|
# The whole idea of the captcha script is to let server admins adapt it to
|
||||||
|
# their own needs. The goal is to be able to make the captcha generation as
|
||||||
|
# unique as possible, to make the captcha challenge difficult to bypass by
|
||||||
|
# a bot.
|
||||||
|
# Server admins are thus supposed to write and use their own captcha generators.
|
||||||
|
|
||||||
|
# This script relies on ImageMagick.
|
||||||
|
# It is NOT compliant with ImageMagick forks like GraphicsMagick.
|
||||||
|
|
||||||
|
INPUT=$1
|
||||||
|
|
||||||
|
for n in $(od -A n -t u2 -N 48 /dev/urandom); do RL="$RL$n "; done
|
||||||
|
get_random ()
|
||||||
|
{
|
||||||
|
R=${RL%% *}
|
||||||
|
RL=${RL#* }
|
||||||
|
}
|
||||||
|
|
||||||
|
get_random
|
||||||
|
WAVE1_AMPLITUDE=$((2 + R % 5))
|
||||||
|
get_random
|
||||||
|
WAVE1_LENGTH=$((50 + R % 25))
|
||||||
|
get_random
|
||||||
|
WAVE2_AMPLITUDE=$((2 + R % 5))
|
||||||
|
get_random
|
||||||
|
WAVE2_LENGTH=$((50 + R % 25))
|
||||||
|
get_random
|
||||||
|
WAVE3_AMPLITUDE=$((2 + R % 5))
|
||||||
|
get_random
|
||||||
|
WAVE3_LENGTH=$((50 + R % 25))
|
||||||
|
get_random
|
||||||
|
W1_LINE_START_Y=$((10 + R % 40))
|
||||||
|
get_random
|
||||||
|
W1_LINE_STOP_Y=$((10 + R % 40))
|
||||||
|
get_random
|
||||||
|
W2_LINE_START_Y=$((10 + R % 40))
|
||||||
|
get_random
|
||||||
|
W2_LINE_STOP_Y=$((10 + R % 40))
|
||||||
|
get_random
|
||||||
|
W3_LINE_START_Y=$((10 + R % 40))
|
||||||
|
get_random
|
||||||
|
W3_LINE_STOP_Y=$((10 + R % 40))
|
||||||
|
|
||||||
|
get_random
|
||||||
|
B1_LINE_START_Y=$((R % 40))
|
||||||
|
get_random
|
||||||
|
B1_LINE_STOP_Y=$((R % 40))
|
||||||
|
get_random
|
||||||
|
B2_LINE_START_Y=$((R % 40))
|
||||||
|
get_random
|
||||||
|
B2_LINE_STOP_Y=$((R % 40))
|
||||||
|
#B3_LINE_START_Y=$((R % 40))
|
||||||
|
#B3_LINE_STOP_Y=$((R % 40))
|
||||||
|
|
||||||
|
get_random
|
||||||
|
B1_LINE_START_X=$((R % 20))
|
||||||
|
get_random
|
||||||
|
B1_LINE_STOP_X=$((100 + R % 40))
|
||||||
|
get_random
|
||||||
|
B2_LINE_START_X=$((R % 20))
|
||||||
|
get_random
|
||||||
|
B2_LINE_STOP_X=$((100 + R % 40))
|
||||||
|
#B3_LINE_START_X=$((R % 20))
|
||||||
|
#B3_LINE_STOP_X=$((100 + R % 40))
|
||||||
|
|
||||||
|
get_random
|
||||||
|
ROLL_X=$((R % 40))
|
||||||
|
|
||||||
|
convert -size 180x60 xc:none -pointsize 40 \
|
||||||
|
\( -clone 0 -fill white \
|
||||||
|
-stroke black -strokewidth 4 -annotate +0+40 "$INPUT" \
|
||||||
|
-stroke white -strokewidth 2 -annotate +0+40 "$INPUT" \
|
||||||
|
-roll +$ROLL_X+0 \
|
||||||
|
-wave "$WAVE1_AMPLITUDE"x"$WAVE1_LENGTH" \
|
||||||
|
-roll -$ROLL_X+0 \) \
|
||||||
|
\( -clone 0 -stroke black \
|
||||||
|
-strokewidth 1 -draw \
|
||||||
|
"line $B1_LINE_START_X,$B1_LINE_START_Y $B1_LINE_STOP_X,$B1_LINE_STOP_Y" \
|
||||||
|
-strokewidth 1 -draw \
|
||||||
|
"line $B2_LINE_START_X,$B2_LINE_START_Y $B2_LINE_STOP_X,$B2_LINE_STOP_Y" \
|
||||||
|
-wave "$WAVE2_AMPLITUDE"x"$WAVE2_LENGTH" \) \
|
||||||
|
\( -clone 0 -stroke white \
|
||||||
|
-strokewidth 2 -draw "line 0,$W1_LINE_START_Y 140,$W1_LINE_STOP_Y" \
|
||||||
|
-strokewidth 2 -draw "line 0,$W2_LINE_START_Y 140,$W2_LINE_STOP_Y" \
|
||||||
|
-strokewidth 2 -draw "line 0,$W3_LINE_START_Y 140,$W3_LINE_STOP_Y" \
|
||||||
|
-wave "$WAVE3_AMPLITUDE"x"$WAVE3_LENGTH" \) \
|
||||||
|
-flatten -crop 140x60 +repage -quality 90 -depth 8 png:-
|
102
index.js
Normal file
102
index.js
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import Database from 'better-sqlite3'
|
||||||
|
import express from 'express'
|
||||||
|
import crypto from 'crypto'
|
||||||
|
import dotenv from 'dotenv'
|
||||||
|
|
||||||
|
import { exec } from 'child_process'
|
||||||
|
|
||||||
|
dotenv.config()
|
||||||
|
|
||||||
|
const app = express()
|
||||||
|
const port = process.env.PORT
|
||||||
|
let valid = {}
|
||||||
|
let glauth = undefined
|
||||||
|
|
||||||
|
console.log(process.env)
|
||||||
|
|
||||||
|
dbInit()
|
||||||
|
|
||||||
|
app.use(express.urlencoded({
|
||||||
|
extended: true
|
||||||
|
}))
|
||||||
|
|
||||||
|
app.use(express.static('public'))
|
||||||
|
|
||||||
|
app.post('/register', (req, res) => {
|
||||||
|
// 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"))
|
||||||
|
|
||||||
|
// is captcha valid
|
||||||
|
if(!valid[req.body.captcha])
|
||||||
|
return(res.send("Invalid captcha!"))
|
||||||
|
|
||||||
|
const captchaAge = Math.abs((valid[req.body.captcha].getTime() - new Date().getTime())/1000)
|
||||||
|
|
||||||
|
if(captchaAge > 600)
|
||||||
|
return(res.send("Invalid captcha!"))
|
||||||
|
|
||||||
|
// expire the captcha
|
||||||
|
delete valid[req.body.captcha]
|
||||||
|
|
||||||
|
// Does user already exist?
|
||||||
|
if(glauth.prepare(`SELECT * FROM users WHERE name = ?`).get(req.body.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'))
|
||||||
|
|
||||||
|
console.log(`>>> User: ${req.body.username} was succesfully created!`)
|
||||||
|
res.send("Account registered!")
|
||||||
|
|
||||||
|
res.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get('/captcha', async (req, res) => {
|
||||||
|
const captcha = crypto.randomBytes(3).toString('hex')
|
||||||
|
await execawait(`./captcha.sh ${captcha} > captcha.png`)
|
||||||
|
|
||||||
|
// Make it valid for 10 minutes
|
||||||
|
valid[captcha] = new Date()
|
||||||
|
|
||||||
|
// Send the captcha image
|
||||||
|
res.contentType('image/png');
|
||||||
|
res.sendFile('captcha.png', {
|
||||||
|
root: './'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
app.listen(port);
|
||||||
|
console.log('Server started at http://localhost:' + port);
|
||||||
|
|
||||||
|
|
||||||
|
function execawait(cmd) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(cmd, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.warn(error);
|
||||||
|
}
|
||||||
|
resolve(stdout ? stdout : stderr);
|
||||||
|
});
|
||||||
|
});7
|
||||||
|
}
|
||||||
|
|
||||||
|
function dbInit() {
|
||||||
|
glauth = new Database(process.env.GLAUTH_DB, {})
|
||||||
|
|
||||||
|
console.log(`Loaded in GLAuth - users.db`)
|
||||||
|
}
|
18
package.json
Normal file
18
package.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "qwik-register",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"better-sqlite3": "^7.4.6",
|
||||||
|
"dotenv": "^12.0.3",
|
||||||
|
"express": "^4.17.2",
|
||||||
|
"expresss": "^0.0.0"
|
||||||
|
}
|
||||||
|
}
|
17
public/index.html
Normal file
17
public/index.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<img src="./captcha">
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>2-20 character in length</li>
|
||||||
|
<li>only a-zA-Z0-9 characters only</li>
|
||||||
|
</ul>
|
||||||
|
<form method="POST" action="/register">
|
||||||
|
<label for="username">Username:</label><br>
|
||||||
|
<input type="text" id="username" name="username"><br>
|
||||||
|
<label for="password">Password:</label><br>
|
||||||
|
<input type="password" id="password" name="password">
|
||||||
|
<br>
|
||||||
|
<label for="captcha">Captcha:</label><br>
|
||||||
|
<input type="text" id="captcha" name="captcha">
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Register!" />
|
||||||
|
</form>
|
Loading…
Reference in New Issue
Block a user