Security hardening: authentication, input validation, OWASP compliance, architecture improvements, and CSP fixes for browser mode (#942)

This commit is contained in:
Copilot
2025-12-22 16:52:42 +01:00
committed by GitHub
parent a7136bd572
commit 6c041cba02
50 changed files with 1943 additions and 734 deletions

View File

@@ -1,5 +1,6 @@
// Browser-specific webpack configuration
import HtmlWebpackPlugin from 'html-webpack-plugin'
// Extends the base webpack.config.mjs with minimal browser-specific overrides
import baseConfig from './webpack.config.mjs'
import webpack from 'webpack'
import path from 'path'
import { fileURLToPath } from 'url'
@@ -9,99 +10,87 @@ const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
export default {
entry: {
app: './src/index.tsx',
bugtracking: './src/utils/bugtracking.ts',
},
output: {
chunkFilename: '[name].bundle.js',
filename: '[name].bundle.js',
path: `${__dirname}/build`,
},
optimization: {
minimize: false,
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/](react|react-dom|@material-ui|popper\.js|react|react-redux|prop-types|jss|redux|scheduler|react-transition-group)[\\/]/,
name: 'vendors',
chunks: 'all',
priority: -10,
},
default: {
name: 'default',
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
runtimeChunk: 'single',
},
devServer: {
hot: true,
liveReload: true,
},
target: 'web', // Changed from 'electron-renderer' to 'web'
mode: 'production',
devtool: 'source-map',
...baseConfig,
// Browser target instead of electron-renderer
target: 'web',
// Browser-specific module resolution
resolve: {
extensions: ['.ts', '.mjs', '.m.js', '.tsx', '.js', '.json'],
modules: ['node_modules', path.resolve(__dirname, 'node_modules')],
...baseConfig.resolve,
modules: [
path.resolve(__dirname, 'node_modules'), // App-level node_modules (priority for browser deps)
path.resolve(__dirname, '..', 'node_modules'), // Root-level node_modules
'node_modules',
],
alias: {
electron: path.resolve(__dirname, './src/mocks/electron.ts'),
},
fallback: {
// Browser fallbacks for Node.js modules
path: 'path-browserify',
fs: false,
crypto: false,
url: 'url/',
os: 'os-browserify/browser',
events: 'events/',
},
},
module: {
rules: [
// Browser-specific plugins
plugins: [
// Replace base config's DefinePlugin with one that includes both NODE_ENV and BROWSER_MODE
...baseConfig.plugins.filter(plugin => !(plugin instanceof webpack.DefinePlugin)),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
'process.env.BROWSER_MODE': JSON.stringify('true'),
}),
// Replace events/index with browser-specific version that excludes IPC EventBus
new webpack.NormalModuleReplacementPlugin(/^\.\.\/\.\.\/\.\.\/events$/, resource => {
// Point to browser event bus when importing from '../../../events'
resource.request = path.resolve(__dirname, 'src', 'browserEventBus.ts')
}),
new webpack.NormalModuleReplacementPlugin(/^\.\.\/\.\.\/\.\.\/\.\.\/events$/, resource => {
// Point to browser event bus when importing from '../../../../events'
resource.request = path.resolve(__dirname, 'src', 'browserEventBus.ts')
}),
// Replace EventSystem/EventBus directly as well
new webpack.NormalModuleReplacementPlugin(/events[\\/]EventSystem[\\/]EventBus$/, resource => {
resource.request = path.resolve(__dirname, 'src', 'browserEventBus.ts')
}),
// Exclude IPC-based EventBus files completely
new webpack.IgnorePlugin({
resourceRegExp: /IpcRendererEventBus\.ts$/,
}),
new webpack.IgnorePlugin({
resourceRegExp: /IpcMainEventBus\.ts$/,
}),
],
// Cache directory
cache: {
...baseConfig.cache,
cacheDirectory: path.resolve(__dirname, '.webpack-cache'),
},
// Dev server configuration for browser mode development
devServer: {
static: {
directory: path.resolve(__dirname),
publicPath: '/',
},
compress: true,
port: 8080, // Different port from backend server (3000)
hot: true,
historyApiFallback: true,
proxy: [
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true, // Skip type checking, we already did it with tsc
},
},
],
exclude: /node_modules/,
},
{ enforce: 'pre', test: /\.js$/, loader: 'source-map-loader' },
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif)$/i,
type: 'asset/resource',
// Proxy API, auth, and socket.io requests to backend server
context: ['/socket.io', '/api', '/auth'],
target: 'http://localhost:3000',
ws: true, // Enable WebSocket proxying
changeOrigin: true,
},
],
},
plugins: [
new HtmlWebpackPlugin({ template: './index.html', file: './build/index.html', inject: false }),
new webpack.DefinePlugin({
'process.env.BROWSER_MODE': JSON.stringify('true'),
}),
new webpack.NormalModuleReplacementPlugin(/EventSystem[\\/]EventBus$/, resource => {
console.log('Replacing EventBus:', resource.request)
resource.request = resource.request.replace(/EventBus$/, 'BrowserEventBus')
}),
],
externals: {},
cache: false,
}