You are an expert full-stack developer and AI assistant tasked with building a single-page application (SPA) for managing SSH keys securely. This application, named 'SSH Anahtar Yöneticisi: Güvenli Erişim', aims to solve the problem of insecure and disorganized SSH key management faced by developers and system administrators. The core value proposition is to provide a centralized, encrypted, and user-friendly platform for storing, organizing, and accessing SSH keys and associated server connection details, thereby enhancing security and operational efficiency.
### 1. PROJECT OVERVIEW
The application 'SSH Anahtar Yöneticisi: Güvenli Erişim' is designed to address the common pain points of managing SSH private keys. Users often store these keys scattered across their local machines, in plain text files, or use insecure sharing methods. This poses significant security risks, including unauthorized access, data breaches, and compliance issues. Our application will offer a secure, cloud-based (or optionally local storage for advanced users) solution to store, categorize, and associate SSH keys with specific server connection details (hostname, port, username). The goal is to create a seamless and secure workflow for accessing remote servers.
### 2. TECH STACK
* **Frontend Framework:** React.js (using Create React App for simplicity or Next.js for potential SSR/SSG benefits if needed later, but for MVP, CRA is sufficient).
* **Styling:** Tailwind CSS for rapid UI development and consistent styling. Custom CSS modules for specific component styling if necessary.
* **State Management:** React Context API for global state and `useState`/`useReducer` hooks for local component state. For a more complex app, Zustand or Redux Toolkit could be considered later.
* **Routing:** React Router DOM for handling navigation within the SPA.
* **Form Handling:** React Hook Form for efficient and performant form management, including validation.
* **Cryptography (Client-side):** SubtleCrypto API (Web Crypto API) for encrypting/decrypting private keys before storing them in local storage or sending to a backend. Libraries like `crypto-js` can be used as a simpler alternative if Web Crypto API proves too complex for MVP. **Note:** For true security, server-side encryption and handling are crucial, but for an MVP focusing on client-side management and educational purposes, client-side encryption is a starting point. If a backend is introduced, encryption will be handled server-side.
* **Local Storage:** Browser's `localStorage` API for storing encrypted keys and user preferences. Sensitive data should be encrypted before storage.
* **UI Components:** Headless UI or similar accessible component library can be integrated if needed, but primarily using Tailwind CSS for styling.
* **Icons:** React Icons library for a variety of SVG icons.
### 3. CORE FEATURES (MVP)
**a. Secure SSH Key Storage:**
* **User Flow:** User navigates to the 'Keys' section. Clicks 'Add New Key'. Is prompted to paste their private SSH key content and optionally a passphrase. The application encrypts the private key using a user-defined or derived key (e.g., from a master password) and stores it in `localStorage`. The public key is extracted and displayed.
* **Details:** Private keys must be encrypted before storage. The UI should warn users about the security implications of not using a strong passphrase or master password.
**b. Key Organization (Tagging & Grouping):**
* **User Flow:** When adding or editing a key, the user can assign tags (e.g., 'production', 'staging', 'client-project-x'). Users can also filter and sort keys by these tags.
* **Details:** Tags are simple strings. The grouping logic will be based on these tags.
**c. Server Connection Mapping:**
* **User Flow:** User navigates to 'Servers' or 'Connections'. Clicks 'Add New Connection'. Enters hostname, port (defaults to 22), username, and selects/associates one or more stored SSH keys from their library. A description field can be added for context.
* **Details:** This feature links stored keys to specific server access configurations. The association is stored locally.
**d. Key Management (Add/Delete/Download):**
* **User Flow:** Within the 'Keys' list, each key has options to delete it, view its details (public key, associated servers), or download the encrypted private key file (e.g., `id_rsa.enc`). An 'Add Key' button is prominent on the page.
* **Details:** Downloaded keys would require the decryption mechanism (using the passphrase/master password) to be usable locally.
**e. User Authentication & Basic Security:**
* **User Flow:** Upon first visit, the user is prompted to set a master password. This password is used to encrypt/decrypt all keys stored locally. Subsequent visits require this master password to access keys.
* **Details:** Implements a simple login/logout flow based on the master password. This password is not stored directly but used to derive an encryption key.
### 4. UI/UX DESIGN
* **Layout:** A clean, single-page application layout. A persistent sidebar navigation (for Keys, Servers, Settings) and a main content area. A top header bar for the app title and user status/logout.
* **Color Palette:** Primary: Dark Blue (`#1a202c` - dark background). Secondary: Teal (`#38b2ac` - active states, buttons). Accent: Light Gray (`#e2e8f0` - text, borders). Warning/Error: Red (`#f56565`).
* **Typography:** Sans-serif font like Inter or Poppins for readability. Use Tailwind's default scale.
* **Responsive Design:** Mobile-first approach. Sidebar collapses into a hamburger menu on smaller screens. Content adjusts fluidly. Ensure usability on various screen sizes (320px to 1920px+).
* **Key Components:**
* `Sidebar`: Navigation links.
* `Header`: App title, user info.
* `KeyList`: Displays table/list of keys.
* `KeyItem`: Individual key row with actions.
* `AddKeyForm`: Modal/form for adding new keys.
* `ServerList`: Displays table/list of server connections.
* `ServerItem`: Individual server row.
* `AddServerForm`: Modal/form for adding connections.
* `LoginForm`: For master password entry.
* `TagInput`: Component for adding/managing tags.
### 5. DATA MODEL (Local Storage Structure)
```json
{
"user": {
"masterPasswordHash": "encrypted_hash_of_master_password_or_derived_key",
"isLoggedIn": false
},
"keys": [
{
"id": "uuid_1",
"name": "Work Laptop Key", // User-defined name
"publicKey": "ssh-rsa AAAAB3NzaC1yc2E...",
"encryptedPrivateKey": "encrypted_base64_string...", // Encrypted using master password derived key
"tags": ["work", "personal"],
"createdAt": "2023-10-27T10:00:00Z",
"updatedAt": "2023-10-27T10:00:00Z"
}
// ... more keys
],
"servers": [
{
"id": "uuid_2",
"name": "Production Server Alpha",
"hostname": "alpha.example.com",
"port": 22,
"username": "admin",
"associatedKeyIds": ["uuid_1", "uuid_3"],
"description": "Main production server",
"createdAt": "2023-10-27T11:00:00Z"
}
// ... more servers
]
}
```
**Encryption/Decryption Logic:**
* When setting the master password: Derive an encryption key (e.g., using PBKDF2) from the master password and a salt (stored separately or generated). Use this key with AES-GCM for encryption/decryption of `privateKey`.
* Accessing Keys: Prompt for master password -> Derive key -> Decrypt `encryptedPrivateKey` -> Use key.
* Storing Keys: Encrypt `privateKey` using derived key -> Store `encryptedPrivateKey`.
### 6. COMPONENT BREAKDOWN
* **`App.js`**: Main application component. Sets up routing, global context providers.
* Props: None
* Responsibilities: Root component, routing setup.
* **`Layout.js`**: Contains the overall page structure (Header, Sidebar, Main Content).
* Props: `children`
* Responsibilities: Structural layout, responsiveness.
* **`Header.js`**: Displays the application title and potentially user status.
* Props: `user` (object)
* Responsibilities: Branding, global status display.
* **`Sidebar.js`**: Navigation menu.
* Props: `links` (array of objects), `onNavigate` (function)
* Responsibilities: Navigation control.
* **`HomePage.js`**: Dashboard or landing page (can be a welcome message for MVP).
* Props: None
* Responsibilities: Entry point content.
* **`KeyManager.js`**: Container for KeyList and AddKeyForm.
* Props: `keys` (array), `servers` (array)
* Responsibilities: Manages key data fetching/state, rendering KeyList and AddKeyForm.
* **`KeyList.js`**: Renders a list or table of SSH keys.
* Props: `keys` (array), `onDeleteKey` (function), `onEditKey` (function), `onAssociateServer` (function)
* Responsibilities: Displays key data, provides actions per key.
* **`KeyItem.js`**: Represents a single row/item in the KeyList.
* Props: `key` (object), `actions` (object: onDelete, onEdit, etc.)
* Responsibilities: Renders single key details and action buttons.
* **`AddEditKeyForm.js`**: Form for adding or editing an SSH key (likely in a modal).
* Props: `onSubmit` (function), `initialData` (object, for editing), `onClose` (function)
* Responsibilities: Handles user input for key details, including pasting the private key.
* **`ServerManager.js`**: Container for ServerList and AddServerForm.
* Props: `servers` (array), `keys` (array)
* Responsibilities: Manages server data, renders ServerList and AddServerForm.
* **`ServerList.js`**: Renders a list or table of server connections.
* Props: `servers` (array), `keys` (array), `onDeleteServer` (function), `onEditServer` (function)
* Responsibilities: Displays server connection details.
* **`ServerItem.js`**: Represents a single row/item in the ServerList.
* Props: `server` (object), `associatedKeys` (array), `actions` (object)
* Responsibilities: Renders single server details.
* **`AddEditServerForm.js`**: Form for adding or editing a server connection (modal).
* Props: `onSubmit`, `initialData`, `onClose`, `availableKeys` (array)
* Responsibilities: Handles user input for server details and key association.
* **`LoginForm.js`**: Modal for entering the master password.
* Props: `onSubmit` (function), `onClose` (function)
* Responsibilities: Securely captures master password.
* **`TagInput.js`**: Component for managing tags within forms.
* Props: `tags` (array), `onChange` (function)
* Responsibilities: Allows users to add, remove, and view tags.
### 7. ANIMATIONS & INTERACTIONS
* **Page Transitions:** Subtle fade-in/fade-out transitions between routes using `react-transition-group` or similar.
* **Button Hovers:** Slight scale-up or color change on button hovers using Tailwind's `hover:` variants.
* **Form Element Interactions:** Focus states on input fields using Tailwind's `focus:` variants.
* **Loading States:** Show spinners or skeleton loaders when fetching or processing data (e.g., during key encryption/decryption, though this should be fast client-side). Display a "Processing..." message for potentially longer operations.
* **Modal Transitions:** Smooth slide-in/fade-in animations for modals (Add Key/Server forms, Login).
* **Micro-interactions:** Visual feedback on successful key addition/deletion (e.g., a temporary toast notification).
### 8. EDGE CASES & ERROR HANDLING
* **No Keys/Servers:** Display friendly messages like "You haven't added any SSH keys yet. Click 'Add Key' to start." with a clear call to action.
* **Invalid Key Format:** When adding a key, perform basic validation to check if the pasted text resembles an SSH private key format (e.g., starts with `-----BEGIN`). Provide clear error messages.
* **Incorrect Master Password:** Handle incorrect master password attempts gracefully. Limit attempts or display clear error messages without revealing too much information. Prevent brute-force attacks (rate limiting might be considered for a backend version).
* **Local Storage Full:** Handle potential `QuotaExceededError` if `localStorage` is full. Inform the user.
* **Encryption/Decryption Errors:** Catch errors during crypto operations and display user-friendly messages. For example, if decryption fails with the wrong password.
* **Accessibility (a11y):** Ensure all interactive elements are keyboard-navigable. Use semantic HTML. Provide ARIA attributes where necessary. Ensure sufficient color contrast. Use accessible modal/form components.
* **Data Corruption:** Implement checks for data integrity in `localStorage` if possible (e.g., checksums, though complex for MVP).
### 9. SAMPLE DATA (Mock Data for `localStorage`)
```json
{
"user": {
"masterPasswordHash": "dummy_hash_for_demo",
"isLoggedIn": true
},
"keys": [
{
"id": "key_001",
"name": "Personal Server Key",
"publicKey": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3... user@personal-machine",
"encryptedPrivateKey": "U2FsdGVkX1+exampleEncryptedData123...",
"tags": ["personal", "test"],
"createdAt": "2023-10-26T14:30:00Z",
"updatedAt": "2023-10-26T14:35:00Z"
},
{
"id": "key_002",
"name": "Work Staging Key",
"publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... admin@work-staging",
"encryptedPrivateKey": "U2FsdGVkX1+anotherEncryptedData456...",
"tags": ["work", "staging"],
"createdAt": "2023-10-27T09:15:00Z",
"updatedAt": "2023-10-27T09:15:00Z"
}
],
"servers": [
{
"id": "srv_001",
"name": "Dev Environment",
"hostname": "dev.example.com",
"port": 2222,
"username": "developer",
"associatedKeyIds": ["key_001"],
"description": "Development server environment.",
"createdAt": "2023-10-26T15:00:00Z"
},
{
"id": "srv_002",
"name": "Staging Server",
"hostname": "staging.example.com",
"port": 22,
"username": "deployer",
"associatedKeyIds": ["key_002"],
"description": "Production-like staging environment.",
"createdAt": "2023-10-27T09:30:00Z"
}
]
}
```
### 10. DEPLOYMENT NOTES
* **Build:** Use `npm run build` or `yarn build`. The output will be in the `build/` directory.
* **Environment Variables:** For MVP using `localStorage`, no specific environment variables are strictly needed. If transitioning to a backend, `REACT_APP_API_URL` would be essential.
* **Hosting:** Can be hosted statically on platforms like Netlify, Vercel, GitHub Pages.
* **Performance:** Ensure efficient state updates. Use `React.memo` or `useCallback` where necessary. Optimize bundle size using code splitting if the app grows.
* **Security Considerations (MVP):** Emphasize that `localStorage` is not inherently secure. The primary security comes from client-side encryption using the master password. Advise users against storing highly sensitive production keys without a robust backend solution. The master password itself should ideally be used to derive a key, and that derived key used for AES encryption, rather than encrypting directly with the password.
* **Future Enhancements:** Consider backend synchronization, team collaboration features, SSH agent forwarding integration, audit logs, and support for different key types.
This prompt provides a comprehensive guide for an AI to generate the 'SSH Anahtar Yöneticisi: Güvenli Erişim' application as a functional SPA.