├── .env ├── .eslintrc.cjs ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── greetings.yml │ └── pr-checker.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── backend ├── .gitignore ├── package-lock.json ├── package.json └── server.js ├── generate-sitemap.js ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.png ├── icons │ ├── eye.png │ ├── eyecross.png │ ├── github.png │ └── heart.png ├── robots.txt ├── sitemap.xml └── vite.svg ├── src ├── App.css ├── App.jsx ├── assets │ └── react.svg ├── atoms │ └── authState.js ├── browser-extension │ ├── background.js │ ├── content.js │ ├── manifest.json │ ├── popup.html │ └── popup.js ├── components │ ├── Footer.jsx │ ├── Manager.jsx │ ├── Navbar.jsx │ ├── SignIn.jsx │ ├── SignUp.jsx │ ├── UserAccount.jsx │ └── variables.json ├── contexts │ └── authContext │ │ └── index.jsx ├── firebase │ ├── auth.js │ └── firebase.js ├── index.css ├── main.jsx └── metadata.jsx ├── tailwind.config.js └── vite.config.js /.env: -------------------------------------------------------------------------------- 1 | MONGO_URI = mongodb://localhost:27017 2 | DB_NAME = passop 3 | # Encryption and Decryption keys 4 | # Must be 256 bits (32 bytes) 5 | ENCRYPTION_KEY = thisisaverysecureencryptionkey!! 6 | 7 | # for firebase auth configuration 8 | VITE_FIREBASE_API_KEY=YOUR_API_KEY 9 | VITE_FIREBASE_AUTH_DOMAIN=YOUR_AUTH_DOMAIN 10 | VITE_FIREBASE_PROJECT_ID=PROJECT_ID 11 | VITE_FIREBASE_STORAGE_BUCKET=SOCKET_BUTTON 12 | VITE_FIREBASE_MESSAGING_SENDER_ID=SENDER_ID 13 | VITE_FIREBASE_APP_ID=APP_ID 14 | VITE_FIREBASE_MEASUREMENT_ID=MEASUREMENT_ID -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react/jsx-no-target-blank': 'off', 16 | 'react-refresh/only-export-components': [ 17 | 'warn', 18 | { allowConstantExport: true }, 19 | ], 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened, synchronized, reopened] 6 | issues: 7 | types: [opened, closed] 8 | 9 | jobs: 10 | greeting: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | issues: write 14 | pull-requests: write 15 | steps: 16 | # Greet on new issue 17 | - name: Greet on new issue 18 | if: github.event_name == 'issues' && github.event.action == 'opened' 19 | uses: actions/first-interaction@v1 20 | with: 21 | issue-message: "Thank you @${{ github.actor }} for raising an issue! We appreciate your effort in helping us improve. Our team will review it shortly. Stay tuned!" 22 | 23 | # Greet on new pull request 24 | - name: Greet on new pull request 25 | if: github.event_name == 'pull_request_target' && github.event.action == 'opened' 26 | uses: actions/first-interaction@v1 27 | with: 28 | pr-message: "Thank you @${{ github.actor }} for your contribution! Your pull request has been submitted successfully. A maintainer will review it as soon as possible. We appreciate your support in making this project better." 29 | 30 | # Congratulate on closed issue 31 | # - name: Congratulate on closed issue 32 | # if: github.event_name == 'issues' && github.event.action == 'closed' 33 | # run: | 34 | # echo "Congratulations to @${{ github.event.issue.user.login }} for closing your issue!" 35 | # echo "If you enjoyed contributing, please consider giving us a ⭐ and following us for updates!" 36 | # # Post a comment on the issue 37 | # curl -X POST \ 38 | # -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 39 | # -H "Accept: application/vnd.github.v3+json" \ 40 | # https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments \ 41 | # -d "{\"body\": \"Congratulations to @${{ github.event.issue.user.login }} for closing your issue! If you enjoyed contributing, please consider giving us a ⭐ on GitHub and following us for updates!\"}" 42 | -------------------------------------------------------------------------------- /.github/workflows/pr-checker.yml: -------------------------------------------------------------------------------- 1 | name: PR Issue Checker 2 | # Created by @smog-root. 3 | on: 4 | pull_request: 5 | types: [opened, edited] 6 | 7 | jobs: 8 | check_pr_description: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v2 14 | 15 | - name: Check PR Description 16 | id: check_pr_description 17 | run: | 18 | PR_DESCRIPTION="${{ github.event.pull_request.body }}" 19 | 20 | # Check if PR description is empty 21 | if [[ -z "$PR_DESCRIPTION" ]]; then 22 | echo "##[error]PR description is missing." 23 | exit 1 24 | fi 25 | 26 | # Check if PR description includes 'Fixes #' 27 | if [[ ! "$PR_DESCRIPTION" =~ Fixes\ #[0-9]+ ]]; then 28 | echo "##[error]The PR description should include 'Fixes #' if addressing an issue." 29 | exit 1 30 | fi 31 | 32 | echo "PR description is valid." 33 | 34 | - name: Output result 35 | if: success() 36 | run: echo "All checks passed." 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We, as members, contributors, and leaders, pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 8 | 9 | ## Our Standards 10 | 11 | Examples of behavior that contributes to a positive environment for our community include: 12 | 13 | - Demonstrating empathy and kindness toward other people 14 | - Being respectful of differing opinions, viewpoints, and experiences 15 | - Giving and gracefully accepting constructive feedback 16 | - Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience 17 | - Focusing on what is best not just for us as individuals, but for the overall community 18 | 19 | Examples of unacceptable behavior include: 20 | 21 | - The use of sexualized language or imagery, and sexual attention or advances of any kind 22 | - Trolling, insulting or derogatory comments, and personal or political attacks 23 | - Public or private harassment 24 | - Publishing others’ private information, such as a physical or email address, without their explicit permission 25 | - Other conduct which could reasonably be considered inappropriate in a professional setting 26 | 27 | ## Enforcement Responsibilities 28 | 29 | Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. 32 | 33 | ## Scope 34 | 35 | This Code of Conduct applies within all community spaces, and it also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 36 | 37 | ## Enforcement 38 | 39 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [email@example.com]. All complaints will be reviewed and investigated promptly and fairly. 40 | 41 | All community leaders are obligated to respect the privacy and security of the reporter of any incident. 42 | 43 | ## Enforcement Guidelines 44 | 45 | Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: 46 | 47 | 1. **Correction** 48 | Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. 49 | Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. 50 | 51 | 2. **Warning** 52 | Community Impact: A violation through a single incident or series of actions. 53 | Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. 54 | 55 | 3. **Temporary Ban** 56 | Community Impact: A serious violation of community standards, including sustained inappropriate behavior. 57 | Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. 58 | 59 | 4. **Permanent Ban** 60 | Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. 61 | Consequence: A permanent ban from any sort of public interaction within the community. 62 | 63 | ## Attribution 64 | 65 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. 66 | 67 | For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq. 68 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to PassOP 2 | 3 | We welcome contributions from the community! Follow these steps to contribute to the project: 4 | 5 | 1. **Fork the Repository** 6 | Click the "Fork" button at the top of this repository. 7 | 8 | 2. **Clone Your Fork** 9 | Clone the forked repository to your local machine: 10 | 11 | ```bash 12 | git clone https://github.com//PassOP.git 13 | cd PassOP 14 | ``` 15 | 16 | 3. **Create a New Branch** 17 | Create a new branch for your feature or bug fix: 18 | 19 | ```bash 20 | git checkout -b feature/new-feature 21 | ``` 22 | 23 | 4. **Make Your Changes** 24 | Implement your changes, and make sure to test them. 25 | 26 | 5. **Commit and Push Your Changes** 27 | 28 | ```bash 29 | git add . 30 | git commit -m "Add new feature or fix" 31 | git push origin feature/new-feature 32 | ``` 33 | 34 | 6. **Submit a Pull Request** 35 | Go to the original repository on GitHub, and click the "New Pull Request" button. -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Node runtime as the base image 2 | FROM node:20-alpine 3 | 4 | # Set the working directory in the container 5 | WORKDIR /app 6 | 7 | # Copy package.json and package-lock.json (if available) 8 | COPY package*.json ./ 9 | 10 | # Install all dependencies including 'devDependencies' 11 | RUN npm install 12 | 13 | # Copy the rest of the application code 14 | COPY . . 15 | 16 | # Build the app 17 | RUN npm run build 18 | 19 | # Install a simple server to serve static content 20 | RUN npm install -g serve 21 | 22 | # Expose the port the app runs on 23 | EXPOSE 3000 24 | 25 | # Serve the app 26 | CMD ["serve", "-s", "dist", "-l", "3000"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Adarsh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | #

