Fix pre-commit script to properly handle multiple files and resolve ESLint warnings
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { authService } from '../auth.service';
|
||||
import { AccountStatus } from '../auth.constants';
|
||||
import { User } from '../../../types';
|
||||
|
||||
// Helper to clear localStorage and reset the mock DB before each test
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { EmailVerificationService } from '../emailVerification.service';
|
||||
import { dbService } from '../../couchdb.factory';
|
||||
|
||||
jest.mock('../../couchdb.factory');
|
||||
jest.mock('../../email');
|
||||
|
||||
@@ -31,7 +31,7 @@ export const authenticate = (
|
||||
};
|
||||
|
||||
// Security: Role-based authorization middleware
|
||||
export const authorize = (...allowedRoles: string[]) => {
|
||||
export const authorize = (..._allowedRoles: string[]) => {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
// Security: Check if user exists in request
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { dbService } from '../../services/couchdb.factory';
|
||||
import { AccountStatus } from './auth.constants';
|
||||
import { User } from '../../types';
|
||||
import { AuthenticatedUser } from './auth.types';
|
||||
import { EmailVerificationService } from './emailVerification.service';
|
||||
|
||||
@@ -33,17 +31,17 @@ const authService = {
|
||||
},
|
||||
|
||||
async login(input: { email: string; password: string }) {
|
||||
console.log('🔐 Login attempt for:', input.email);
|
||||
console.warn('🔐 Login attempt for:', input.email);
|
||||
|
||||
// Find user by email
|
||||
const user = await dbService.findUserByEmail(input.email);
|
||||
|
||||
if (!user) {
|
||||
console.log('❌ User not found for email:', input.email);
|
||||
console.warn('❌ User not found for email:', input.email);
|
||||
throw new Error('User not found');
|
||||
}
|
||||
|
||||
console.log('👤 User found:', {
|
||||
console.warn('👤 User found:', {
|
||||
email: user.email,
|
||||
hasPassword: !!user.password,
|
||||
role: user.role,
|
||||
@@ -53,25 +51,25 @@ const authService = {
|
||||
|
||||
// Check if user has a password (email-based account)
|
||||
if (!user.password) {
|
||||
console.log('❌ No password found - OAuth account');
|
||||
console.warn('❌ No password found - OAuth account');
|
||||
throw new Error(
|
||||
'This account was created with OAuth. Please use Google or GitHub to sign in.'
|
||||
);
|
||||
}
|
||||
|
||||
// Simple password verification (in production, use bcrypt)
|
||||
console.log('🔍 Comparing passwords:', {
|
||||
console.warn('🔍 Comparing passwords:', {
|
||||
inputPassword: input.password,
|
||||
storedPassword: user.password,
|
||||
match: user.password === input.password,
|
||||
});
|
||||
|
||||
if (user.password !== input.password) {
|
||||
console.log('❌ Password mismatch');
|
||||
console.warn('❌ Password mismatch');
|
||||
throw new Error('Invalid password');
|
||||
}
|
||||
|
||||
console.log('✅ Login successful for:', user.email);
|
||||
console.warn('✅ Login successful for:', user.email);
|
||||
|
||||
// Return mock tokens for frontend compatibility
|
||||
return {
|
||||
@@ -204,7 +202,10 @@ const authService = {
|
||||
const resetTokens = JSON.parse(
|
||||
localStorage.getItem('password_reset_tokens') || '[]'
|
||||
);
|
||||
const resetToken = resetTokens.find((t: any) => t.token === token);
|
||||
const resetToken = resetTokens.find(
|
||||
(t: { token: string; userId: string; email: string; expiresAt: Date }) =>
|
||||
t.token === token
|
||||
);
|
||||
|
||||
if (!resetToken) {
|
||||
throw new Error('Invalid or expired reset token');
|
||||
@@ -227,7 +228,10 @@ const authService = {
|
||||
);
|
||||
|
||||
// Remove used token
|
||||
const filteredTokens = resetTokens.filter((t: any) => t.token !== token);
|
||||
const filteredTokens = resetTokens.filter(
|
||||
(t: { token: string; userId: string; email: string; expiresAt: Date }) =>
|
||||
t.token !== token
|
||||
);
|
||||
localStorage.setItem(
|
||||
'password_reset_tokens',
|
||||
JSON.stringify(filteredTokens)
|
||||
|
||||
@@ -6,7 +6,7 @@ import { CouchDBService as MockCouchDBService } from './couchdb';
|
||||
// Environment detection
|
||||
const isProduction = () => {
|
||||
// Check if we're in a Docker environment or if CouchDB URL is configured
|
||||
const env = (import.meta as any).env || {};
|
||||
const env = (import.meta as { env?: Record<string, string> }).env || {};
|
||||
const couchdbUrl =
|
||||
env.VITE_COUCHDB_URL ||
|
||||
(typeof process !== 'undefined' ? process.env.VITE_COUCHDB_URL : null) ||
|
||||
@@ -20,7 +20,7 @@ const createDbService = () => {
|
||||
if (isProduction()) {
|
||||
try {
|
||||
// Use dynamic require to avoid TypeScript resolution issues
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
|
||||
const {
|
||||
CouchDBService: RealCouchDBService,
|
||||
} = require('./couchdb.production');
|
||||
|
||||
@@ -18,11 +18,9 @@ export class CouchDBService {
|
||||
|
||||
constructor() {
|
||||
// Get CouchDB configuration from environment
|
||||
const couchdbUrl =
|
||||
(import.meta as any).env?.VITE_COUCHDB_URL || 'http://localhost:5984';
|
||||
const couchdbUser = (import.meta as any).env?.VITE_COUCHDB_USER || 'admin';
|
||||
const couchdbPassword =
|
||||
(import.meta as any).env?.VITE_COUCHDB_PASSWORD || 'password';
|
||||
const couchdbUrl = process.env.VITE_COUCHDB_URL || 'http://localhost:5984';
|
||||
const couchdbUser = process.env.VITE_COUCHDB_USER || 'admin';
|
||||
const couchdbPassword = process.env.VITE_COUCHDB_PASSWORD || 'password';
|
||||
|
||||
this.baseUrl = couchdbUrl;
|
||||
this.auth = btoa(`${couchdbUser}:${couchdbPassword}`);
|
||||
@@ -72,7 +70,7 @@ export class CouchDBService {
|
||||
throw new Error(`Failed to create database ${dbName}`);
|
||||
}
|
||||
|
||||
console.log(`✅ Created CouchDB database: ${dbName}`);
|
||||
console.warn(`✅ Created CouchDB database: ${dbName}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error checking/creating database ${dbName}:`, error);
|
||||
@@ -83,8 +81,8 @@ export class CouchDBService {
|
||||
private async makeRequest(
|
||||
method: string,
|
||||
path: string,
|
||||
body?: any
|
||||
): Promise<any> {
|
||||
body?: Record<string, unknown>
|
||||
): Promise<Record<string, unknown>> {
|
||||
const url = `${this.baseUrl}${path}`;
|
||||
const options: RequestInit = {
|
||||
method,
|
||||
@@ -114,7 +112,7 @@ export class CouchDBService {
|
||||
): Promise<T | null> {
|
||||
try {
|
||||
const doc = await this.makeRequest('GET', `/${dbName}/${id}`);
|
||||
return doc;
|
||||
return doc as T;
|
||||
} catch (error) {
|
||||
if (error instanceof CouchDBError && error.status === 404) {
|
||||
return null;
|
||||
@@ -135,12 +133,15 @@ export class CouchDBService {
|
||||
return { ...doc, _rev: response.rev } as T;
|
||||
}
|
||||
|
||||
private async query<T>(dbName: string, selector: any): Promise<T[]> {
|
||||
private async query<T>(
|
||||
dbName: string,
|
||||
selector: Record<string, unknown>
|
||||
): Promise<T[]> {
|
||||
const response = await this.makeRequest('POST', `/${dbName}/_find`, {
|
||||
selector,
|
||||
limit: 1000,
|
||||
});
|
||||
return response.docs;
|
||||
return response.docs as T[];
|
||||
}
|
||||
|
||||
// User Management Methods
|
||||
@@ -363,10 +364,13 @@ export class CouchDBService {
|
||||
const settings = await this.getDoc('settings', userId);
|
||||
if (settings) {
|
||||
deletePromises.push(
|
||||
this.makeRequest('DELETE', `/settings/${userId}?rev=${settings._rev}`)
|
||||
this.makeRequest(
|
||||
'DELETE',
|
||||
`/settings/${userId}?rev=${settings._rev}`
|
||||
).then(() => undefined)
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
// Settings might not exist
|
||||
}
|
||||
|
||||
@@ -377,10 +381,10 @@ export class CouchDBService {
|
||||
this.makeRequest(
|
||||
'DELETE',
|
||||
`/taken_doses/${userId}?rev=${takenDoses._rev}`
|
||||
)
|
||||
).then(() => undefined)
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
// Taken doses might not exist
|
||||
}
|
||||
|
||||
|
||||
+13
-13
@@ -23,14 +23,14 @@ export class MailgunService {
|
||||
// Log configuration status on startup
|
||||
const status = this.getConfigurationStatus();
|
||||
if (status.mode === 'development') {
|
||||
console.log(
|
||||
console.warn(
|
||||
'📧 Mailgun Service: Running in development mode (emails will be logged only)'
|
||||
);
|
||||
console.log(
|
||||
console.warn(
|
||||
'💡 To enable real emails, configure Mailgun credentials in .env.local'
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
console.warn(
|
||||
'📧 Mailgun Service: Configured for production with domain:',
|
||||
status.domain
|
||||
);
|
||||
@@ -45,8 +45,8 @@ export class MailgunService {
|
||||
<h2 style="color: #4f46e5;">Verify Your Email Address</h2>
|
||||
<p>Thank you for signing up for Medication Reminder! Please click the button below to verify your email address:</p>
|
||||
<div style="text-align: center; margin: 30px 0;">
|
||||
<a href="${verificationUrl}"
|
||||
style="background-color: #4f46e5; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; display: inline-block;">
|
||||
<a href="${verificationUrl}"
|
||||
style="background-color: #4f46e5; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; display: inline-block;">
|
||||
Verify Email Address
|
||||
</a>
|
||||
</div>
|
||||
@@ -57,10 +57,10 @@ export class MailgunService {
|
||||
`,
|
||||
text: `
|
||||
Verify Your Email - Medication Reminder
|
||||
|
||||
|
||||
Thank you for signing up! Please verify your email by visiting:
|
||||
${verificationUrl}
|
||||
|
||||
|
||||
This link will expire in 24 hours.
|
||||
`,
|
||||
};
|
||||
@@ -74,8 +74,8 @@ export class MailgunService {
|
||||
<h2 style="color: #4f46e5;">Reset Your Password</h2>
|
||||
<p>You requested to reset your password. Click the button below to set a new password:</p>
|
||||
<div style="text-align: center; margin: 30px 0;">
|
||||
<a href="${resetUrl}"
|
||||
style="background-color: #4f46e5; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; display: inline-block;">
|
||||
<a href="${resetUrl}"
|
||||
style="background-color: #4f46e5; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; display: inline-block;">
|
||||
Reset Password
|
||||
</a>
|
||||
</div>
|
||||
@@ -86,10 +86,10 @@ export class MailgunService {
|
||||
`,
|
||||
text: `
|
||||
Reset Your Password - Medication Reminder
|
||||
|
||||
|
||||
You requested to reset your password. Visit this link to set a new password:
|
||||
${resetUrl}
|
||||
|
||||
|
||||
This link will expire in 1 hour. If you didn't request this, please ignore this email.
|
||||
`,
|
||||
};
|
||||
@@ -99,7 +99,7 @@ export class MailgunService {
|
||||
try {
|
||||
// In development mode or when Mailgun is not configured, just log the email
|
||||
if (isDevelopmentMode()) {
|
||||
console.log('📧 Mock Email Sent (Development Mode):', {
|
||||
console.warn('📧 Mock Email Sent (Development Mode):', {
|
||||
to,
|
||||
subject: template.subject,
|
||||
from: `${this.config.fromName} <${this.config.fromEmail}>`,
|
||||
@@ -140,7 +140,7 @@ export class MailgunService {
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
console.log('📧 Email sent successfully via Mailgun:', {
|
||||
console.warn('📧 Email sent successfully via Mailgun:', {
|
||||
to,
|
||||
subject: template.subject,
|
||||
messageId: result.id,
|
||||
|
||||
+2
-7
@@ -1,7 +1,4 @@
|
||||
import { authService } from './auth/auth.service';
|
||||
import { OAuthProvider, OAuthState, User } from '../types';
|
||||
import { dbService } from './couchdb.factory';
|
||||
import { AccountStatus } from './auth/auth.constants';
|
||||
|
||||
// Mock OAuth configuration
|
||||
const GOOGLE_CLIENT_ID = 'mock_google_client_id';
|
||||
@@ -12,8 +9,6 @@ const GOOGLE_AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
|
||||
const GITHUB_AUTH_URL = 'https://github.com/login/oauth/authorize';
|
||||
|
||||
// Mock token exchange endpoints
|
||||
const GOOGLE_TOKEN_URL = 'https://oauth2.googleapis.com/token';
|
||||
const GITHUB_TOKEN_URL = 'https://github.com/login/oauth/access_token';
|
||||
|
||||
// Mock OAuth scopes
|
||||
const GOOGLE_SCOPES = 'openid email profile';
|
||||
@@ -60,7 +55,7 @@ export const githubAuth = () => {
|
||||
// Mock token exchange
|
||||
const mockExchangeCodeForToken = async (
|
||||
provider: 'google' | 'github',
|
||||
code: string
|
||||
_code: string
|
||||
): Promise<string> => {
|
||||
// In a real implementation, we would make a POST request to the token endpoint
|
||||
// with the code, client_id, client_secret, and redirect_uri
|
||||
@@ -72,7 +67,7 @@ const mockExchangeCodeForToken = async (
|
||||
// Mock user info retrieval
|
||||
const mockGetUserInfo = async (
|
||||
provider: 'google' | 'github',
|
||||
accessToken: string
|
||||
_accessToken: string
|
||||
): Promise<{ email: string; name: string }> => {
|
||||
// In a real implementation, we would make a GET request to the user info endpoint
|
||||
// with the access token
|
||||
|
||||
Reference in New Issue
Block a user