04/16 Updated with domain settings in .env file
This commit is contained in:
@@ -294,8 +294,10 @@ def update_existing_qr_codes():
|
|||||||
"""Update existing QR codes with missing URLs or images at startup.
|
"""Update existing QR codes with missing URLs or images at startup.
|
||||||
|
|
||||||
Regenerates qr_url slugs without needing a request context.
|
Regenerates qr_url slugs without needing a request context.
|
||||||
For qr_code_image, constructs the base URL from FLASK_HOST/FLASK_PORT
|
For qr_code_image, uses QR_BASE_URL (from .env) as the authoritative base
|
||||||
config so this can run safely outside any HTTP request.
|
URL so that generated links always match the public-facing domain.
|
||||||
|
Falls back to FLASK_HOST/FLASK_PORT construction only when QR_BASE_URL is
|
||||||
|
not configured (development environments without a reverse proxy).
|
||||||
"""
|
"""
|
||||||
from extensions import db as _db, logger_handler as lh
|
from extensions import db as _db, logger_handler as lh
|
||||||
from utils.helpers import generate_qr_code, get_qr_styling, generate_qr_url
|
from utils.helpers import generate_qr_code, get_qr_styling, generate_qr_url
|
||||||
@@ -306,7 +308,12 @@ def update_existing_qr_codes():
|
|||||||
if not qr_codes:
|
if not qr_codes:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Build a base URL that does not require an active request context.
|
# Prefer the explicit QR_BASE_URL env var (required behind a reverse proxy).
|
||||||
|
# Fall back to FLASK_HOST/PORT for local/dev environments.
|
||||||
|
qr_base_url = os.environ.get('QR_BASE_URL', '').rstrip('/')
|
||||||
|
if qr_base_url:
|
||||||
|
base_url = qr_base_url + '/'
|
||||||
|
else:
|
||||||
host = os.environ.get('FLASK_HOST', '0.0.0.0')
|
host = os.environ.get('FLASK_HOST', '0.0.0.0')
|
||||||
# 0.0.0.0 is a bind address, not a reachable hostname — default to localhost
|
# 0.0.0.0 is a bind address, not a reachable hostname — default to localhost
|
||||||
if host in ('0.0.0.0', ''):
|
if host in ('0.0.0.0', ''):
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ class Config:
|
|||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
COMPANY_NAME = os.environ.get('COMPANY_NAME', 'QR Code Management System')
|
COMPANY_NAME = os.environ.get('COMPANY_NAME', 'QR Code Management System')
|
||||||
CONTRACT_NAME = os.environ.get('CONTRACT_NAME', 'Default Contract')
|
CONTRACT_NAME = os.environ.get('CONTRACT_NAME', 'Default Contract')
|
||||||
|
# Public-facing base URL used when constructing QR code destination links.
|
||||||
|
# Set this to your domain with no trailing slash, e.g.:
|
||||||
|
# QR_BASE_URL=https://qr.govservicesinc.com
|
||||||
|
# This prevents doubled-hostname issues when running behind a reverse proxy.
|
||||||
|
QR_BASE_URL = os.environ.get('QR_BASE_URL', '').rstrip('/')
|
||||||
|
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# File uploads
|
# File uploads
|
||||||
|
|||||||
+23
-5
@@ -42,6 +42,24 @@ import openpyxl
|
|||||||
bp = Blueprint('qr_codes', __name__)
|
bp = Blueprint('qr_codes', __name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_qr_base_url():
|
||||||
|
"""
|
||||||
|
Return the authoritative base URL for QR code destination links.
|
||||||
|
Prefers the explicit QR_BASE_URL config value (set via .env / config.py).
|
||||||
|
Falls back gracefully to request.url_root if not configured.
|
||||||
|
|
||||||
|
Using an explicit QR_BASE_URL is required when the app runs behind a
|
||||||
|
reverse proxy (e.g. nginx) that can cause request.url_root to produce
|
||||||
|
a doubled hostname such as:
|
||||||
|
https://qr.govservicesinc.com,qr.govservicesinc.com/
|
||||||
|
"""
|
||||||
|
configured = current_app.config.get('QR_BASE_URL', '').rstrip('/')
|
||||||
|
if configured:
|
||||||
|
return configured + '/'
|
||||||
|
# Fallback: normalise request.url_root to avoid any trailing-slash issues
|
||||||
|
return request.url_root.rstrip('/') + '/'
|
||||||
|
|
||||||
|
|
||||||
# --- ADDED: helper — returns distinct (location, location_address) pairs from
|
# --- ADDED: helper — returns distinct (location, location_address) pairs from
|
||||||
# all standard QR codes, used to auto-populate the dynamic QR location list ---
|
# all standard QR codes, used to auto-populate the dynamic QR location list ---
|
||||||
def get_unique_qr_locations():
|
def get_unique_qr_locations():
|
||||||
@@ -193,7 +211,7 @@ def create_qr_code():
|
|||||||
qr_url = generate_qr_url(name, new_qr_code.id)
|
qr_url = generate_qr_url(name, new_qr_code.id)
|
||||||
|
|
||||||
# Generate QR code data with the destination URL and custom styling
|
# Generate QR code data with the destination URL and custom styling
|
||||||
qr_data = f"{request.url_root}qr/{qr_url}"
|
qr_data = f"{_get_qr_base_url()}qr/{qr_url}"
|
||||||
qr_image = generate_qr_code(
|
qr_image = generate_qr_code(
|
||||||
data=qr_data,
|
data=qr_data,
|
||||||
fill_color=fill_color,
|
fill_color=fill_color,
|
||||||
@@ -321,7 +339,7 @@ def import_bulk_qr_codes():
|
|||||||
created_by=session['user_id'],
|
created_by=session['user_id'],
|
||||||
generate_qr_code_func=generate_qr_code,
|
generate_qr_code_func=generate_qr_code,
|
||||||
generate_qr_url_func=generate_qr_url,
|
generate_qr_url_func=generate_qr_url,
|
||||||
request_url_root=request.url_root,
|
request_url_root=_get_qr_base_url(),
|
||||||
project_lookup=project_lookup,
|
project_lookup=project_lookup,
|
||||||
QRCode=QRCode,
|
QRCode=QRCode,
|
||||||
Project=Project,
|
Project=Project,
|
||||||
@@ -543,7 +561,7 @@ def edit_qr_code(qr_id):
|
|||||||
|
|
||||||
# Regenerate QR code if name or styling changed
|
# Regenerate QR code if name or styling changed
|
||||||
if name_changed or styling_changed:
|
if name_changed or styling_changed:
|
||||||
qr_data = f"{request.url_root}qr/{qr_code.qr_url}"
|
qr_data = f"{_get_qr_base_url()}qr/{qr_code.qr_url}"
|
||||||
|
|
||||||
# Use new styling if available, otherwise use defaults
|
# Use new styling if available, otherwise use defaults
|
||||||
styling = get_qr_styling(qr_code)
|
styling = get_qr_styling(qr_code)
|
||||||
@@ -1117,7 +1135,7 @@ def copy_qr_url(qr_id):
|
|||||||
return jsonify({
|
return jsonify({
|
||||||
'success': True,
|
'success': True,
|
||||||
'message': f'QR code URL copied to clipboard!',
|
'message': f'QR code URL copied to clipboard!',
|
||||||
'url': f"{request.url_root}qr/{qr_code.qr_url}"
|
'url': f"{_get_qr_base_url()}qr/{qr_code.qr_url}"
|
||||||
})
|
})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1140,7 +1158,7 @@ def open_qr_link(qr_id):
|
|||||||
return jsonify({
|
return jsonify({
|
||||||
'success': True,
|
'success': True,
|
||||||
'message': f'Opening QR code link...',
|
'message': f'Opening QR code link...',
|
||||||
'url': f"{request.url_root}qr/{qr_code.qr_url}"
|
'url': f"{_get_qr_base_url()}qr/{qr_code.qr_url}"
|
||||||
})
|
})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user