feat: implement basic auth using nginx and bcrypt password hashing
This commit is contained in:
parent
bbd9c44259
commit
b43cd62ca9
@ -31,10 +31,11 @@ COPY data-api.js /usr/share/nginx/api/
|
||||
COPY backup-s3.js /usr/share/nginx/api/
|
||||
COPY auth-middleware.js /usr/share/nginx/api/
|
||||
COPY login.html /usr/share/nginx/api/
|
||||
COPY inject-password-hash.js /usr/share/nginx/api/
|
||||
COPY generate-htpasswd.js /usr/share/nginx/api/
|
||||
|
||||
# Copy a custom Nginx configuration that includes the data API proxy
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY nginx-auth.conf /etc/nginx/auth.conf
|
||||
|
||||
# Copy supervisor configuration
|
||||
COPY supervisord.conf /etc/supervisord.conf
|
||||
|
||||
33
generate-htpasswd.js
Normal file
33
generate-htpasswd.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Generate .htpasswd file for Nginx basic authentication
|
||||
*
|
||||
* This script creates a .htpasswd file from the bcrypt hash provided in the
|
||||
* PASSWORD_HASH environment variable.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Default username
|
||||
const USERNAME = 'user';
|
||||
|
||||
// Get password hash from environment variable
|
||||
const passwordHash = process.env.PASSWORD_HASH || '$2a$10$EgxHKjDDFcZKtQY9hl/N4.QvEQHCXVnQXw9dzFYlUDVKOcLMGp9eq';
|
||||
|
||||
// Format for .htpasswd: username:$2y$...hash...
|
||||
// Note: Nginx requires $2y$ format instead of bcrypt's $2a$ format
|
||||
const htpasswdContent = `${USERNAME}:${passwordHash.replace('$2a$', '$2y$')}`;
|
||||
|
||||
// Path to the .htpasswd file
|
||||
const htpasswdPath = '/etc/nginx/.htpasswd';
|
||||
|
||||
// Write the .htpasswd file
|
||||
try {
|
||||
fs.writeFileSync(htpasswdPath, htpasswdContent);
|
||||
console.log(`Generated .htpasswd file at ${htpasswdPath}`);
|
||||
} catch (error) {
|
||||
console.error(`Error generating .htpasswd file: ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Basic authentication setup complete');
|
||||
42
generate-password.js
Normal file
42
generate-password.js
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Password Hash Generator for Weight Tracker
|
||||
*
|
||||
* This script generates a bcrypt hash for a given password that can be used
|
||||
* with the Weight Tracker application's authentication system.
|
||||
*
|
||||
* Usage:
|
||||
* node generate-password.js <your-password>
|
||||
*/
|
||||
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
// Get password from command line arguments
|
||||
const password = process.argv[2];
|
||||
|
||||
if (!password) {
|
||||
console.error('Error: Password is required');
|
||||
console.log('Usage: node generate-password.js <your-password>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Generate salt and hash
|
||||
const saltRounds = 10;
|
||||
bcrypt.genSalt(saltRounds, (err, salt) => {
|
||||
if (err) {
|
||||
console.error('Error generating salt:', err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
bcrypt.hash(password, salt, (err, hash) => {
|
||||
if (err) {
|
||||
console.error('Error generating hash:', err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('\nPassword Hash for Nginx Basic Authentication:');
|
||||
console.log(hash);
|
||||
console.log('\nUse this hash in your PASSWORD_HASH environment variable in Coolify.');
|
||||
console.log('Example:');
|
||||
console.log(`PASSWORD_HASH=${hash}`);
|
||||
});
|
||||
});
|
||||
13
nginx-auth.conf
Normal file
13
nginx-auth.conf
Normal file
@ -0,0 +1,13 @@
|
||||
# Authentication configuration for Nginx
|
||||
# This file will be included in the main Nginx configuration
|
||||
|
||||
# Define the authentication realm
|
||||
auth_basic "Weight Tracker";
|
||||
|
||||
# Path to the .htpasswd file containing user credentials
|
||||
auth_basic_user_file /etc/nginx/.htpasswd;
|
||||
|
||||
# CORS headers
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization' always;
|
||||
41
nginx.conf
41
nginx.conf
@ -1,29 +1,19 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Enable compression
|
||||
server_name localhost;
|
||||
|
||||
# Enable gzip compression
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
# Authentication check - redirect to login if not authenticated
|
||||
location = / {
|
||||
# First try to use the API to check authentication
|
||||
auth_request /auth/check;
|
||||
# Protect all routes with basic authentication
|
||||
location / {
|
||||
# Include authentication configuration
|
||||
include /etc/nginx/auth.conf;
|
||||
|
||||
# If auth passes, serve the main page
|
||||
# Serve static files
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# CORS headers
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization' always;
|
||||
|
||||
# Error indicates not authenticated, redirect to login
|
||||
error_page 401 = @error401;
|
||||
|
||||
# Handle preflight requests
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
@ -35,21 +25,6 @@ server {
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
|
||||
# Serve static files directly
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# CORS headers
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization' always;
|
||||
}
|
||||
|
||||
# Handle 401 unauthorized by redirecting to login
|
||||
location @error401 {
|
||||
return 302 /login;
|
||||
}
|
||||
|
||||
# Proxy requests to the data API
|
||||
location /data/ {
|
||||
|
||||
@ -5,8 +5,8 @@ logfile=/dev/stdout
|
||||
logfile_maxbytes=0
|
||||
pidfile=/var/run/supervisord.pid
|
||||
|
||||
[program:inject-password-hash]
|
||||
command=node /usr/share/nginx/api/inject-password-hash.js
|
||||
[program:generate-htpasswd]
|
||||
command=node /usr/share/nginx/api/generate-htpasswd.js
|
||||
directory=/usr/share/nginx/api
|
||||
environment=PASSWORD_HASH="%(ENV_PASSWORD_HASH)s"
|
||||
autostart=true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user