Procházet zdrojové kódy

User registration toggle in Settings page.

lllllllillllllillll před 1 rokem
rodič
revize
cef9f7e7d7
7 změnil soubory, kde provedl 95 přidání a 66 odebrání
  1. 2 0
      CHANGELOG.md
  2. 1 1
      README.md
  3. 1 2
      compose.yaml
  4. 49 30
      controllers/register.js
  5. 23 11
      controllers/settings.js
  6. 17 20
      views/partials/settings.html
  7. 2 2
      views/register.html

+ 2 - 0
CHANGELOG.md

@@ -12,6 +12,8 @@
 * Fixed HTTPS env.
 * New - One-click sign-in if NO_AUTH env is set to 'true' and you're connecting from localhost.
 * New (again) - PM2 to keep the app running if it encounters an error.
+* New - User registration enabled/disabled from Settings page.
+* Removed 'SECRET' environment variable.
 
 ## v0.60 (June 9th 2024) - Permissions system and import templates
 * Converted JS template literals into HTML.

+ 1 - 1
README.md

@@ -47,8 +47,8 @@ services:
     image: lllllllillllllillll/dweebui
     environment:
       PORT: 8000
-      SECRET: MrWiskers
       HTTPS: false
+      NO_AUTH: false
     restart: unless-stopped
     ports:
       - 8000:8000

+ 1 - 2
compose.yaml

@@ -2,10 +2,9 @@ version: "3.9"
 services:
   dweebui:
     container_name: dweebui
-    image: lllllllillllllillll/dweebui
+    image: lllllllillllllillll/dweebui:v0.70-dev
     environment:
       PORT: 8000
-      SECRET: MrWiskers
       HTTPS: false
       NO_AUTH: false
     restart: unless-stopped

+ 49 - 30
controllers/register.js

@@ -1,27 +1,45 @@
-import { User, Syslog, Permission } from '../database/models.js';
+import { User, Syslog, Permission, ServerSettings } from '../database/models.js';
 import bcrypt from 'bcrypt';
 
