{"id":30240174,"url":"https://github.com/moneydash/resumeforge-express","last_synced_at":"2025-08-15T04:11:10.776Z","repository":{"id":308936173,"uuid":"1022730021","full_name":"Moneydash/resumeforge-express","owner":"Moneydash","description":"Resume Builder for Developers - API (Express)","archived":false,"fork":false,"pushed_at":"2025-08-08T18:06:50.000Z","size":72,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-08T20:24:45.610Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Moneydash.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-19T17:44:18.000Z","updated_at":"2025-08-08T18:05:15.000Z","dependencies_parsed_at":"2025-08-08T20:24:56.346Z","dependency_job_id":"f83bf11c-0e23-42a7-acbb-d8f07a9c0d99","html_url":"https://github.com/Moneydash/resumeforge-express","commit_stats":null,"previous_names":["moneydash/resumeforge-express"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Moneydash/resumeforge-express","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moneydash%2Fresumeforge-express","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moneydash%2Fresumeforge-express/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moneydash%2Fresumeforge-express/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moneydash%2Fresumeforge-express/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Moneydash","download_url":"https://codeload.github.com/Moneydash/resumeforge-express/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moneydash%2Fresumeforge-express/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270520189,"owners_count":24599309,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-15T02:00:12.559Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-15T04:11:08.955Z","updated_at":"2025-08-15T04:11:10.767Z","avatar_url":"https://github.com/Moneydash.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ResumeForge Express Backend\n\nA Node.js/Express backend for a resume-building platform with Google and GitHub OAuth authentication, PDF generation, and MySQL database integration. Built with TypeScript for type safety and maintainability.\n\n---\n\n## Project Summary\n\nResumeForge Express provides secure, passwordless authentication via Google and GitHub, allowing users to create, save, and generate PDF resumes. The backend is modular, using Express.js, Passport.js, Knex.js, and Puppeteer for PDF rendering. All user data is stored in a MySQL database.\n\n---\n\n## Features\n\n- **Google \u0026 GitHub OAuth authentication** (no password login)\n- **MySQL database integration** with Knex.js ORM\n- **PDF generation** from HTML using Puppeteer with multiple resume templates\n- **Resume management** (create, read, update, delete, clone, rename)\n- **Session management** with secure cookies and CSRF protection\n- **Rate limiting** for authentication and PDF generation endpoints\n- **Input validation** and sanitization for security\n- **CORS support** for frontend integration\n- **TypeScript** for type safety and better developer experience\n- **Database migrations** for schema management and versioning\n\n---\n\n## Security Practices\n\n- No password storage or password-based login (reduces risk of brute-force and credential leaks)\n- All authentication via trusted OAuth providers (Google, GitHub)\n- Session cookies are set to `secure` in production and use `httpOnly`\n- Input validation and sanitization for user-provided HTML\n- Rate limiting middleware for authentication endpoints\n- CORS origin restricted via environment variable\n\n**Areas for Improvement:**\n- Ensure all secrets (session, OAuth) are set via environment variables\n- Enforce HTTPS in production\n- Consider adding global rate limiting\n- Unify database access (prefer Knex.js over raw MySQL)\n- Add automated tests for critical flows\n\n---\n\n## Setup Instructions\n\n### 1. Install Dependencies\n\n```bash\nnpm install\n```\n\n### 2. Environment Variables\n\nCreate a `.env` file in the root directory with the following variables:\n\n```env\nPORT=8080\nNODE_ENV=development\nDB_HOST=localhost\nDB_USER=root\nDB_PASSWORD=your_mysql_password\nDB_NAME=resumeforge\nDB_PORT=3306\nGOOGLE_CLIENT_ID=your_google_client_id\nGOOGLE_CLIENT_SECRET=your_google_client_secret\nGITHUB_CLIENT_ID=your_github_client_id\nGITHUB_CLIENT_SECRET=your_github_client_secret\nSESSION_SECRET=your_session_secret_key_here\nFRONTEND_URL=http://localhost:3000\n```\n\n### 3. Database Setup\n\n1. Create a MySQL database named `resumeforge`\n2. Run migrations to create tables:\n   ```bash\n   npm run migrate\n   ```\n3. (Optional) Run seeds to populate initial data:\n   ```bash\n   npm run seed\n   ```\n\n### 4. OAuth Setup\n\n- Set up OAuth credentials for Google and GitHub in their respective developer consoles.\n- Add authorized redirect URIs:\n  - `http://localhost:8080/auth/google/callback`\n  - `http://localhost:8080/auth/github/callback`\n\n### 5. Run the Application\n\n```bash\nnpm run dev\n```\n\nThe server will start on `http://localhost:8080`\n\n---\n\n## API Endpoints\n\n### Authentication\n- `GET /` - Root route, redirects based on auth status\n- `GET /login` - Login page (returns available providers)\n- `GET /auth/google` - Initiate Google OAuth login\n- `GET /auth/google/callback` - Google OAuth callback\n- `GET /auth/github` - Initiate GitHub OAuth login\n- `GET /auth/github/callback` - GitHub OAuth callback\n- `POST /logout` - Logout user\n- `GET /auth-status` - Check authentication status\n- `GET /dashboard` - Protected dashboard route\n- `GET /profile` - Get user profile (requires authentication)\n- `GET /csrf-token` - Get CSRF token for secure requests\n- `GET /db-test` - Test database connection\n\n### Resume Management\n- `POST /resume/generate` - Generate PDF from HTML (requires authentication)\n- `POST /resume/save-data` - Save or update user resume data (requires authentication)\n- `GET /resume/fetch-data/:id/:userId` - Fetch specific resume data (requires authentication)\n- `GET /resume/fetch-resumes/:userId` - Fetch all resumes for a user (requires authentication)\n- `POST /resume/create-init/:userId` - Create a new empty resume (requires authentication)\n- `POST /resume/rename/:id/:userId` - Rename an existing resume (requires authentication)\n- `POST /resume/clone/:id/:userId` - Clone an existing resume (requires authentication)\n- `DELETE /resume/delete-resume/:id/:userId` - Delete a resume (requires authentication)\n\n---\n\n## Project Structure\n\n```bash\nsrc/\n├── controllers/\n│   ├── auth.ts          # OAuth authentication controllers (Google \u0026 GitHub)\n│   ├── resume.ts        # Resume CRUD operations controllers\n│   └── pdf.ts           # PDF generation controller using Puppeteer\n├── routes/\n│   ├── auth.ts          # Authentication routes with middleware\n│   └── resume.ts        # Resume/PDF routes with rate limiting\n├── models/\n│   ├── User.ts          # User model with OAuth provider support\n│   └── Resume.ts        # Resume data model with CRUD operations\n├── db/\n│   ├── db.ts            # MySQL2 connection setup\n│   ├── knex.ts          # Knex configuration\n│   └── migrations/      # Database migrations\n├── middlewares/\n│   └── auth.ts          # Authentication, CSRF, and rate limiting middleware\n├── types/\n│   ├── interface.user.ts        # User type definitions\n│   ├── interface.resume.ts      # Resume data type definitions\n│   └── types.controller-type.ts # Controller type definitions\n├── utils/\n│   └── helper.ts         # Utility functions (ID generation, HTML formatting)\n└── index.ts              # Main application entry point with Express setup\n```\n\n---\n\n## Database Schema\n\n### Users Table\n- `id` (VARCHAR) - Primary key\n- `google_id` (VARCHAR) - Google OAuth ID (unique)\n- `github_id` (VARCHAR) - GitHub OAuth ID (unique)\n- `email` (VARCHAR) - User email (unique)\n- `name` (VARCHAR) - User display name\n- `avatar` (TEXT) - User avatar URL\n- `created_at` (TIMESTAMP) - Account creation time\n- `updated_at` (TIMESTAMP) - Last update time\n\n### user_resume_data Table\n- `id` (VARCHAR) - Primary key\n- `user_id` (VARCHAR) - Foreign key to users.id\n- `resume_name` (VARCHAR) - Display name for the resume\n- `resume_slug_name` (VARCHAR) - URL-friendly slug for the resume\n- `resume_data` (TEXT/JSON) - Resume content in JSON format\n- `template` (VARCHAR) - Resume template identifier\n- `created_at` (TIMESTAMP) - Creation timestamp\n- `updated_at` (TIMESTAMP) - Last update timestamp\n- `deleted_at` (TIMESTAMP) - Soft delete timestamp (nullable)\n\n---\n\n## Troubleshooting\n\n- **CORS Errors:** Ensure `FRONTEND_URL` in `.env` matches your frontend URL and requests include `credentials: 'include'`.\n- **Database Connection Errors:** Verify MySQL is running, credentials are correct, and the database exists.\n- **OAuth Errors:** Check credentials and redirect URIs in your provider consoles and `.env` file.\n\n---\n\n## License\n\nPolyform Noncommercial License","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoneydash%2Fresumeforge-express","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoneydash%2Fresumeforge-express","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoneydash%2Fresumeforge-express/lists"}