🔑 PassOP: Your Password Manager 🚀

4 |

5 | 6 |

7 | 8 |
9 | 10 |

Hi there, Secure your online life with PassOP!

11 | 12 |

13 | 14 |

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
🌟 Stars🍴 Forks🐛 Issues🔔 Open PRs🔕 Close PRs
StarsForksIssuesOpen Pull RequestsClose Pull Requests
35 | 36 | ## Overview 📌 37 |
    38 |
  • 🔒 **PassOP** is a simple and secure password manager built with React that allows users to save, view, edit, and delete their passwords.
  • 39 |
  • 💡 It helps you manage your passwords efficiently and securely using modern encryption techniques.
  • 40 |
41 | 42 |

Features

43 |
    44 |
  • 💾 Add Password: Save a new password with a website URL, username, and password.
  • 45 |
  • 📝 Edit Password: Update an existing password easily.
  • 46 |
  • Delete Password: Remove any saved password you no longer need.
  • 47 |
  • 📋 Copy to Clipboard: Quickly copy website URLs, usernames, and passwords to your clipboard.
  • 48 |
  • 👁️ Show/Hide Password: Toggle visibility of passwords for added convenience.
  • 49 |
50 | 51 | ## Open-Source-Programmes 🤝 52 | 53 | ### This project is now OFFICIALLY accepted for 54 |
GSSOC
55 |
HACTOBERFEST
56 | 57 |

58 | 59 |

60 | 61 |

Back To Top

62 | 63 | ## Getting Started 🚀 64 | 65 | ### Prerequisites 66 | Ensure you have the following installed: 67 | - [Node.js](https://nodejs.org/) (version 14.x or higher) 68 | - [npm](https://www.npmjs.com/) (Node package manager) 69 | - [Vite](https://vitejs.dev/) (for running the React front-end) 70 | - [MongoDB](https://www.mongodb.com/) (local or cloud instance) 71 | 72 | ### Installation 73 | 74 | #### 1. Clone the Repository: 75 | 76 | ```bash 77 | git clone https://github.com//PassOP.git 78 | cd PassOP 79 | ``` 80 | 81 | #### 2. Setting Up the Backend: 82 | 83 | - Navigate to the backend folder: 84 | 85 | ```bash 86 | cd backend 87 | ``` 88 | 89 | - Install the required dependencies: 90 | 91 | ```bash 92 | npm install 93 | ``` 94 | 95 | - Set up your environment variables. Create or edit the `.env` file in the backend folder with the following: 96 | ```env 97 | MONGO_URI= 98 | DB_NAME= 99 | ``` 100 | - Run the backend server: 101 | 102 | ```bash 103 | node server.js 104 | ``` 105 | 106 | #### 3. Setting Up the Frontend: 107 | 108 | - Move back to the root directory: 109 | 110 | ```bash 111 | cd .. 112 | ``` 113 | 114 | - Install the front-end dependencies: 115 | 116 | ```bash 117 | npm install 118 | ``` 119 | 120 | - Run the React application using Vite: 121 | 122 | ```bash 123 | npm run dev 124 | ``` 125 | 126 | #### 4. Access the Application: 127 | 128 | - Open your browser and go to: 129 | [http://localhost:3000](http://localhost:3000) 130 | 131 | Now your password manager should be running locally! 132 | 133 | ## Folder Structure 📂 134 | 135 | ``` 136 | PassOP/ 137 | ├── backend/ # Backend Node.js application 138 | │ ├── server.js # Main server file 139 | │ ├── .env # Environment configuration (not included in repo) 140 | │ ├── package.json # Backend dependencies 141 | │ └── ... # Other backend files 142 | ├── frontend/ # React frontend application (using Vite) 143 | │ ├── src/ # React components and files 144 | │ ├── public/ # Public static files 145 | │ ├── package.json # Frontend dependencies 146 | │ └── vite.config.js # Vite configuration file 147 | ├── README.md # This file 148 | └── ... 149 | ``` 150 | 151 | ## Contributing ⭐ 152 | 153 | We welcome all contributions! Read our [CONTRIBUTING.md](./CONTRIBUTING.md) to get started building! 🛠️ 154 | 155 | ## Code of Conduct 📜 156 | 157 | Please make sure to review and follow the project's [Code of Conduct](./CODE_OF_CONDUCT.md) when contributing. 158 | 159 |
160 | 161 | ## Project Admin ⚡ 162 | 163 | 164 | 168 | 169 |
165 | 166 |