-let SECRET = process.env.SECRET || "MrWiskers"
+export const Register = async function (req,res) {
 
-export const Register = function(req,res){
-    if(req.session.user){
-        res.redirect("/logout");
-    } else {
+    // Redirect to dashboard if user is already logged in.
+    if(req.session.user){ res.redirect("/dashboard"); return; } 
+    
+    // Continue to registration page if no users have been created.
+    let users = await User.count();
+    if (users == 0) {
+        const disable_passphrase = await ServerSettings.create({ key: 'registration', value: ''});
         res.render("register",{
-            "error":"",
+            "error": "Creating admin account. Leave passphrase blank.",
         });
+    } else {
+    // Check if registration is enabled.
+        let registration = await ServerSettings.findOne({ where: {key: 'registration'}});
+        if (registration.value == 'off') {
+            res.render("login",{
+                "error":"User registration is disabled.",
+            });
+        } else {
+            res.render("register",{
+                "error":"",
+            });
+        }
     }
 }
 
 
+export const submitRegister = async function (req,res) {
 
-export const submitRegister = async function(req,res){
-
-    let { name, username, email, password, confirmPassword, secret } = req.body;
-    email = email.toLowerCase();
+    // Grab values from the form.
+    let { name, username, password, confirmPassword, passphrase } = req.body;
+    let email = req.body.email.toLowerCase();
 
+    // Get the passphrase from the database.
+    let confirm_passphrase = await ServerSettings.findOne({ where: {key: 'registration'}});
 
-    if (secret != SECRET) {
+    // Create a log entry if the form is submitted with an invalid passphrase.
+    if (passphrase != confirm_passphrase.value) {
         const syslog = await Syslog.create({
             user: username,
             email: email,
@@ -31,24 +49,25 @@ export const submitRegister = async function(req,res){
         });
     }
 
-    if((name && email && password && confirmPassword && username) && (secret == SECRET) && (password == confirmPassword)){
+    // Check that all fields are filled out and that the passphrase is correct.
+    if ((name && email && password && confirmPassword && username) && (passphrase == confirm_passphrase.value) && (password == confirmPassword)) {
 
         async function userRole () {
             let userCount = await User.count();
-            if(userCount == 0){
-                return "admin";
-            }else{
-                return "user";
+            if (userCount == 0) { 
+                // Disable registration.
+                await ServerSettings.update({ value: 'off' }, { where: { key: 'registration' }}); 
+                return "admin"; 
+            } else { 
+                return "user"; 
             }
         }
 
+        // Check if the email address has already been used.
         let existingUser = await User.findOne({ where: {email:email}});
-        if(!existingUser){
-
+        if (!existingUser) {
             try {
-                let currentDate = new Date();
-                let newLogin = currentDate.toLocaleString();
-
+                // Create the user.
                 const user = await User.create({ 
                     name: name,
                     username: username,
@@ -56,23 +75,23 @@ export const submitRegister = async function(req,res){
                     password: bcrypt.hashSync(password,10),
                     role: await userRole(),
                     group: 'all',
-                    lastLogin: newLogin,
+                    lastLogin: new Date().toLocaleString(),
                 });
 
                 // make sure the user was created and get the UUID.
                 let newUser = await User.findOne({ where: {email:email}});
                 let match = await bcrypt.compare(password,newUser.password);
 
-                if(match){  
+                if (match) {  
+                    // Create the user session.
                     req.session.user = newUser.username;
                     req.session.UUID = newUser.UUID;
                     req.session.role = newUser.role;
 
-                    const permission = await Permission.create({
-                        user: newUser.username,
-                        userID: newUser.UUID
-                    });
+                    // Create an entry in the permissions table.
+                    await Permission.create({ user: newUser.username, userID: newUser.UUID });
 
+                    // Create a log entry.
                     const syslog = await Syslog.create({
                         user: req.session.user,
                         email: email,
@@ -80,10 +99,10 @@ export const submitRegister = async function(req,res){
                         message: "User registered successfully",
                         ip: req.socket.remoteAddress
                     });
-
                     res.redirect("/dashboard");
                 }
-            } catch(err) {
+
+            } catch {
                 res.render("register",{
                     "error":"Something went wrong when creating account.",
                 });

+ 23 - 11
controllers/settings.js

@@ -1,4 +1,4 @@
-import { read, readFileSync } from 'fs';  
+import { readFileSync } from 'fs';  
 import { ServerSettings } from '../database/models.js';
 
 
@@ -7,22 +7,34 @@ export const Settings = async (req, res) => {
     let settings = readFileSync('views/partials/settings.html', 'utf8');
 
     let links = await ServerSettings.findOne({ where: {key: 'links'}});
-    if (links.value != 'localhost' && links.value != '') {
-        settings = settings.replaceAll('data-LinkMode', 'checked');
-        settings = settings.replaceAll('data-LinkValue', `value="${links.value}"`);
+    try {
+        if (links.value != 'localhost' && links.value != '') {
+            settings = settings.replaceAll('data-LinkMode', 'checked');
+            settings = settings.replaceAll('data-LinkValue', `value="${links.value}"`);
+        }
+    } catch {
+        console.log(`Container Links: No Value Set`)
     }
-
+        
     let registration = await ServerSettings.findOne({ where: {key: 'registration'}});
-    if (registration.value != 'off' && registration.value != '') {
-        settings = settings.replaceAll('data-UserReg', 'checked');
-        settings = settings.replaceAll('data-Passphrase', `value="${registration.value}"`);
+    try {
+        if (registration.value != 'off' && registration.value != '') {
+            settings = settings.replaceAll('data-UserReg', 'checked');
+            settings = settings.replaceAll('data-Passphrase', `value="${registration.value}"`);
+        }
+    } catch {
+        console.log(`User Registration: No Value Set`);
     }
 
     async function hostInfo(host) {
         let info = await ServerSettings.findOne({ where: {key: host}});
-        if (info.value != 'off' && info.value != '') {
-            let values = info.value.split(',');
-            return { tag: values[0], ip: values[1], port: values[2] };
+        try {
+            if (info.value != 'off' && info.value != '') {
+                let values = info.value.split(',');
+                return { tag: values[0], ip: values[1], port: values[2] };
+            }
+        } catch {
+            console.log(`${host}: No Value Set`);
         }
     }
     

+ 17 - 20
views/partials/settings.html

@@ -3,47 +3,44 @@
 	<div class="card-body">
 		<h2 class="mb-4">Settings</h2>
 
-			
-		
-				<h3 class="mt-5">Container Links</h3>
-				<label class="text-muted mb-2">Choose the default behaviour for container links. Enter IP address or Domain before enabling.</label>
+				<h3 class="mt-5">User Registration</h3>
+				<label class="text-muted mb-2">Allow other users to register.</label>
 				<div class="row align-items-center">
 					<div class="col-auto">
 						<label class="form-check form-switch form-switch-lg">
-							<input class="form-check-input" type="checkbox" name="link_mode" data-LinkMode>
-							<span class="form-check-label form-check-label-on text-warning">
-								Custom
+							<input class="form-check-input" type="checkbox" name="user_registration" data-UserReg>
+							<span class="form-check-label form-check-label-on text-success">
+								Enabled
 							</span>
-							<span class="form-check-label form-check-label-off text-success">
-								Localhost
+							<span class="form-check-label form-check-label-off text-danger">
+								Disabled
 							</span>
 						</label>
 					</div>
 					<div class="col-5">
-						<input type="text" class="form-control" name="link" placeholder="IP Address or Domain" data-LinkValue>
+						<input type="text" class="form-control" name="passphrase" placeholder="multiple-words-strong-passphrase" data-Passphrase>
 					</div>
 				</div>
-
-				<h3 class="mt-5">User Registration</h3>
-				<label class="text-muted mb-2">Allow other users to register.</label>
+		
+				<h3 class="mt-5">Container Links</h3>
+				<label class="text-muted mb-2">Choose the default behaviour for container links. Enter IP address or Domain before enabling.</label>
 				<div class="row align-items-center">
 					<div class="col-auto">
 						<label class="form-check form-switch form-switch-lg">
-							<input class="form-check-input" type="checkbox" name="user_registration" data-UserReg>
-							<span class="form-check-label form-check-label-on text-success">
-								Enabled
+							<input class="form-check-input" type="checkbox" name="link_mode" data-LinkMode>
+							<span class="form-check-label form-check-label-on text-warning">
+								Custom
 							</span>
-							<span class="form-check-label form-check-label-off text-danger">
-								Disabled
+							<span class="form-check-label form-check-label-off text-success">
+								Localhost
 							</span>
 						</label>
 					</div>
 					<div class="col-5">
-						<input type="text" class="form-control" name="passphrase" placeholder="multiple-words-strong-passphrase" data-Passphrase>
+						<input type="text" class="form-control" name="link" placeholder="IP Address or Domain" data-LinkValue>
 					</div>
 				</div>
 
-
 				<h3 class="mt-5">Remote Hosts</h3>
 				<label class="text-muted mb-2">Host #2</label>
 				<div class="row align-items-center">

+ 2 - 2
views/register.html

@@ -85,8 +85,8 @@
             </div>
 
             <div class="mb-2">
-              <label class="form-label" title="Enter the value of 'SECRET' from the DweebUI docker-compose.yaml">SECRET</label>
-              <input type="text" class="form-control" id="secret" name="secret">
+              <label class="form-label" title="Enter registration passphrase.">Passphrase</label>
+              <input type="text" class="form-control" id="passphrase" name="passphrase">
             </div>