mirror of
https://github.com/Zandercraft/TechnicFlux.git
synced 2026-11-01 05:09:19 +00:00
Add session handling and optional reCaptcha support
This commit is contained in:
18
.env.example
18
.env.example
@@ -29,6 +29,14 @@ ADMIN_PASS="flux"
|
|||||||
# 4. Put your solder API URL (http[s]://example.com/api/) in and link it.
|
# 4. Put your solder API URL (http[s]://example.com/api/) in and link it.
|
||||||
API_KEY=""
|
API_KEY=""
|
||||||
|
|
||||||
|
# (REQUIRED) Session Secret Key. CHANGE THIS!!!!
|
||||||
|
# This is the key that will be used to encrypt sessions. It is recommended that you make it secure.
|
||||||
|
# You can generate one using the following steps:
|
||||||
|
# 1. Go to https://www.lastpass.com/features/password-generator#generatorTool
|
||||||
|
# 2. Set password length to 50 and leave it set to all characters
|
||||||
|
# 3. Copy the password here.
|
||||||
|
SESSION_KEY="(/jg~WBd4%+cXt9vp'&/lN-;mynl:N}v£D!0I5V04tcpYb&;.F"
|
||||||
|
|
||||||
# (Optional) Default Author Name (for custom files)
|
# (Optional) Default Author Name (for custom files)
|
||||||
# This is the name that will be pre-filled when you go to upload custom files for a modpack.
|
# This is the name that will be pre-filled when you go to upload custom files for a modpack.
|
||||||
# Unset behaviour: You will need to specify the author every time.
|
# Unset behaviour: You will need to specify the author every time.
|
||||||
@@ -49,3 +57,13 @@ API_RATE_REQUESTS=1000
|
|||||||
# The amount of time (in milliseconds) that the request limit is applied to.
|
# The amount of time (in milliseconds) that the request limit is applied to.
|
||||||
# Unset behaviour: Defaults to 60000
|
# Unset behaviour: Defaults to 60000
|
||||||
API_RATE_WINDOW=60000
|
API_RATE_WINDOW=60000
|
||||||
|
|
||||||
|
# --- Google ReCaptcha ---
|
||||||
|
# TechnicFlux comes with Google ReCaptcha support.
|
||||||
|
# When configured, this will enable captcha protection on your login page.
|
||||||
|
|
||||||
|
# (Optional) Google ReCaptcha Credentials
|
||||||
|
# You can obtain these credentials at https://www.google.com/recaptcha/admin/create
|
||||||
|
# Unset behaviour: ReCaptcha is disabled on login page.
|
||||||
|
#CAPTCHA_SITE_KEY=""
|
||||||
|
#CAPTCHA_SITE_SECRET=""
|
||||||
|
|||||||
15
app.js
15
app.js
@@ -4,6 +4,8 @@ const path = require('path')
|
|||||||
const cookieParser = require('cookie-parser')
|
const cookieParser = require('cookie-parser')
|
||||||
const logger = require('morgan')
|
const logger = require('morgan')
|
||||||
const multer = require('multer')
|
const multer = require('multer')
|
||||||
|
const session = require('express-session')
|
||||||
|
const MongoStore = require('connect-mongo')
|
||||||
|
|
||||||
// Setup multer disk-store
|
// Setup multer disk-store
|
||||||
const storage = multer.diskStorage({
|
const storage = multer.diskStorage({
|
||||||
@@ -27,9 +29,20 @@ const app = express()
|
|||||||
app.set('views', path.join(__dirname, 'views'))
|
app.set('views', path.join(__dirname, 'views'))
|
||||||
app.set('view engine', 'hbs')
|
app.set('view engine', 'hbs')
|
||||||
|
|
||||||
|
// --- Middleware ---
|
||||||
|
app.use(session({
|
||||||
|
secret: process.env.SESSION_KEY,
|
||||||
|
saveUninitialized: false,
|
||||||
|
resave: false,
|
||||||
|
store: MongoStore.create({
|
||||||
|
mongoUrl: process.env.MONGODB_CONN_STRING,
|
||||||
|
touchAfter: 24 * 3600,
|
||||||
|
collectionName: "technicflux_sessions"
|
||||||
|
})
|
||||||
|
}))
|
||||||
app.use(logger('dev'))
|
app.use(logger('dev'))
|
||||||
app.use(express.json())
|
app.use(express.json())
|
||||||
app.use(express.urlencoded({ extended: false }))
|
app.use(express.urlencoded({ extended: true }))
|
||||||
app.use(cookieParser())
|
app.use(cookieParser())
|
||||||
app.use(express.static(path.join(__dirname, 'public')))
|
app.use(express.static(path.join(__dirname, 'public')))
|
||||||
|
|
||||||
|
|||||||
13
bin/www
13
bin/www
@@ -7,12 +7,13 @@ require('dotenv').config()
|
|||||||
|
|
||||||
// Check if the .env config file is included.
|
// Check if the .env config file is included.
|
||||||
const required_variables = [
|
const required_variables = [
|
||||||
process.env.MONGODB_CONN_STRING,
|
process.env.MONGODB_CONN_STRING,
|
||||||
process.env.ADMIN_USER,
|
process.env.ADMIN_USER,
|
||||||
process.env.ADMIN_PASS,
|
process.env.ADMIN_PASS,
|
||||||
process.env.NAME,
|
process.env.NAME,
|
||||||
process.env.HOST,
|
process.env.HOST,
|
||||||
process.env.API_KEY
|
process.env.API_KEY,
|
||||||
|
process.env.SESSION_KEY
|
||||||
]
|
]
|
||||||
for (let variable of required_variables) {
|
for (let variable of required_variables) {
|
||||||
if (variable === undefined) {
|
if (variable === undefined) {
|
||||||
|
|||||||
139
package-lock.json
generated
139
package-lock.json
generated
@@ -11,12 +11,15 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@zip.js/zip.js": "^2.7.29",
|
"@zip.js/zip.js": "^2.7.29",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
|
"connect-mongo": "^5.0.0",
|
||||||
"cookie-parser": "~1.4.4",
|
"cookie-parser": "~1.4.4",
|
||||||
"current-git-branch": "^1.1.0",
|
"current-git-branch": "^1.1.0",
|
||||||
"debug": "~4.3.4",
|
"debug": "~4.3.4",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"express": "~4.18.2",
|
"express": "~4.18.2",
|
||||||
"express-rate-limit": "^7.0.2",
|
"express-rate-limit": "^7.0.2",
|
||||||
|
"express-recaptcha": "^5.1.0",
|
||||||
|
"express-session": "^1.17.3",
|
||||||
"hbs": "~4.2.0",
|
"hbs": "~4.2.0",
|
||||||
"http-errors": "~1.6.3",
|
"http-errors": "~1.6.3",
|
||||||
"mongoose": "^7.5.3",
|
"mongoose": "^7.5.3",
|
||||||
@@ -395,6 +398,17 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/asn1.js": {
|
||||||
|
"version": "5.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
|
||||||
|
"integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
|
||||||
|
"dependencies": {
|
||||||
|
"bn.js": "^4.0.0",
|
||||||
|
"inherits": "^2.0.1",
|
||||||
|
"minimalistic-assert": "^1.0.0",
|
||||||
|
"safer-buffer": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/asynciterator.prototype": {
|
"node_modules/asynciterator.prototype": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz",
|
||||||
@@ -449,6 +463,11 @@
|
|||||||
"safe-buffer": "^5.1.1"
|
"safe-buffer": "^5.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bn.js": {
|
||||||
|
"version": "4.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
|
||||||
|
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
||||||
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "1.20.1",
|
"version": "1.20.1",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
||||||
@@ -665,6 +684,22 @@
|
|||||||
"typedarray": "^0.0.6"
|
"typedarray": "^0.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/connect-mongo": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-s93jiP6GkRApn5duComx6RLwtP23YrulPxShz+8peX7svd6Q+MS8nKLhKCCazbP92C13eTVaIOxgeLt0ezIiCg==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.1",
|
||||||
|
"kruptein": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.9.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"express-session": "^1.17.1",
|
||||||
|
"mongodb": "^5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
@@ -1615,6 +1650,75 @@
|
|||||||
"express": "^4 || ^5"
|
"express": "^4 || ^5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/express-recaptcha": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-recaptcha/-/express-recaptcha-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-L9BSaHbwVzEAf38LNnFwEbk4qpX1LiD1z8viBGYBuxyBWWVKMgBrKDb1mNLq6uSxubJzZbyIz+0ldgTSXfxsvQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express-session": {
|
||||||
|
"version": "1.17.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz",
|
||||||
|
"integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==",
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": "0.4.2",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"on-headers": "~1.0.2",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"safe-buffer": "5.2.1",
|
||||||
|
"uid-safe": "~2.1.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express-session/node_modules/cookie": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||||
|
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express-session/node_modules/debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express-session/node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express-session/node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/express/node_modules/cookie": {
|
"node_modules/express/node_modules/cookie": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
||||||
@@ -2620,6 +2724,17 @@
|
|||||||
"json-buffer": "3.0.1"
|
"json-buffer": "3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/kruptein": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/kruptein/-/kruptein-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-EQJjTwAJfQkC4NfdQdo3HXM2a9pmBm8oidzH270cYu1MbgXPNPMJuldN7OPX+qdhPO5rw4X3/iKz0BFBfkXGKA==",
|
||||||
|
"dependencies": {
|
||||||
|
"asn1.js": "^5.4.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/levn": {
|
"node_modules/levn": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||||
@@ -2753,6 +2868,11 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/minimalistic-assert": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
|
||||||
|
},
|
||||||
"node_modules/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
@@ -3388,6 +3508,14 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/random-bytes": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/range-parser": {
|
"node_modules/range-parser": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
@@ -4327,6 +4455,17 @@
|
|||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/uid-safe": {
|
||||||
|
"version": "2.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
|
||||||
|
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
|
||||||
|
"dependencies": {
|
||||||
|
"random-bytes": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/unbox-primitive": {
|
"node_modules/unbox-primitive": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||||
|
|||||||
@@ -39,12 +39,15 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@zip.js/zip.js": "^2.7.29",
|
"@zip.js/zip.js": "^2.7.29",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
|
"connect-mongo": "^5.0.0",
|
||||||
"cookie-parser": "~1.4.4",
|
"cookie-parser": "~1.4.4",
|
||||||
"current-git-branch": "^1.1.0",
|
"current-git-branch": "^1.1.0",
|
||||||
"debug": "~4.3.4",
|
"debug": "~4.3.4",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"express": "~4.18.2",
|
"express": "~4.18.2",
|
||||||
"express-rate-limit": "^7.0.2",
|
"express-rate-limit": "^7.0.2",
|
||||||
|
"express-recaptcha": "^5.1.0",
|
||||||
|
"express-session": "^1.17.3",
|
||||||
"hbs": "~4.2.0",
|
"hbs": "~4.2.0",
|
||||||
"http-errors": "~1.6.3",
|
"http-errors": "~1.6.3",
|
||||||
"mongoose": "^7.5.3",
|
"mongoose": "^7.5.3",
|
||||||
|
|||||||
2
public/stylesheets/bootstrap.min.css
vendored
2
public/stylesheets/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -9,3 +9,7 @@ body {
|
|||||||
a {
|
a {
|
||||||
color: #00B7FF;
|
color: #00B7FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.grecaptcha-badge {
|
||||||
|
margin-bottom: 65px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,36 @@
|
|||||||
const express = require('express')
|
const express = require('express')
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
const { RecaptchaV3 } = require('express-recaptcha')
|
||||||
|
|
||||||
|
// --- Google ReCaptcha
|
||||||
|
const site_key = process.env?.CAPTCHA_SITE_KEY
|
||||||
|
const site_secret = process.env?.CAPTCHA_SITE_SECRET
|
||||||
|
const captcha_enabled = (site_key !== undefined) && (site_secret !== undefined)
|
||||||
|
const recaptcha = captcha_enabled ? new RecaptchaV3(site_key, site_secret, {
|
||||||
|
callback: 'cb'
|
||||||
|
}) : undefined
|
||||||
|
|
||||||
/* GET home page. */
|
/* GET home page. */
|
||||||
router.get('/', function (req, res) {
|
router.get('/', captcha_enabled ? recaptcha.middleware.render : (req, res, next) => {next()}, function (req, res) {
|
||||||
res.render('index', { title: 'TechnicFlux' })
|
res.render('index', {
|
||||||
|
title: 'TechnicFlux',
|
||||||
|
captcha: captcha_enabled ? res.recaptcha : false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/* POST home page (login info w/ captcha) */
|
||||||
|
router.post('/', captcha_enabled ? recaptcha.middleware.verify : (req, res, next) => {next()}, function (req, res) {
|
||||||
|
// Validate captcha, if enabled.
|
||||||
|
if (captcha_enabled && req.recaptcha.error) {
|
||||||
|
return res.render('index', {
|
||||||
|
title: 'TechnicFlux',
|
||||||
|
captcha: captcha_enabled ? res.recaptcha : false,
|
||||||
|
error: "Captcha validation failed! Ensure that javascript is enabled!"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check login info
|
||||||
|
res.json({success: "yay"})
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|||||||
0
views/dashboard.hbs
Normal file
0
views/dashboard.hbs
Normal file
@@ -1,4 +1,53 @@
|
|||||||
<img src="/images/technicflux-logo-white.png" width="108px" height="108px" />
|
<div id="layoutAuthentication_content">
|
||||||
<h1>{{title}}</h1>
|
<main>
|
||||||
<p>Welcome to {{title}}!</p>
|
<div class="container">
|
||||||
<p>The dashboard isn't ready yet. We are currently working on the API and backend stuff.</p>
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-lg-5">
|
||||||
|
<div class="card border-0 rounded-lg mt-5">
|
||||||
|
<div class="card-header bg-white">
|
||||||
|
<img class="mx-auto my-5 d-block" src="/images/technicflux-logo.png" width="108px" height="108px" alt="TechnicFlux logo"/>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{{#if error}}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{error}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<form id="login-form" method="post" target="/">
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input class="form-control" id="inputEmail" type="text" placeholder="name@example.com" />
|
||||||
|
<label for="inputEmail" class="text-dark">Username</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input class="form-control" id="inputPassword" type="password" placeholder="Password" />
|
||||||
|
<label for="inputPassword" class="text-dark">Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
|
<button class="btn btn-primary w-100 g-recaptcha"
|
||||||
|
data-sitekey="{{site_key}}"
|
||||||
|
data-callback="onSubmit"
|
||||||
|
data-action="submit"
|
||||||
|
>Log In</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if captcha}}
|
||||||
|
{{{captcha}}}
|
||||||
|
<script>
|
||||||
|
function cb(token) {
|
||||||
|
let input = document.createElement('input')
|
||||||
|
input.setAttribute('type', 'text')
|
||||||
|
input.setAttribute('name', 'g-recaptcha-response')
|
||||||
|
input.setAttribute('value', token)
|
||||||
|
input.setAttribute('hidden', true)
|
||||||
|
document.getElementsByTagName('form')[0].appendChild(input)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{{/if}}
|
||||||
|
|||||||
Reference in New Issue
Block a user