-
-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Initialize Offline Secrets Manager with Prisma SQLite #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Initialize Offline Secrets Manager with Prisma SQLite #4
Conversation
- Fix import name from PBKDF2 to PBKDF2HMAC (correct cryptography API) - Fix SQLAlchemy session detachment issue in list_projects() - Eagerly load relationships to prevent lazy load errors Tested on macOS - all functionality working correctly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR represents a complete transformation of ENV Storage Manager from a Python CLI application to a modern Electron-based desktop application with React frontend. The changes introduce Prisma ORM with SQLite for offline data storage, build a comprehensive React UI using Ant Design components, and establish the foundation for a secure environment variable management system.
Key Changes:
- Complete technology stack migration: Python → JavaScript/Node.js with Electron + React
- Modern UI implementation: Full React frontend using Ant Design components with dark theme
- Database modernization: Prisma ORM with SQLite replacing direct SQLAlchemy implementation
Reviewed Changes
Copilot reviewed 61 out of 68 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | New project configuration with Electron, React, Vite, Prisma, and Ant Design dependencies |
| prisma/schema.prisma | Complete database schema definition for Config, Project, EnvVar, and AuditLog models |
| electron/main.js | Electron main process setup with window management and IPC handler initialization |
| electron/ipc-handlers.js | Comprehensive IPC handlers for authentication, projects, environment variables, and audit logging |
| electron/database.js | Prisma client initialization and database connection management |
| electron/crypto.js | Cryptographic functions for encryption, decryption, and password hashing |
| src/components/* | Complete React UI implementation with 6 main components using Ant Design |
| src/App.jsx | Main React application with authentication flow and theme configuration |
| vite.config.js | Vite build configuration for React and Tailwind CSS |
| Various removed files | Cleanup of legacy Python implementation files |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| */ | ||
| export function verifyPassword(password, hash, salt) { | ||
| const hashToVerify = hashPassword(password, salt); | ||
| return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(hashToVerify)); |
Copilot
AI
Oct 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The verifyPassword function assumes both hash and hashToVerify are hex strings when converting to buffers, but this could lead to timing attacks if the lengths differ. Consider using crypto.timingSafeEqual(Buffer.from(hash, 'hex'), Buffer.from(hashToVerify, 'hex')) to be explicit about encoding, or ensure both values are normalized to the same buffer length."
| return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(hashToVerify)); | |
| const hashBuffer = Buffer.from(hash, 'hex'); | |
| const hashToVerifyBuffer = Buffer.from(hashToVerify, 'hex'); | |
| if (hashBuffer.length !== hashToVerifyBuffer.length) { | |
| return false; | |
| } | |
| return crypto.timingSafeEqual(hashBuffer, hashToVerifyBuffer); |
| import prisma from './database.js'; | ||
| import { encrypt, decrypt, deriveKey, generateSalt, hashPassword, verifyPassword } from './crypto.js'; | ||
|
|
||
| let masterKey = null; |
Copilot
AI
Oct 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storing the master key in a global variable poses a security risk as it remains in memory throughout the application lifecycle. Consider implementing a more secure key management approach, such as clearing the key after a timeout period or using secure memory allocation techniques.
| // Set database URL to user data directory in production | ||
| const isDev = process.env.NODE_ENV !== 'production'; | ||
| const dbPath = isDev | ||
| ? path.join(__dirname, '../prisma/dev.db') |
Copilot
AI
Oct 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The development database path uses a relative path that could be vulnerable to path traversal attacks. Consider using an absolute path or additional validation to ensure the database is created in the intended location.
| ? path.join(__dirname, '../prisma/dev.db') | |
| ? path.resolve(__dirname, '../prisma/dev.db') |
| { required: true, message: 'Please enter your password' }, | ||
| !isSetup ? { min: 8, message: 'Password must be at least 8 characters' } : null, |
Copilot
AI
Oct 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The password minimum length validation is only applied when !isSetup is true, which means it's only enforced during the initial setup. This logic appears inverted - password length validation should apply during setup (when isSetup is false) but the condition checks !isSetup. This could allow weak passwords during login attempts.
| try { | ||
| if (!masterKey) { | ||
| return { success: false, error: 'Not authenticated' }; | ||
| } |
Copilot
AI
Oct 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The authentication check is repeated in multiple handlers (envvars:list, envvars:create, envvars:update, envvars:export). Consider extracting this into a reusable authentication middleware function to reduce code duplication and ensure consistent authentication behavior across all protected routes.
|
comply with the checks |
|
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation. |
Summary
Initialize the ENV_Storage project with Prisma ORM and SQLite database configuration for offline secrets management.
Changes
Technical Details
Testing
Next Steps