Feat(Security):
a. Update CORS settings b. Update session cookie settings c. Remove comments that expose project architecture (and that Claude made most of it :P)
This commit is contained in:
27
app.py
27
app.py
@@ -29,7 +29,7 @@ from controllers.store.stock_item import routes_store_stock_item
|
|||||||
from controllers.store.supplier import routes_store_supplier
|
from controllers.store.supplier import routes_store_supplier
|
||||||
from controllers.store.supplier_purchase_order import routes_store_supplier_purchase_order
|
from controllers.store.supplier_purchase_order import routes_store_supplier_purchase_order
|
||||||
from controllers.user import routes_user
|
from controllers.user import routes_user
|
||||||
from extensions import db, csrf, cors, mail, oauth
|
from extensions import db, csrf, mail, oauth
|
||||||
from helpers.helper_app import Helper_App
|
from helpers.helper_app import Helper_App
|
||||||
# external
|
# external
|
||||||
from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session
|
from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session
|
||||||
@@ -82,12 +82,13 @@ def make_session_permanent():
|
|||||||
session.permanent = True
|
session.permanent = True
|
||||||
|
|
||||||
csrf = CSRFProtect()
|
csrf = CSRFProtect()
|
||||||
"""
|
cors = CORS(app, resources={
|
||||||
cors = CORS()
|
r"/static/*": {
|
||||||
db = SQLAlchemy()
|
"origins": [app.config["URL_HOST"]],
|
||||||
mail = Mail()
|
"methods": ["GET"],
|
||||||
oauth = OAuth()
|
"max_age": 3600
|
||||||
"""
|
}
|
||||||
|
})
|
||||||
|
|
||||||
csrf.init_app(app)
|
csrf.init_app(app)
|
||||||
cors.init_app(app)
|
cors.init_app(app)
|
||||||
@@ -132,4 +133,14 @@ app.register_blueprint(routes_user)
|
|||||||
@app.template_filter('console_log')
|
@app.template_filter('console_log')
|
||||||
def console_log(value):
|
def console_log(value):
|
||||||
Helper_App.console_log(value)
|
Helper_App.console_log(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@app.after_request
|
||||||
|
def add_cache_headers(response):
|
||||||
|
if request.path.startswith('/static/'):
|
||||||
|
# Cache static assets
|
||||||
|
response.headers['Cache-Control'] = 'public, max-age=31536000'
|
||||||
|
else:
|
||||||
|
# No caching for dynamic content
|
||||||
|
response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
|
||||||
|
return response
|
||||||
@@ -40,7 +40,8 @@ class Config:
|
|||||||
# Auth0
|
# Auth0
|
||||||
SESSION_COOKIE_SECURE = True
|
SESSION_COOKIE_SECURE = True
|
||||||
SESSION_COOKIE_HTTPONLY = True
|
SESSION_COOKIE_HTTPONLY = True
|
||||||
# SESSION_COOKIE_SAMESITE = 'Lax'
|
SESSION_COOKIE_SAMESITE = 'Strict'
|
||||||
|
REMEMBER_COOKIE_SECURE = True
|
||||||
# PERMANENT_SESSION_LIFETIME = 3600
|
# PERMANENT_SESSION_LIFETIME = 3600
|
||||||
WTF_CSRF_ENABLED = True
|
WTF_CSRF_ENABLED = True
|
||||||
# WTF_CSRF_CHECK_DEFAULT = False # We'll check it manually for API routes
|
# WTF_CSRF_CHECK_DEFAULT = False # We'll check it manually for API routes
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from authlib.integrations.flask_client import OAuth
|
|||||||
|
|
||||||
|
|
||||||
csrf = CSRFProtect()
|
csrf = CSRFProtect()
|
||||||
cors = CORS()
|
# cors = CORS()
|
||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
mail = Mail()
|
mail = Mail()
|
||||||
oauth = OAuth()
|
oauth = OAuth()
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import DOM from './dom.js';
|
import DOM from './dom.js';
|
||||||
|
|
||||||
// Module for API calls
|
|
||||||
export default class API {
|
export default class API {
|
||||||
|
|
||||||
static getCsrfToken() {
|
static getCsrfToken() {
|
||||||
@@ -151,7 +150,6 @@ export default class API {
|
|||||||
const api = new API();
|
const api = new API();
|
||||||
export default api;
|
export default api;
|
||||||
|
|
||||||
Example of using the API
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
initializeApp();
|
initializeApp();
|
||||||
setupEventListeners();
|
setupEventListeners();
|
||||||
|
|||||||
@@ -1,30 +1,6 @@
|
|||||||
/*
|
|
||||||
// Bundle css imports
|
|
||||||
import '../css/lib/reset.css';
|
|
||||||
import '../css/lib/typography.css';
|
|
||||||
import '../css/lib/variables.css';
|
|
||||||
import '../css/lib/utils.css';
|
|
||||||
|
|
||||||
import '../css/layouts/header.css';
|
|
||||||
import '../css/layouts/footer.css';
|
|
||||||
import '../css/layouts/table-main.css'
|
|
||||||
|
|
||||||
import '../css/components/button.css';
|
|
||||||
import '../css/components/card.css';
|
|
||||||
import '../css/components/dialog.css';
|
|
||||||
import '../css/components/form.css';
|
|
||||||
import '../css/components/modal.css';
|
|
||||||
import '../css/components/navigation.css';
|
|
||||||
import '../css/components/overlay.css';
|
|
||||||
|
|
||||||
import '../css/sections/store.css';
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Main entry point for the application
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// import API from './api.js';
|
|
||||||
import DOM from './dom.js';
|
import DOM from './dom.js';
|
||||||
import Router from './router.js';
|
import Router from './router.js';
|
||||||
|
|
||||||
@@ -41,34 +17,24 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupEventListeners() {
|
setupEventListeners() {
|
||||||
// Global event listeners
|
|
||||||
// document.addEventListener('click', this.handleGlobalClick.bind(this));
|
// document.addEventListener('click', this.handleGlobalClick.bind(this));
|
||||||
// Add more global event listeners as needed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleGlobalClick(event) {
|
handleGlobalClick(event) {
|
||||||
// Handle global click events
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
// Additional startup logic
|
|
||||||
this.initPageCurrent();
|
this.initPageCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
initPageCurrent() {
|
initPageCurrent() {
|
||||||
/*
|
|
||||||
_pageCurrent = Router.getPageCurrent();
|
|
||||||
_pageCurrent.initialize();
|
|
||||||
*/
|
|
||||||
this.router.loadPageCurrent();
|
this.router.loadPageCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Application instance
|
|
||||||
const app = new App();
|
const app = new App();
|
||||||
|
|
||||||
// DOM ready handler
|
|
||||||
function domReady(fn) {
|
function domReady(fn) {
|
||||||
if (document.readyState !== 'loading') {
|
if (document.readyState !== 'loading') {
|
||||||
fn();
|
fn();
|
||||||
@@ -77,13 +43,10 @@ function domReady(fn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize and start the app when DOM is ready
|
|
||||||
domReady(() => {
|
domReady(() => {
|
||||||
app.initialize();
|
app.initialize();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Expose app to window for debugging (optional)
|
|
||||||
window.app = app;
|
window.app = app;
|
||||||
|
|
||||||
// Export app if using modules
|
|
||||||
export default app;
|
export default app;
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
import Validation from "./lib/validation.js";
|
import Validation from "./lib/validation.js";
|
||||||
|
|
||||||
// Module for DOM manipulation
|
|
||||||
export default class DOM {
|
export default class DOM {
|
||||||
static setElementAttributesValuesCurrentAndPrevious(element, data) {
|
static setElementAttributesValuesCurrentAndPrevious(element, data) {
|
||||||
DOM.setElementAttributeValueCurrent(element, data);
|
DOM.setElementAttributeValueCurrent(element, data);
|
||||||
|
|||||||
@@ -27,44 +27,11 @@ import PageStoreSupplierPurchaseOrders from './pages/store/supplier_purchase_ord
|
|||||||
// import PageUserAccount from './pages/user/account.js';
|
// import PageUserAccount from './pages/user/account.js';
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
import "./lib/common.js";
|
|
||||||
import "./lib/constants.js";
|
|
||||||
import "./lib/events.js";
|
|
||||||
import "./lib/extras.js";
|
|
||||||
// import "./DEPRECATED/init.js";
|
|
||||||
import "./lib/local_storage.js";
|
|
||||||
import "./lib/utils.js";
|
|
||||||
import "./lib/validation.js";
|
|
||||||
*/
|
|
||||||
|
|
||||||
import API from './api.js';
|
import API from './api.js';
|
||||||
import DOM from './dom.js';
|
import DOM from './dom.js';
|
||||||
import PagePrivacyPolicy from './pages/legal/privacy_policy.js';
|
import PagePrivacyPolicy from './pages/legal/privacy_policy.js';
|
||||||
import PageRetentionSchedule from './pages/legal/retention_schedule.js';
|
import PageRetentionSchedule from './pages/legal/retention_schedule.js';
|
||||||
|
|
||||||
// Create a context for the pages
|
|
||||||
// const pagesContext = require.context('./pages', true, /\.js$/);
|
|
||||||
|
|
||||||
/*
|
|
||||||
const pageModules = {
|
|
||||||
// Core
|
|
||||||
[hashPageHome]: () => import('./pages/core/home.js'),
|
|
||||||
[hashPageContact]: () => import('./pages/core/contact.js'),
|
|
||||||
[hashPageServices]: () => import('./pages/core/services.js'),
|
|
||||||
[hashPageAdminHome]: () => import('./pages/core/admin_home.js'),
|
|
||||||
// Legal
|
|
||||||
[hashPageAccessibilityStatement]: () => import('./pages/legal/accessibility_statement.js'),
|
|
||||||
[hashPageLicense]: () => import('./pages/legal/license.js'),
|
|
||||||
// Store
|
|
||||||
[hashPageStoreProductCategories]: () => import('./pages/store/product_categories.js'),
|
|
||||||
[hashPageStoreProductPermutations]: () => import('./pages/store/product_permutations.js'),
|
|
||||||
// [hashPageStoreProducts]: () => import('./pages/store/products.js'),
|
|
||||||
// User
|
|
||||||
// Add other pages here...
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default class Router {
|
export default class Router {
|
||||||
constructor() {
|
constructor() {
|
||||||
// Pages
|
// Pages
|
||||||
@@ -326,11 +293,8 @@ export default class Router {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and export a singleton instance
|
|
||||||
export const router = new Router();
|
export const router = new Router();
|
||||||
// import this for navigation
|
|
||||||
|
|
||||||
// Usage example (you can put this in your main.js or app.js)
|
|
||||||
/*
|
/*
|
||||||
router.addRoute('/', () => {
|
router.addRoute('/', () => {
|
||||||
console.log('Home page');
|
console.log('Home page');
|
||||||
@@ -342,7 +306,6 @@ router.addRoute('/about', () => {
|
|||||||
// Load about page content
|
// Load about page content
|
||||||
});
|
});
|
||||||
|
|
||||||
// Example of how to use the router in other parts of your application
|
|
||||||
export function setupNavigationEvents() {
|
export function setupNavigationEvents() {
|
||||||
document.querySelectorAll('a[data-nav]').forEach(link => {
|
document.querySelectorAll('a[data-nav]').forEach(link => {
|
||||||
link.addEventListener('click', (e) => {
|
link.addEventListener('click', (e) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user