cleanup: remove legacy config and backup files
- Remove deprecated config/app.config.ts - Clean up old test backup files in tests/.backup/ - Completes transition to unified configuration system - Eliminates potential confusion from dual config sources
This commit is contained in:
@@ -1,355 +0,0 @@
|
|||||||
// Centralized Application Configuration
|
|
||||||
// This file consolidates all configuration constants and environment variables
|
|
||||||
// to eliminate duplication and provide a single source of truth
|
|
||||||
|
|
||||||
import { getEnvVar, isProduction, isTest } from '../utils/env';
|
|
||||||
|
|
||||||
// Simple console logging for configuration (avoid circular dependency with logger)
|
|
||||||
const configLog = {
|
|
||||||
warn: (message: string) => console.warn(`⚠️ Config: ${message}`),
|
|
||||||
error: (message: string) => console.error(`❌ Config: ${message}`),
|
|
||||||
info: (message: string) => console.warn(`📋 Config: ${message}`),
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Application Configuration Interface
|
|
||||||
*/
|
|
||||||
export interface AppConfig {
|
|
||||||
// Application Identity
|
|
||||||
name: string;
|
|
||||||
version: string;
|
|
||||||
|
|
||||||
// URLs and Endpoints
|
|
||||||
baseUrl: string;
|
|
||||||
apiUrl: string;
|
|
||||||
|
|
||||||
// Database Configuration
|
|
||||||
database: {
|
|
||||||
url: string;
|
|
||||||
username: string;
|
|
||||||
password: string;
|
|
||||||
useMock: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Authentication Configuration
|
|
||||||
auth: {
|
|
||||||
jwtSecret: string;
|
|
||||||
jwtExpiresIn: string;
|
|
||||||
refreshTokenExpiresIn: string;
|
|
||||||
emailVerificationExpiresIn: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Email Configuration
|
|
||||||
email: {
|
|
||||||
mailgun: {
|
|
||||||
apiKey?: string;
|
|
||||||
domain?: string;
|
|
||||||
baseUrl: string;
|
|
||||||
fromName: string;
|
|
||||||
fromEmail?: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// OAuth Configuration
|
|
||||||
oauth: {
|
|
||||||
google: {
|
|
||||||
clientId?: string;
|
|
||||||
};
|
|
||||||
github: {
|
|
||||||
clientId?: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Feature Flags
|
|
||||||
features: {
|
|
||||||
enableEmailVerification: boolean;
|
|
||||||
enableOAuth: boolean;
|
|
||||||
enableAdminInterface: boolean;
|
|
||||||
debugMode: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Environment Information
|
|
||||||
environment: {
|
|
||||||
nodeEnv: string;
|
|
||||||
isProduction: boolean;
|
|
||||||
isTest: boolean;
|
|
||||||
isDevelopment: boolean;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default Configuration Values
|
|
||||||
*/
|
|
||||||
const DEFAULT_CONFIG: Partial<AppConfig> = {
|
|
||||||
name: 'RxMinder',
|
|
||||||
version: '1.0.0',
|
|
||||||
baseUrl: 'http://localhost:5173',
|
|
||||||
apiUrl: 'http://localhost:3000/api',
|
|
||||||
|
|
||||||
database: {
|
|
||||||
url: 'http://localhost:5984',
|
|
||||||
username: 'admin',
|
|
||||||
password: 'password',
|
|
||||||
useMock: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
auth: {
|
|
||||||
jwtSecret: 'your-super-secret-jwt-key-change-in-production',
|
|
||||||
jwtExpiresIn: '1h',
|
|
||||||
refreshTokenExpiresIn: '7d',
|
|
||||||
emailVerificationExpiresIn: '24h',
|
|
||||||
},
|
|
||||||
|
|
||||||
email: {
|
|
||||||
mailgun: {
|
|
||||||
baseUrl: 'https://api.mailgun.net/v3',
|
|
||||||
fromName: 'RxMinder',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
features: {
|
|
||||||
enableEmailVerification: true,
|
|
||||||
enableOAuth: true,
|
|
||||||
enableAdminInterface: true,
|
|
||||||
debugMode: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load configuration from environment variables with fallbacks
|
|
||||||
*/
|
|
||||||
function loadConfig(): AppConfig {
|
|
||||||
const nodeEnv = getEnvVar('NODE_ENV') || 'development';
|
|
||||||
const isProd = isProduction();
|
|
||||||
const isTestEnv = isTest();
|
|
||||||
const isDev = nodeEnv === 'development';
|
|
||||||
|
|
||||||
return {
|
|
||||||
// Application Identity
|
|
||||||
name:
|
|
||||||
getEnvVar('VITE_APP_NAME') ||
|
|
||||||
getEnvVar('APP_NAME') ||
|
|
||||||
DEFAULT_CONFIG.name!,
|
|
||||||
version: getEnvVar('VITE_APP_VERSION') || DEFAULT_CONFIG.version!,
|
|
||||||
|
|
||||||
// URLs and Endpoints
|
|
||||||
baseUrl:
|
|
||||||
getEnvVar('APP_BASE_URL') ||
|
|
||||||
getEnvVar('VITE_BASE_URL') ||
|
|
||||||
DEFAULT_CONFIG.baseUrl!,
|
|
||||||
apiUrl:
|
|
||||||
getEnvVar('API_URL') ||
|
|
||||||
getEnvVar('VITE_API_URL') ||
|
|
||||||
DEFAULT_CONFIG.apiUrl!,
|
|
||||||
|
|
||||||
// Database Configuration
|
|
||||||
database: {
|
|
||||||
url:
|
|
||||||
getEnvVar('VITE_COUCHDB_URL') ||
|
|
||||||
getEnvVar('COUCHDB_URL') ||
|
|
||||||
DEFAULT_CONFIG.database!.url,
|
|
||||||
username:
|
|
||||||
getEnvVar('VITE_COUCHDB_USER') ||
|
|
||||||
getEnvVar('COUCHDB_USER') ||
|
|
||||||
DEFAULT_CONFIG.database!.username,
|
|
||||||
password:
|
|
||||||
getEnvVar('VITE_COUCHDB_PASSWORD') ||
|
|
||||||
getEnvVar('COUCHDB_PASSWORD') ||
|
|
||||||
DEFAULT_CONFIG.database!.password,
|
|
||||||
useMock:
|
|
||||||
isTestEnv ||
|
|
||||||
getEnvVar('USE_MOCK_DB') === 'true' ||
|
|
||||||
(!getEnvVar('VITE_COUCHDB_URL') && !getEnvVar('COUCHDB_URL')),
|
|
||||||
},
|
|
||||||
|
|
||||||
// Authentication Configuration
|
|
||||||
auth: {
|
|
||||||
jwtSecret: getEnvVar('JWT_SECRET') || DEFAULT_CONFIG.auth!.jwtSecret,
|
|
||||||
jwtExpiresIn:
|
|
||||||
getEnvVar('JWT_EXPIRES_IN') || DEFAULT_CONFIG.auth!.jwtExpiresIn,
|
|
||||||
refreshTokenExpiresIn:
|
|
||||||
getEnvVar('REFRESH_TOKEN_EXPIRES_IN') ||
|
|
||||||
DEFAULT_CONFIG.auth!.refreshTokenExpiresIn,
|
|
||||||
emailVerificationExpiresIn:
|
|
||||||
getEnvVar('EMAIL_VERIFICATION_EXPIRES_IN') ||
|
|
||||||
DEFAULT_CONFIG.auth!.emailVerificationExpiresIn,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Email Configuration
|
|
||||||
email: {
|
|
||||||
mailgun: {
|
|
||||||
apiKey:
|
|
||||||
getEnvVar('VITE_MAILGUN_API_KEY') || getEnvVar('MAILGUN_API_KEY'),
|
|
||||||
domain: getEnvVar('VITE_MAILGUN_DOMAIN') || getEnvVar('MAILGUN_DOMAIN'),
|
|
||||||
baseUrl:
|
|
||||||
getEnvVar('VITE_MAILGUN_BASE_URL') ||
|
|
||||||
getEnvVar('MAILGUN_BASE_URL') ||
|
|
||||||
DEFAULT_CONFIG.email!.mailgun!.baseUrl,
|
|
||||||
fromName:
|
|
||||||
getEnvVar('VITE_MAILGUN_FROM_NAME') ||
|
|
||||||
getEnvVar('MAILGUN_FROM_NAME') ||
|
|
||||||
DEFAULT_CONFIG.email!.mailgun!.fromName,
|
|
||||||
fromEmail:
|
|
||||||
getEnvVar('VITE_MAILGUN_FROM_EMAIL') ||
|
|
||||||
getEnvVar('MAILGUN_FROM_EMAIL'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// OAuth Configuration
|
|
||||||
oauth: {
|
|
||||||
google: {
|
|
||||||
clientId:
|
|
||||||
getEnvVar('VITE_GOOGLE_CLIENT_ID') || getEnvVar('GOOGLE_CLIENT_ID'),
|
|
||||||
},
|
|
||||||
github: {
|
|
||||||
clientId:
|
|
||||||
getEnvVar('VITE_GITHUB_CLIENT_ID') || getEnvVar('GITHUB_CLIENT_ID'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Feature Flags
|
|
||||||
features: {
|
|
||||||
enableEmailVerification:
|
|
||||||
getEnvVar('ENABLE_EMAIL_VERIFICATION') !== 'false',
|
|
||||||
enableOAuth: getEnvVar('ENABLE_OAUTH') !== 'false',
|
|
||||||
enableAdminInterface: getEnvVar('ENABLE_ADMIN_INTERFACE') !== 'false',
|
|
||||||
debugMode: isDev || getEnvVar('DEBUG_MODE') === 'true',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Environment Information
|
|
||||||
environment: {
|
|
||||||
nodeEnv,
|
|
||||||
isProduction: isProd,
|
|
||||||
isTest: isTestEnv,
|
|
||||||
isDevelopment: isDev,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate configuration and warn about missing values
|
|
||||||
*/
|
|
||||||
function validateConfig(config: AppConfig): void {
|
|
||||||
const warnings: string[] = [];
|
|
||||||
const errors: string[] = [];
|
|
||||||
|
|
||||||
// Check critical configuration
|
|
||||||
if (config.environment.isProduction) {
|
|
||||||
if (config.auth.jwtSecret === DEFAULT_CONFIG.auth!.jwtSecret) {
|
|
||||||
errors.push('JWT_SECRET must be changed in production');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.database.password === DEFAULT_CONFIG.database!.password) {
|
|
||||||
warnings.push(
|
|
||||||
'Consider changing default database password in production'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check email configuration if email verification is enabled
|
|
||||||
if (config.features.enableEmailVerification) {
|
|
||||||
if (!config.email.mailgun.apiKey) {
|
|
||||||
warnings.push(
|
|
||||||
'MAILGUN_API_KEY not configured - email features will use console logging'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.email.mailgun.domain) {
|
|
||||||
warnings.push(
|
|
||||||
'MAILGUN_DOMAIN not configured - email features may not work properly'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check OAuth configuration if OAuth is enabled
|
|
||||||
if (config.features.enableOAuth) {
|
|
||||||
if (!config.oauth.google.clientId && !config.oauth.github.clientId) {
|
|
||||||
warnings.push(
|
|
||||||
'No OAuth client IDs configured - OAuth features will be disabled'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log warnings and errors
|
|
||||||
if (warnings.length > 0) {
|
|
||||||
configLog.warn('Configuration warnings:');
|
|
||||||
warnings.forEach(warning => configLog.warn(` - ${warning}`));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errors.length > 0) {
|
|
||||||
configLog.error('Configuration errors:');
|
|
||||||
errors.forEach(error => configLog.error(` - ${error}`));
|
|
||||||
throw new Error('Critical configuration errors detected');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load and validate application configuration
|
|
||||||
*/
|
|
||||||
export function createAppConfig(): AppConfig {
|
|
||||||
const config = loadConfig();
|
|
||||||
|
|
||||||
// Only validate in non-test environments to avoid test noise
|
|
||||||
if (!config.environment.isTest) {
|
|
||||||
validateConfig(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Singleton application configuration instance
|
|
||||||
*/
|
|
||||||
export const appConfig = createAppConfig();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility functions for common configuration access patterns
|
|
||||||
*/
|
|
||||||
export const CONFIG = {
|
|
||||||
// Application
|
|
||||||
APP_NAME: appConfig.name,
|
|
||||||
APP_VERSION: appConfig.version,
|
|
||||||
BASE_URL: appConfig.baseUrl,
|
|
||||||
|
|
||||||
// Database
|
|
||||||
DATABASE_URL: appConfig.database.url,
|
|
||||||
USE_MOCK_DB: appConfig.database.useMock,
|
|
||||||
|
|
||||||
// Environment
|
|
||||||
IS_PRODUCTION: appConfig.environment.isProduction,
|
|
||||||
IS_DEVELOPMENT: appConfig.environment.isDevelopment,
|
|
||||||
IS_TEST: appConfig.environment.isTest,
|
|
||||||
DEBUG_MODE: appConfig.features.debugMode,
|
|
||||||
|
|
||||||
// Features
|
|
||||||
FEATURES: appConfig.features,
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get configuration for specific modules
|
|
||||||
*/
|
|
||||||
export const getAuthConfig = () => appConfig.auth;
|
|
||||||
export const getDatabaseConfig = () => appConfig.database;
|
|
||||||
export const getEmailConfig = () => appConfig.email;
|
|
||||||
export const getOAuthConfig = () => appConfig.oauth;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Development helper to log current configuration
|
|
||||||
*/
|
|
||||||
export function logConfig(): void {
|
|
||||||
if (appConfig.features.debugMode) {
|
|
||||||
configLog.info('Application Configuration');
|
|
||||||
configLog.info(`Environment: ${appConfig.environment.nodeEnv}`);
|
|
||||||
configLog.info(`App Name: ${appConfig.name}`);
|
|
||||||
configLog.info(`Base URL: ${appConfig.baseUrl}`);
|
|
||||||
configLog.info(
|
|
||||||
`Database Strategy: ${appConfig.database.useMock ? 'Mock' : 'Production'}`
|
|
||||||
);
|
|
||||||
configLog.info(`Features: ${JSON.stringify(appConfig.features)}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-log configuration in development
|
|
||||||
if (appConfig.features.debugMode && typeof window !== 'undefined') {
|
|
||||||
logConfig();
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
// Simple test script to verify admin login functionality
|
|
||||||
// Run this in the browser console to test admin credentials
|
|
||||||
|
|
||||||
async function testAdminLogin() {
|
|
||||||
console.log('🧪 Testing admin login...');
|
|
||||||
|
|
||||||
// Import the services (this won't work directly, but helps us understand the flow)
|
|
||||||
console.log('Admin credentials:');
|
|
||||||
console.log('Email: admin@localhost');
|
|
||||||
console.log('Password: admin123!');
|
|
||||||
|
|
||||||
// Check if admin user exists in localStorage
|
|
||||||
const users = JSON.parse(localStorage.getItem('users') || '[]');
|
|
||||||
console.log('All users in localStorage:', users);
|
|
||||||
|
|
||||||
const adminUser = users.find(u => u.email === 'admin@localhost');
|
|
||||||
console.log('Admin user found:', adminUser);
|
|
||||||
|
|
||||||
if (adminUser) {
|
|
||||||
console.log('Admin user details:');
|
|
||||||
console.log('- Email:', adminUser.email);
|
|
||||||
console.log('- Password:', adminUser.password);
|
|
||||||
console.log('- Role:', adminUser.role);
|
|
||||||
console.log('- Status:', adminUser.status);
|
|
||||||
console.log('- Email Verified:', adminUser.emailVerified);
|
|
||||||
} else {
|
|
||||||
console.log('❌ Admin user not found in localStorage');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instructions
|
|
||||||
console.log('Copy and paste this function in browser console:');
|
|
||||||
console.log(testAdminLogin.toString());
|
|
||||||
console.log('Then run: testAdminLogin()');
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
// Simple test to verify auth database functionality
|
|
||||||
// Run this in browser console at http://localhost:5174
|
|
||||||
|
|
||||||
console.log('Testing Authentication Database...');
|
|
||||||
|
|
||||||
// Test the mock database service
|
|
||||||
async function testDatabase() {
|
|
||||||
try {
|
|
||||||
// Import the services (this would work in browser context)
|
|
||||||
const { dbService } = await import('./services/couchdb.ts');
|
|
||||||
const { authService } = await import('./services/auth/auth.service.ts');
|
|
||||||
|
|
||||||
console.log('1. Testing user creation with password...');
|
|
||||||
|
|
||||||
// Test creating a user with password
|
|
||||||
const testEmail = 'test@example.com';
|
|
||||||
const testPassword = 'password123';
|
|
||||||
|
|
||||||
try {
|
|
||||||
const newUser = await dbService.createUserWithPassword(
|
|
||||||
testEmail,
|
|
||||||
testPassword
|
|
||||||
);
|
|
||||||
console.log('✅ User created successfully:', newUser);
|
|
||||||
} catch (error) {
|
|
||||||
if (error.message.includes('already exists')) {
|
|
||||||
console.log('ℹ️ User already exists, testing login...');
|
|
||||||
} else {
|
|
||||||
console.error('❌ User creation failed:', error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('2. Testing password login...');
|
|
||||||
|
|
||||||
// Test login with password
|
|
||||||
try {
|
|
||||||
const loginResult = await authService.login({
|
|
||||||
email: testEmail,
|
|
||||||
password: testPassword,
|
|
||||||
});
|
|
||||||
console.log('✅ Password login successful:', loginResult);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Password login failed:', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('3. Testing OAuth user creation...');
|
|
||||||
|
|
||||||
// Test OAuth user creation
|
|
||||||
const oauthData = {
|
|
||||||
email: 'oauth@example.com',
|
|
||||||
username: 'oauth_user',
|
|
||||||
avatar: 'https://example.com/avatar.jpg',
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const oauthUser = await dbService.createUserFromOAuth(oauthData);
|
|
||||||
console.log('✅ OAuth user created successfully:', oauthUser);
|
|
||||||
} catch (error) {
|
|
||||||
if (error.message.includes('already exists')) {
|
|
||||||
console.log('ℹ️ OAuth user already exists');
|
|
||||||
} else {
|
|
||||||
console.error('❌ OAuth user creation failed:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('4. Testing user lookup by email...');
|
|
||||||
|
|
||||||
// Test finding users
|
|
||||||
const foundUser = await dbService.findUserByEmail(testEmail);
|
|
||||||
console.log('✅ User found by email:', foundUser);
|
|
||||||
|
|
||||||
console.log('🎉 All database tests completed!');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('💥 Test setup failed:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export for manual testing
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
window.testAuthDB = testDatabase;
|
|
||||||
console.log('Run window.testAuthDB() to test the authentication database');
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
// Test the email validation in browser console
|
|
||||||
console.log('Testing email validation for admin@localhost');
|
|
||||||
|
|
||||||
const emailRegex = /^[^\s@]+@[^\s@]+(\.[^\s@]+|localhost)$/;
|
|
||||||
const testEmail = 'admin@localhost';
|
|
||||||
|
|
||||||
console.log('Email:', testEmail);
|
|
||||||
console.log('Regex:', emailRegex.toString());
|
|
||||||
console.log('Test result:', emailRegex.test(testEmail));
|
|
||||||
|
|
||||||
// Let's also test step by step
|
|
||||||
console.log('Parts breakdown:');
|
|
||||||
console.log('- Has @ symbol:', testEmail.includes('@'));
|
|
||||||
console.log('- Before @:', testEmail.split('@')[0]);
|
|
||||||
console.log('- After @:', testEmail.split('@')[1]);
|
|
||||||
console.log('- No spaces:', !/\s/.test(testEmail));
|
|
||||||
|
|
||||||
// Let's test a simpler regex that should definitely work
|
|
||||||
const simpleRegex = /^[^@\s]+@[^@\s]+$/;
|
|
||||||
console.log('Simple regex test:', simpleRegex.test(testEmail));
|
|
||||||
|
|
||||||
// Copy this code and paste it in the browser console when you get the validation error
|
|
||||||
Reference in New Issue
Block a user