Adarsh

167 |
170 | 171 |

Contributors

172 | 173 | Big thanks to all the contributors who have helped make Passop a better platform! 🎉 174 | 175 | 176 | 177 |

Back To Top

178 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /backend/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "backend", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "backend": "file:", 13 | "body-parser": "^1.20.2", 14 | "cors": "^2.8.5", 15 | "crypto": "^1.0.1", 16 | "dotenv": "^16.4.5", 17 | "express": "^4.18.3", 18 | "mongodb": "^6.4.0" 19 | } 20 | }, 21 | "node_modules/@mongodb-js/saslprep": { 22 | "version": "1.1.7", 23 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz", 24 | "integrity": "sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==", 25 | "dependencies": { 26 | "sparse-bitfield": "^3.0.3" 27 | } 28 | }, 29 | "node_modules/@types/webidl-conversions": { 30 | "version": "7.0.3", 31 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", 32 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" 33 | }, 34 | "node_modules/@types/whatwg-url": { 35 | "version": "11.0.5", 36 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", 37 | "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", 38 | "dependencies": { 39 | "@types/webidl-conversions": "*" 40 | } 41 | }, 42 | "node_modules/accepts": { 43 | "version": "1.3.8", 44 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 45 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 46 | "dependencies": { 47 | "mime-types": "~2.1.34", 48 | "negotiator": "0.6.3" 49 | }, 50 | "engines": { 51 | "node": ">= 0.6" 52 | } 53 | }, 54 | "node_modules/array-flatten": { 55 | "version": "1.1.1", 56 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 57 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 58 | }, 59 | "node_modules/backend": { 60 | "resolved": "", 61 | "link": true 62 | }, 63 | "node_modules/body-parser": { 64 | "version": "1.20.2", 65 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", 66 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", 67 | "dependencies": { 68 | "bytes": "3.1.2", 69 | "content-type": "~1.0.5", 70 | "debug": "2.6.9", 71 | "depd": "2.0.0", 72 | "destroy": "1.2.0", 73 | "http-errors": "2.0.0", 74 | "iconv-lite": "0.4.24", 75 | "on-finished": "2.4.1", 76 | "qs": "6.11.0", 77 | "raw-body": "2.5.2", 78 | "type-is": "~1.6.18", 79 | "unpipe": "1.0.0" 80 | }, 81 | "engines": { 82 | "node": ">= 0.8", 83 | "npm": "1.2.8000 || >= 1.4.16" 84 | } 85 | }, 86 | "node_modules/bson": { 87 | "version": "6.7.0", 88 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.7.0.tgz", 89 | "integrity": "sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==", 90 | "engines": { 91 | "node": ">=16.20.1" 92 | } 93 | }, 94 | "node_modules/bytes": { 95 | "version": "3.1.2", 96 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 97 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 98 | "engines": { 99 | "node": ">= 0.8" 100 | } 101 | }, 102 | "node_modules/call-bind": { 103 | "version": "1.0.7", 104 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", 105 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", 106 | "dependencies": { 107 | "es-define-property": "^1.0.0", 108 | "es-errors": "^1.3.0", 109 | "function-bind": "^1.1.2", 110 | "get-intrinsic": "^1.2.4", 111 | "set-function-length": "^1.2.1" 112 | }, 113 | "engines": { 114 | "node": ">= 0.4" 115 | }, 116 | "funding": { 117 | "url": "https://github.com/sponsors/ljharb" 118 | } 119 | }, 120 | "node_modules/content-disposition": { 121 | "version": "0.5.4", 122 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 123 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 124 | "dependencies": { 125 | "safe-buffer": "5.2.1" 126 | }, 127 | "engines": { 128 | "node": ">= 0.6" 129 | } 130 | }, 131 | "node_modules/content-type": { 132 | "version": "1.0.5", 133 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 134 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 135 | "engines": { 136 | "node": ">= 0.6" 137 | } 138 | }, 139 | "node_modules/cookie": { 140 | "version": "0.6.0", 141 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", 142 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", 143 | "engines": { 144 | "node": ">= 0.6" 145 | } 146 | }, 147 | "node_modules/cookie-signature": { 148 | "version": "1.0.6", 149 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 150 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 151 | }, 152 | "node_modules/cors": { 153 | "version": "2.8.5", 154 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 155 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 156 | "dependencies": { 157 | "object-assign": "^4", 158 | "vary": "^1" 159 | }, 160 | "engines": { 161 | "node": ">= 0.10" 162 | } 163 | }, 164 | "node_modules/crypto": { 165 | "version": "1.0.1", 166 | "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", 167 | "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", 168 | "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.", 169 | "license": "ISC" 170 | }, 171 | "node_modules/debug": { 172 | "version": "2.6.9", 173 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 174 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 175 | "dependencies": { 176 | "ms": "2.0.0" 177 | } 178 | }, 179 | "node_modules/define-data-property": { 180 | "version": "1.1.4", 181 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 182 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 183 | "dependencies": { 184 | "es-define-property": "^1.0.0", 185 | "es-errors": "^1.3.0", 186 | "gopd": "^1.0.1" 187 | }, 188 | "engines": { 189 | "node": ">= 0.4" 190 | }, 191 | "funding": { 192 | "url": "https://github.com/sponsors/ljharb" 193 | } 194 | }, 195 | "node_modules/depd": { 196 | "version": "2.0.0", 197 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 198 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 199 | "engines": { 200 | "node": ">= 0.8" 201 | } 202 | }, 203 | "node_modules/destroy": { 204 | "version": "1.2.0", 205 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 206 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 207 | "engines": { 208 | "node": ">= 0.8", 209 | "npm": "1.2.8000 || >= 1.4.16" 210 | } 211 | }, 212 | "node_modules/dotenv": { 213 | "version": "16.4.5", 214 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", 215 | "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", 216 | "engines": { 217 | "node": ">=12" 218 | }, 219 | "funding": { 220 | "url": "https://dotenvx.com" 221 | } 222 | }, 223 | "node_modules/ee-first": { 224 | "version": "1.1.1", 225 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 226 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 227 | }, 228 | "node_modules/encodeurl": { 229 | "version": "1.0.2", 230 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 231 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 232 | "engines": { 233 | "node": ">= 0.8" 234 | } 235 | }, 236 | "node_modules/es-define-property": { 237 | "version": "1.0.0", 238 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", 239 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", 240 | "dependencies": { 241 | "get-intrinsic": "^1.2.4" 242 | }, 243 | "engines": { 244 | "node": ">= 0.4" 245 | } 246 | }, 247 | "node_modules/es-errors": { 248 | "version": "1.3.0", 249 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 250 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 251 | "engines": { 252 | "node": ">= 0.4" 253 | } 254 | }, 255 | "node_modules/escape-html": { 256 | "version": "1.0.3", 257 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 258 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 259 | }, 260 | "node_modules/etag": { 261 | "version": "1.8.1", 262 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 263 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 264 | "engines": { 265 | "node": ">= 0.6" 266 | } 267 | }, 268 | "node_modules/express": { 269 | "version": "4.19.2", 270 | "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", 271 | "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", 272 | "dependencies": { 273 | "accepts": "~1.3.8", 274 | "array-flatten": "1.1.1", 275 | "body-parser": "1.20.2", 276 | "content-disposition": "0.5.4", 277 | "content-type": "~1.0.4", 278 | "cookie": "0.6.0", 279 | "cookie-signature": "1.0.6", 280 | "debug": "2.6.9", 281 | "depd": "2.0.0", 282 | "encodeurl": "~1.0.2", 283 | "escape-html": "~1.0.3", 284 | "etag": "~1.8.1", 285 | "finalhandler": "1.2.0", 286 | "fresh": "0.5.2", 287 | "http-errors": "2.0.0", 288 | "merge-descriptors": "1.0.1", 289 | "methods": "~1.1.2", 290 | "on-finished": "2.4.1", 291 | "parseurl": "~1.3.3", 292 | "path-to-regexp": "0.1.7", 293 | "proxy-addr": "~2.0.7", 294 | "qs": "6.11.0", 295 | "range-parser": "~1.2.1", 296 | "safe-buffer": "5.2.1", 297 | "send": "0.18.0", 298 | "serve-static": "1.15.0", 299 | "setprototypeof": "1.2.0", 300 | "statuses": "2.0.1", 301 | "type-is": "~1.6.18", 302 | "utils-merge": "1.0.1", 303 | "vary": "~1.1.2" 304 | }, 305 | "engines": { 306 | "node": ">= 0.10.0" 307 | } 308 | }, 309 | "node_modules/finalhandler": { 310 | "version": "1.2.0", 311 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 312 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 313 | "dependencies": { 314 | "debug": "2.6.9", 315 | "encodeurl": "~1.0.2", 316 | "escape-html": "~1.0.3", 317 | "on-finished": "2.4.1", 318 | "parseurl": "~1.3.3", 319 | "statuses": "2.0.1", 320 | "unpipe": "~1.0.0" 321 | }, 322 | "engines": { 323 | "node": ">= 0.8" 324 | } 325 | }, 326 | "node_modules/forwarded": { 327 | "version": "0.2.0", 328 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 329 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 330 | "engines": { 331 | "node": ">= 0.6" 332 | } 333 | }, 334 | "node_modules/fresh": { 335 | "version": "0.5.2", 336 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 337 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 338 | "engines": { 339 | "node": ">= 0.6" 340 | } 341 | }, 342 | "node_modules/function-bind": { 343 | "version": "1.1.2", 344 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 345 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 346 | "funding": { 347 | "url": "https://github.com/sponsors/ljharb" 348 | } 349 | }, 350 | "node_modules/get-intrinsic": { 351 | "version": "1.2.4", 352 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", 353 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", 354 | "dependencies": { 355 | "es-errors": "^1.3.0", 356 | "function-bind": "^1.1.2", 357 | "has-proto": "^1.0.1", 358 | "has-symbols": "^1.0.3", 359 | "hasown": "^2.0.0" 360 | }, 361 | "engines": { 362 | "node": ">= 0.4" 363 | }, 364 | "funding": { 365 | "url": "https://github.com/sponsors/ljharb" 366 | } 367 | }, 368 | "node_modules/gopd": { 369 | "version": "1.0.1", 370 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 371 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 372 | "dependencies": { 373 | "get-intrinsic": "^1.1.3" 374 | }, 375 | "funding": { 376 | "url": "https://github.com/sponsors/ljharb" 377 | } 378 | }, 379 | "node_modules/has-property-descriptors": { 380 | "version": "1.0.2", 381 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 382 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 383 | "dependencies": { 384 | "es-define-property": "^1.0.0" 385 | }, 386 | "funding": { 387 | "url": "https://github.com/sponsors/ljharb" 388 | } 389 | }, 390 | "node_modules/has-proto": { 391 | "version": "1.0.3", 392 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", 393 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", 394 | "engines": { 395 | "node": ">= 0.4" 396 | }, 397 | "funding": { 398 | "url": "https://github.com/sponsors/ljharb" 399 | } 400 | }, 401 | "node_modules/has-symbols": { 402 | "version": "1.0.3", 403 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 404 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 405 | "engines": { 406 | "node": ">= 0.4" 407 | }, 408 | "funding": { 409 | "url": "https://github.com/sponsors/ljharb" 410 | } 411 | }, 412 | "node_modules/hasown": { 413 | "version": "2.0.2", 414 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 415 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 416 | "dependencies": { 417 | "function-bind": "^1.1.2" 418 | }, 419 | "engines": { 420 | "node": ">= 0.4" 421 | } 422 | }, 423 | "node_modules/http-errors": { 424 | "version": "2.0.0", 425 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 426 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 427 | "dependencies": { 428 | "depd": "2.0.0", 429 | "inherits": "2.0.4", 430 | "setprototypeof": "1.2.0", 431 | "statuses": "2.0.1", 432 | "toidentifier": "1.0.1" 433 | }, 434 | "engines": { 435 | "node": ">= 0.8" 436 | } 437 | }, 438 | "node_modules/iconv-lite": { 439 | "version": "0.4.24", 440 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 441 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 442 | "dependencies": { 443 | "safer-buffer": ">= 2.1.2 < 3" 444 | }, 445 | "engines": { 446 | "node": ">=0.10.0" 447 | } 448 | }, 449 | "node_modules/inherits": { 450 | "version": "2.0.4", 451 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 452 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 453 | }, 454 | "node_modules/ipaddr.js": { 455 | "version": "1.9.1", 456 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 457 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 458 | "engines": { 459 | "node": ">= 0.10" 460 | } 461 | }, 462 | "node_modules/media-typer": { 463 | "version": "0.3.0", 464 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 465 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 466 | "engines": { 467 | "node": ">= 0.6" 468 | } 469 | }, 470 | "node_modules/memory-pager": { 471 | "version": "1.5.0", 472 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 473 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" 474 | }, 475 | "node_modules/merge-descriptors": { 476 | "version": "1.0.1", 477 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 478 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 479 | }, 480 | "node_modules/methods": { 481 | "version": "1.1.2", 482 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 483 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 484 | "engines": { 485 | "node": ">= 0.6" 486 | } 487 | }, 488 | "node_modules/mime": { 489 | "version": "1.6.0", 490 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 491 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 492 | "bin": { 493 | "mime": "cli.js" 494 | }, 495 | "engines": { 496 | "node": ">=4" 497 | } 498 | }, 499 | "node_modules/mime-db": { 500 | "version": "1.52.0", 501 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 502 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 503 | "engines": { 504 | "node": ">= 0.6" 505 | } 506 | }, 507 | "node_modules/mime-types": { 508 | "version": "2.1.35", 509 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 510 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 511 | "dependencies": { 512 | "mime-db": "1.52.0" 513 | }, 514 | "engines": { 515 | "node": ">= 0.6" 516 | } 517 | }, 518 | "node_modules/mongodb": { 519 | "version": "6.7.0", 520 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", 521 | "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==", 522 | "dependencies": { 523 | "@mongodb-js/saslprep": "^1.1.5", 524 | "bson": "^6.7.0", 525 | "mongodb-connection-string-url": "^3.0.0" 526 | }, 527 | "engines": { 528 | "node": ">=16.20.1" 529 | }, 530 | "peerDependencies": { 531 | "@aws-sdk/credential-providers": "^3.188.0", 532 | "@mongodb-js/zstd": "^1.1.0", 533 | "gcp-metadata": "^5.2.0", 534 | "kerberos": "^2.0.1", 535 | "mongodb-client-encryption": ">=6.0.0 <7", 536 | "snappy": "^7.2.2", 537 | "socks": "^2.7.1" 538 | }, 539 | "peerDependenciesMeta": { 540 | "@aws-sdk/credential-providers": { 541 | "optional": true 542 | }, 543 | "@mongodb-js/zstd": { 544 | "optional": true 545 | }, 546 | "gcp-metadata": { 547 | "optional": true 548 | }, 549 | "kerberos": { 550 | "optional": true 551 | }, 552 | "mongodb-client-encryption": { 553 | "optional": true 554 | }, 555 | "snappy": { 556 | "optional": true 557 | }, 558 | "socks": { 559 | "optional": true 560 | } 561 | } 562 | }, 563 | "node_modules/mongodb-connection-string-url": { 564 | "version": "3.0.1", 565 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", 566 | "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", 567 | "dependencies": { 568 | "@types/whatwg-url": "^11.0.2", 569 | "whatwg-url": "^13.0.0" 570 | } 571 | }, 572 | "node_modules/ms": { 573 | "version": "2.0.0", 574 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 575 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 576 | }, 577 | "node_modules/negotiator": { 578 | "version": "0.6.3", 579 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 580 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 581 | "engines": { 582 | "node": ">= 0.6" 583 | } 584 | }, 585 | "node_modules/object-assign": { 586 | "version": "4.1.1", 587 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 588 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 589 | "engines": { 590 | "node": ">=0.10.0" 591 | } 592 | }, 593 | "node_modules/object-inspect": { 594 | "version": "1.13.1", 595 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", 596 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", 597 | "funding": { 598 | "url": "https://github.com/sponsors/ljharb" 599 | } 600 | }, 601 | "node_modules/on-finished": { 602 | "version": "2.4.1", 603 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 604 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 605 | "dependencies": { 606 | "ee-first": "1.1.1" 607 | }, 608 | "engines": { 609 | "node": ">= 0.8" 610 | } 611 | }, 612 | "node_modules/parseurl": { 613 | "version": "1.3.3", 614 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 615 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 616 | "engines": { 617 | "node": ">= 0.8" 618 | } 619 | }, 620 | "node_modules/path-to-regexp": { 621 | "version": "0.1.7", 622 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 623 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 624 | }, 625 | "node_modules/proxy-addr": { 626 | "version": "2.0.7", 627 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 628 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 629 | "dependencies": { 630 | "forwarded": "0.2.0", 631 | "ipaddr.js": "1.9.1" 632 | }, 633 | "engines": { 634 | "node": ">= 0.10" 635 | } 636 | }, 637 | "node_modules/punycode": { 638 | "version": "2.3.1", 639 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 640 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 641 | "engines": { 642 | "node": ">=6" 643 | } 644 | }, 645 | "node_modules/qs": { 646 | "version": "6.11.0", 647 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 648 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 649 | "dependencies": { 650 | "side-channel": "^1.0.4" 651 | }, 652 | "engines": { 653 | "node": ">=0.6" 654 | }, 655 | "funding": { 656 | "url": "https://github.com/sponsors/ljharb" 657 | } 658 | }, 659 | "node_modules/range-parser": { 660 | "version": "1.2.1", 661 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 662 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 663 | "engines": { 664 | "node": ">= 0.6" 665 | } 666 | }, 667 | "node_modules/raw-body": { 668 | "version": "2.5.2", 669 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", 670 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 671 | "dependencies": { 672 | "bytes": "3.1.2", 673 | "http-errors": "2.0.0", 674 | "iconv-lite": "0.4.24", 675 | "unpipe": "1.0.0" 676 | }, 677 | "engines": { 678 | "node": ">= 0.8" 679 | } 680 | }, 681 | "node_modules/safe-buffer": { 682 | "version": "5.2.1", 683 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 684 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 685 | "funding": [ 686 | { 687 | "type": "github", 688 | "url": "https://github.com/sponsors/feross" 689 | }, 690 | { 691 | "type": "patreon", 692 | "url": "https://www.patreon.com/feross" 693 | }, 694 | { 695 | "type": "consulting", 696 | "url": "https://feross.org/support" 697 | } 698 | ] 699 | }, 700 | "node_modules/safer-buffer": { 701 | "version": "2.1.2", 702 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 703 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 704 | }, 705 | "node_modules/send": { 706 | "version": "0.18.0", 707 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 708 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 709 | "dependencies": { 710 | "debug": "2.6.9", 711 | "depd": "2.0.0", 712 | "destroy": "1.2.0", 713 | "encodeurl": "~1.0.2", 714 | "escape-html": "~1.0.3", 715 | "etag": "~1.8.1", 716 | "fresh": "0.5.2", 717 | "http-errors": "2.0.0", 718 | "mime": "1.6.0", 719 | "ms": "2.1.3", 720 | "on-finished": "2.4.1", 721 | "range-parser": "~1.2.1", 722 | "statuses": "2.0.1" 723 | }, 724 | "engines": { 725 | "node": ">= 0.8.0" 726 | } 727 | }, 728 | "node_modules/send/node_modules/ms": { 729 | "version": "2.1.3", 730 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 731 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 732 | }, 733 | "node_modules/serve-static": { 734 | "version": "1.15.0", 735 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 736 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 737 | "dependencies": { 738 | "encodeurl": "~1.0.2", 739 | "escape-html": "~1.0.3", 740 | "parseurl": "~1.3.3", 741 | "send": "0.18.0" 742 | }, 743 | "engines": { 744 | "node": ">= 0.8.0" 745 | } 746 | }, 747 | "node_modules/set-function-length": { 748 | "version": "1.2.2", 749 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 750 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 751 | "dependencies": { 752 | "define-data-property": "^1.1.4", 753 | "es-errors": "^1.3.0", 754 | "function-bind": "^1.1.2", 755 | "get-intrinsic": "^1.2.4", 756 | "gopd": "^1.0.1", 757 | "has-property-descriptors": "^1.0.2" 758 | }, 759 | "engines": { 760 | "node": ">= 0.4" 761 | } 762 | }, 763 | "node_modules/setprototypeof": { 764 | "version": "1.2.0", 765 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 766 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 767 | }, 768 | "node_modules/side-channel": { 769 | "version": "1.0.6", 770 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", 771 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", 772 | "dependencies": { 773 | "call-bind": "^1.0.7", 774 | "es-errors": "^1.3.0", 775 | "get-intrinsic": "^1.2.4", 776 | "object-inspect": "^1.13.1" 777 | }, 778 | "engines": { 779 | "node": ">= 0.4" 780 | }, 781 | "funding": { 782 | "url": "https://github.com/sponsors/ljharb" 783 | } 784 | }, 785 | "node_modules/sparse-bitfield": { 786 | "version": "3.0.3", 787 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 788 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", 789 | "dependencies": { 790 | "memory-pager": "^1.0.2" 791 | } 792 | }, 793 | "node_modules/statuses": { 794 | "version": "2.0.1", 795 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 796 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 797 | "engines": { 798 | "node": ">= 0.8" 799 | } 800 | }, 801 | "node_modules/toidentifier": { 802 | "version": "1.0.1", 803 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 804 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 805 | "engines": { 806 | "node": ">=0.6" 807 | } 808 | }, 809 | "node_modules/tr46": { 810 | "version": "4.1.1", 811 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", 812 | "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", 813 | "dependencies": { 814 | "punycode": "^2.3.0" 815 | }, 816 | "engines": { 817 | "node": ">=14" 818 | } 819 | }, 820 | "node_modules/type-is": { 821 | "version": "1.6.18", 822 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 823 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 824 | "dependencies": { 825 | "media-typer": "0.3.0", 826 | "mime-types": "~2.1.24" 827 | }, 828 | "engines": { 829 | "node": ">= 0.6" 830 | } 831 | }, 832 | "node_modules/unpipe": { 833 | "version": "1.0.0", 834 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 835 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 836 | "engines": { 837 | "node": ">= 0.8" 838 | } 839 | }, 840 | "node_modules/utils-merge": { 841 | "version": "1.0.1", 842 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 843 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 844 | "engines": { 845 | "node": ">= 0.4.0" 846 | } 847 | }, 848 | "node_modules/vary": { 849 | "version": "1.1.2", 850 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 851 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 852 | "engines": { 853 | "node": ">= 0.8" 854 | } 855 | }, 856 | "node_modules/webidl-conversions": { 857 | "version": "7.0.0", 858 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 859 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 860 | "engines": { 861 | "node": ">=12" 862 | } 863 | }, 864 | "node_modules/whatwg-url": { 865 | "version": "13.0.0", 866 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", 867 | "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", 868 | "dependencies": { 869 | "tr46": "^4.1.1", 870 | "webidl-conversions": "^7.0.0" 871 | }, 872 | "engines": { 873 | "node": ">=16" 874 | } 875 | } 876 | } 877 | } 878 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "backend": "file:", 14 | "body-parser": "^1.20.2", 15 | "cors": "^2.8.5", 16 | "crypto": "^1.0.1", 17 | "dotenv": "^16.4.5", 18 | "express": "^4.18.3", 19 | "mongodb": "^6.4.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /backend/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const dotenv = require("dotenv"); 3 | const { MongoClient, ObjectId } = require("mongodb"); 4 | const bodyParser = require("body-parser"); 5 | const cors = require("cors"); 6 | const crypto = require("crypto"); 7 | dotenv.config(); 8 | 9 | // Encryption and Decryption keys 10 | const ENCRYPTION_KEY = Buffer.from(process.env.ENCRYPTION_KEY, 'utf-8'); 11 | const IV_LENGTH = 16; // For AES, this is always 16 12 | 13 | // Encrypt a password 14 | const encrypt = (text) => { 15 | const iv = crypto.randomBytes(IV_LENGTH); 16 | const cipher = crypto.createCipheriv( 17 | "aes-256-cbc", 18 | Buffer.from(ENCRYPTION_KEY), 19 | iv 20 | ); 21 | let encrypted = cipher.update(text, "utf8", "hex"); 22 | encrypted += cipher.final("hex"); 23 | return iv.toString("hex") + ":" + encrypted; // Store IV with the encrypted password 24 | }; 25 | 26 | const decrypt = (text) => { 27 | const [iv, encryptedData] = text.split(":"); 28 | const ivBuffer = Buffer.from(iv, "hex"); 29 | 30 | const decipher = crypto.createDecipheriv( 31 | "aes-256-cbc", 32 | Buffer.from(ENCRYPTION_KEY), 33 | ivBuffer 34 | ); 35 | let decrypted = decipher.update(encryptedData, "hex", "utf-8"); 36 | 37 | decrypted += decipher.final("utf-8"); 38 | 39 | return decrypted; 40 | }; 41 | 42 | // Connecting to the MongoDB Client 43 | const url = process.env.MONGO_URI; 44 | const client = new MongoClient(url); 45 | 46 | client 47 | .connect() 48 | .then(() => { 49 | console.log("Database connected"); 50 | }) 51 | .catch((error) => { 52 | console.error("Database connection failed:", error); 53 | process.exit(1); // Exit the process if the database connection fails 54 | }); 55 | 56 | // App & Database 57 | const dbName = process.env.DB_NAME; 58 | const app = express(); 59 | const port = process.env.PORT || 3000; // Use port from environment variables or default to 3000 60 | 61 | // Middleware 62 | app.use(bodyParser.json()); 63 | app.use(cors({ origin: 'chrome-extension://your-extension-id' })); // Replace with your actual extension ID 64 | 65 | // Get all the passwords 66 | app.get("/", async (req, res) => { 67 | try { 68 | const db = client.db(dbName); 69 | const collection = db.collection("passwords"); 70 | const passwords = await collection.find({}).toArray(); 71 | const decryptedPassword = passwords.map((item) => { 72 | return { ...item, password: decrypt(item.password) }; 73 | }); 74 | res.status(200).json(decryptedPassword); 75 | } catch (error) { 76 | console.error("Error fetching passwords:", error); 77 | res.status(500).json({ success: false, message: "Internal Server Error" }); 78 | } 79 | }); 80 | 81 | // Get a password by id 82 | app.get("/:id", async (req, res) => { 83 | try { 84 | const { id } = req.params; 85 | 86 | // Validate ID format (optional but recommended) 87 | if (!ObjectId.isValid(id)) { 88 | return res.status(400).json({ success: false, message: "Invalid ID format" }); 89 | } 90 | 91 | const db = client.db(dbName); 92 | const collection = db.collection("passwords"); 93 | 94 | // Fetch the password item from the database 95 | const item = await collection.findOne({ _id: new ObjectId(id) }); 96 | 97 | // Check if the password exists 98 | if (!item) { 99 | return res.status(404).json({ success: false, message: "Password not found" }); 100 | } 101 | 102 | // Split and decrypt the password 103 | const [iv, encryptedData] = item.password.split(':'); 104 | const decryptedPassword = decrypt({ iv, encryptedData }); 105 | 106 | // Return the item with the decrypted password 107 | res.status(200).json({ ...item, password: decryptedPassword }); 108 | } catch (error) { 109 | console.error("Error fetching password:", error); 110 | res.status(500).json({ success: false, message: "Internal Server Error" }); 111 | } 112 | }); 113 | 114 | // Save a password 115 | app.post("/", async (req, res) => { 116 | try { 117 | const { site, username, password } = req.body; 118 | if (!site || !username || !password) { 119 | return res.status(400).json({ 120 | success: false, 121 | message: "Site, username, and password are required", 122 | }); 123 | } 124 | 125 | const db = client.db(dbName); 126 | const collection = db.collection("passwords"); 127 | // Encrypt the password before saving 128 | const encryptedPassword = encrypt(password); 129 | const result = await collection.insertOne({ 130 | site, 131 | username, 132 | password: encryptedPassword, 133 | }); 134 | res.status(201).json({ success: true, result }); 135 | } catch (error) { 136 | console.error("Error saving password:", error); 137 | res.status(500).json({ success: false, message: "Internal Server Error" }); 138 | } 139 | }); 140 | 141 | // Update a password by id 142 | app.put("/:id", async (req, res) => { 143 | try { 144 | const { id } = req.params; 145 | const { site, username, password } = req.body; 146 | 147 | if (!site || !username || !password) { 148 | return res.status(400).json({ 149 | success: false, 150 | message: "Site, username, and password are required", 151 | }); 152 | } 153 | 154 | const db = client.db(dbName); 155 | const collection = db.collection("passwords"); 156 | 157 | // Encrypt the new password before updating 158 | const encryptedPassword = encrypt(password); 159 | 160 | const result = await collection.updateOne( 161 | { _id: new ObjectId(id) }, 162 | { $set: { site, username, password: encryptedPassword } } // Use the encrypted password here 163 | ); 164 | 165 | if (result.matchedCount === 0) { 166 | return res 167 | .status(404) 168 | .json({ success: false, message: "Password not found" }); 169 | } 170 | 171 | res.status(200).json({ 172 | success: true, 173 | message: "Password updated successfully", 174 | result, 175 | }); 176 | } catch (error) { 177 | console.error("Error updating password:", error); 178 | res.status(500).json({ success: false, message: "Internal Server Error" }); 179 | } 180 | }); 181 | 182 | // Delete a password by id 183 | app.delete("/:id", async (req, res) => { 184 | try { 185 | const { id } = req.params; 186 | 187 | if (!id) { 188 | return res.status(400).json({ success: false, message: "ID is required" }); 189 | } 190 | 191 | const db = client.db(dbName); 192 | const collection = db.collection("passwords"); 193 | 194 | // Step 1: Find the password by ID 195 | const password = await collection.findOne({ _id: new ObjectId(id) }); 196 | 197 | // Step 2: Check if the password exists 198 | if (!password) { 199 | return res.status(404).json({ success: false, message: "Password not found" }); 200 | } 201 | 202 | // Step 3: Proceed to delete the password 203 | const result = await collection.deleteOne({ _id: new ObjectId(id) }); 204 | 205 | // Step 4: Confirm deletion 206 | if (result.deletedCount === 0) { 207 | return res.status(404).json({ success: false, message: "Password could not be deleted" }); 208 | } 209 | 210 | res.status(200).json({ 211 | success: true, 212 | message: "Password deleted successfully", 213 | result, 214 | }); 215 | } catch (error) { 216 | console.error("Error deleting password:", error); 217 | res.status(500).json({ success: false, message: "Internal Server Error" }); 218 | } 219 | }); 220 | 221 | // Exporting the passwords 222 | app.get("/export", async (req, res) => { 223 | try { 224 | const db = client.db(dbName); 225 | const passwords = await db.collection("passwords").find({}).toArray(); 226 | 227 | // Decrypt each password before exporting 228 | const decryptedPasswords = passwords.map((password) => ({ 229 | site: password.site, 230 | username: password.username, 231 | password: decrypt(password.password), // Directly decrypt the stored password 232 | })); 233 | 234 | res.setHeader("content-Type", "application/json"); 235 | res.setHeader("content-disposition", "attachment; filename=passwords.json"); 236 | res.status(200).json(decryptedPasswords); 237 | } catch (error) { 238 | console.error("Error exporting passwords:", error); 239 | res 240 | .status(500) 241 | .json({ success: false, message: "Error exporting the passwords" }); 242 | } 243 | }); 244 | 245 | // Importing the passwords 246 | app.post("/import", async (req, res) => { 247 | try { 248 | const passwords = req.body; 249 | const db = client.db(dbName); 250 | const collection = db.collection("passwords"); 251 | 252 | await collection.insertMany(passwords); 253 | 254 | res 255 | .status(200) 256 | .json({ success: true, message: "Passwords imported successfully" }); 257 | } catch (error) { 258 | console.error("Error importing passwords:", error); 259 | res 260 | .status(500) 261 | .json({ success: false, message: "Error importing the passwords" }); 262 | } 263 | }); 264 | 265 | // Server listen 266 | app.listen(port, () => { 267 | console.log(`PassOP server listening on http://localhost:${port}`); 268 | }); 269 | -------------------------------------------------------------------------------- /generate-sitemap.js: -------------------------------------------------------------------------------- 1 | import { SitemapStream } from 'sitemap'; 2 | import { createWriteStream } from 'fs'; 3 | import path from 'path'; 4 | import { fileURLToPath } from 'url'; 5 | 6 | const __filename = fileURLToPath(import.meta.url); 7 | const __dirname = path.dirname(__filename); 8 | 9 | // Define the pages you want to include in the sitemap 10 | const pages = [ 11 | { url: '/', changefreq: 'daily', priority: 1.0 }, 12 | { url: '/sign-in', changefreq: 'monthly', priority: 0.8 }, 13 | { url: '/sign-up', changefreq: 'monthly', priority: 0.8 }, 14 | { url: '/manager', changefreq: 'monthly', priority: 0.9 }, 15 | { url: '/issues', changefreq: 'weekly', priority: 0.6 }, // GitHub issues page 16 | { url: '/pulls', changefreq: 'weekly', priority: 0.6 }, // GitHub pull requests page 17 | { url: '/#readme', changefreq: 'monthly', priority: 0.7 }, // README section 18 | // Add more URLs as needed 19 | ]; 20 | 21 | async function generateSitemap() { 22 | // Create a write stream to save the sitemap.xml file 23 | const writeStream = createWriteStream(path.resolve(__dirname, 'public', 'sitemap.xml')); 24 | 25 | // Create a new SitemapStream with your website's hostname 26 | const sitemap = new SitemapStream({ hostname: 'https://github.com/jinx-vi-0/passop' }); 27 | 28 | // Pipe the sitemap to the write stream and log success message on finish 29 | sitemap.pipe(writeStream).on('finish', () => { 30 | console.log('Sitemap generated successfully'); 31 | }); 32 | 33 | // Write each page to the sitemap 34 | pages.forEach(page => sitemap.write(page)); 35 | 36 | // End the sitemap stream 37 | sitemap.end(); 38 | } 39 | 40 | // Execute the generateSitemap function and catch any errors 41 | generateSitemap().catch(error => { 42 | console.error('Error generating sitemap:', error); 43 | }); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PassOP - Your Secure Password Manager 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "passop", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@emotion/react": "^11.13.3", 14 | "@emotion/styled": "^11.13.0", 15 | "@fortawesome/free-brands-svg-icons": "^6.6.0", 16 | "@fortawesome/react-fontawesome": "^0.2.2", 17 | "@mui/icons-material": "^6.1.4", 18 | "@mui/material": "^6.1.4", 19 | "dotenv": "^16.4.5", 20 | "firebase": "^10.14.1", 21 | "install": "^0.13.0", 22 | "npm": "^10.9.0", 23 | "passop": "file:", 24 | "react": "^18.2.0", 25 | "react-dom": "^18.2.0", 26 | "react-icons": "^5.3.0", 27 | "react-router-dom": "^6.27.0", 28 | "react-toastify": "^9.1.3", 29 | "recoil": "^0.7.7", 30 | "uuid": "^9.0.1" 31 | }, 32 | "devDependencies": { 33 | "@types/react": "^18.2.56", 34 | "@types/react-dom": "^18.2.19", 35 | "@vitejs/plugin-react": "^4.2.1", 36 | "autoprefixer": "^10.4.18", 37 | "eslint": "^8.56.0", 38 | "eslint-plugin-react": "^7.33.2", 39 | "eslint-plugin-react-hooks": "^4.6.0", 40 | "eslint-plugin-react-refresh": "^0.4.5", 41 | "postcss": "^8.4.35", 42 | "tailwindcss": "^3.4.1", 43 | "vite": "^5.1.4" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sudo-dpkg/passop/a3d96c8427cfc26db733dc7c12b302b8149a3b63/public/favicon.png -------------------------------------------------------------------------------- /public/icons/eye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sudo-dpkg/passop/a3d96c8427cfc26db733dc7c12b302b8149a3b63/public/icons/eye.png -------------------------------------------------------------------------------- /public/icons/eyecross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sudo-dpkg/passop/a3d96c8427cfc26db733dc7c12b302b8149a3b63/public/icons/eyecross.png -------------------------------------------------------------------------------- /public/icons/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sudo-dpkg/passop/a3d96c8427cfc26db733dc7c12b302b8149a3b63/public/icons/github.png -------------------------------------------------------------------------------- /public/icons/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sudo-dpkg/passop/a3d96c8427cfc26db733dc7c12b302b8149a3b63/public/icons/heart.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /private/ 3 | Allow: / 4 | Sitemap: https://github.com/jinx-vi-0/passop/sitemap.xml -------------------------------------------------------------------------------- /public/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://github.com/jinx-vi-0/passop 5 | 2024-11-08 6 | monthly 7 | 1.0 8 | 9 | 10 | https://github.com/jinx-vi-0/passop#readme 11 | 2024-11-08 12 | monthly 13 | 0.8 14 | 15 | 16 | https://github.com/jinx-vi-0/passop/issues 17 | 2024-11-08 18 | weekly 19 | 0.6 20 | 21 | 22 | https://github.com/jinx-vi-0/passop/pulls 23 | 2024-11-08 24 | weekly 25 | 0.6 26 | 27 | 28 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sudo-dpkg/passop/a3d96c8427cfc26db733dc7c12b302b8149a3b63/src/App.css -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | 2 | import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; 3 | import { useState } from 'react'; 4 | import './App.css'; 5 | import Navbar from './components/Navbar'; 6 | import Manager from './components/Manager'; 7 | import Footer from './components/Footer'; 8 | import SignIn from './components/SignIn'; 9 | import SignUp from './components/SignUp'; 10 | import Metadata from './metadata'; // Import the Metadata component 11 | 12 | function App() { 13 | return ( 14 | 15 | {/* Add Metadata component here */} 16 | 17 |
18 | 19 | } /> 20 | } /> 21 | } /> 22 | {/* Redirect to Manager if no match */} 23 | } /> 24 | 25 |
26 |