|
| 1 | +# Auth Header Injector |
| 2 | + |
| 3 | +A Chrome extension that automatically injects authentication headers into HTTP requests based on URL patterns. Built for developers who need to test APIs with different auth tokens across multiple environments. |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | + |
| 8 | +## Features |
| 9 | + |
| 10 | +- 🎯 **Pattern-based matching** - Target specific domains or subdomains |
| 11 | +- 🔐 **Bearer token injection** - Auto-inject `Authorization` headers |
| 12 | +- 📊 **Real-time tracking** - See which requests are being intercepted |
| 13 | +- 🎨 **Side panel UI** - Context-aware, stays open while browsing |
| 14 | +- ⚡ **Event-driven** - Minimal performance impact with smart caching |
| 15 | +- 🌓 **Dark mode** - Chrome DevTools-inspired aesthetic |
| 16 | + |
| 17 | +## Installation |
| 18 | + |
| 19 | +### From Source |
| 20 | + |
| 21 | +1. **Clone the repository** |
| 22 | + ```bash |
| 23 | + git clone https://github.com/yourusername/auth-header-injector.git |
| 24 | + cd auth-header-injector |
| 25 | + ``` |
| 26 | + |
| 27 | +2. **Install dependencies** |
| 28 | + ```bash |
| 29 | + pnpm install |
| 30 | + ``` |
| 31 | + |
| 32 | +3. **Build the extension** |
| 33 | + ```bash |
| 34 | + pnpm build |
| 35 | + ``` |
| 36 | + |
| 37 | +4. **Load in Chrome** |
| 38 | + - Open `chrome://extensions/` |
| 39 | + - Enable "Developer mode" |
| 40 | + - Click "Load unpacked" |
| 41 | + - Select the `dist` folder |
| 42 | + |
| 43 | +### Development Mode |
| 44 | + |
| 45 | +```bash |
| 46 | +pnpm dev |
| 47 | +``` |
| 48 | + |
| 49 | +This starts a watch server that auto-rebuilds on file changes. Reload the extension in Chrome to see updates. |
| 50 | + |
| 51 | +## Usage |
| 52 | + |
| 53 | +### Quick Start |
| 54 | + |
| 55 | +1. **Open the side panel** |
| 56 | + - Click the extension icon in Chrome toolbar |
| 57 | + - Side panel opens on the right |
| 58 | + |
| 59 | +2. **Enable the extension** |
| 60 | + - Toggle "Enable extension" at the top |
| 61 | + |
| 62 | +3. **Add your first rule** |
| 63 | + - Click "Add Rule" |
| 64 | + - Enter a URL pattern (e.g., `*.api.example.com`) |
| 65 | + - Paste your auth token |
| 66 | + - Add an optional label |
| 67 | + |
| 68 | +4. **Browse and verify** |
| 69 | + - Navigate to a page that makes API calls |
| 70 | + - See real-time request counts in the context bar |
| 71 | + - Verify rules are "active" (intercepting requests) |
| 72 | + |
| 73 | +## URL Pattern Best Practices |
| 74 | + |
| 75 | +### Understanding Pattern Matching |
| 76 | + |
| 77 | +The extension uses Chrome's `urlFilter` syntax with wildcard support. Here are common patterns and what they match: |
| 78 | + |
| 79 | +#### ✅ Recommended Patterns |
| 80 | + |
| 81 | +| Pattern | Matches | Example URLs | |
| 82 | +|---------|---------|--------------| |
| 83 | +| `*example.com` | Base domain + all subdomains | `example.com`<br>`api.example.com`<br>`www.example.com` | |
| 84 | +| `*.example.com` | **Only** subdomains | `api.example.com`<br>`www.example.com`<br>❌ `example.com` | |
| 85 | +| `api.example.com` | Exact subdomain only | `api.example.com`<br>❌ `example.com`<br>❌ `www.example.com` | |
| 86 | +| `*://api.example.com/*` | Explicit URL match | `https://api.example.com/users`<br>`http://api.example.com/auth` | |
| 87 | + |
| 88 | +#### ⚠️ Common Mistakes |
| 89 | + |
| 90 | +```bash |
| 91 | +# ❌ Won't match base domain |
| 92 | +Pattern: *.github.com |
| 93 | +Requests to: github.com/api/... # Not matched! |
| 94 | + |
| 95 | +# ✅ Matches base domain + subdomains |
| 96 | +Pattern: *github.com |
| 97 | +Requests to: github.com/api/... # Matched! |
| 98 | +Requests to: api.github.com/... # Matched! |
| 99 | +``` |
| 100 | + |
| 101 | +#### 🎯 Real-World Examples |
| 102 | + |
| 103 | +**GitHub** |
| 104 | +``` |
| 105 | +Pattern: *github.com |
| 106 | +Matches: |
| 107 | + ✅ https://github.com/api/... |
| 108 | + ✅ https://api.github.com/... |
| 109 | + ✅ https://raw.githubusercontent.com/... |
| 110 | +``` |
| 111 | + |
| 112 | +**Multi-environment API** |
| 113 | +``` |
| 114 | +Pattern: *.lytics.io |
| 115 | +Label: Lytics (All Environments) |
| 116 | +Matches: |
| 117 | + ✅ https://api.lytics.io/... |
| 118 | + ✅ https://c.lytics.io/... |
| 119 | + ❌ https://lytics.io (base domain) |
| 120 | +``` |
| 121 | + |
| 122 | +**Staging Only** |
| 123 | +``` |
| 124 | +Pattern: api.staging.example.com |
| 125 | +Label: Staging API |
| 126 | +Matches: |
| 127 | + ✅ https://api.staging.example.com/users |
| 128 | + ❌ https://api.example.com (production) |
| 129 | +``` |
| 130 | + |
| 131 | +### Testing Your Patterns |
| 132 | + |
| 133 | +1. **Add the rule** with your pattern |
| 134 | +2. **Open the Service Worker console**: |
| 135 | + - Go to `chrome://extensions` |
| 136 | + - Click "Service Worker" under the extension |
| 137 | +3. **Navigate to the target site** |
| 138 | +4. **Check for logs**: `[Request Tracker] ✓ Matched pattern: ...` |
| 139 | + |
| 140 | +If you don't see matches, your pattern might be too narrow (e.g., using `*.domain.com` when you need `*domain.com`). |
| 141 | + |
| 142 | +## Architecture |
| 143 | + |
| 144 | +### Tech Stack |
| 145 | + |
| 146 | +- **Manifest V3** - Latest Chrome extension API |
| 147 | +- **React 19** - UI framework |
| 148 | +- **Shadcn UI** - Component library (Radix UI + Tailwind) |
| 149 | +- **SDK Kit** - Plugin architecture for service worker |
| 150 | +- **Vite** - Build tool with watch mode |
| 151 | +- **TypeScript** - Type safety |
| 152 | +- **Vitest** - Unit testing |
| 153 | + |
| 154 | +### Key Components |
| 155 | + |
| 156 | +``` |
| 157 | +src/ |
| 158 | +├── background/ # Service worker |
| 159 | +│ ├── plugins/ # SDK Kit plugins |
| 160 | +│ │ ├── chromeStorage.ts # Persistent storage |
| 161 | +│ │ ├── patternMatcher.ts # URL pattern matching |
| 162 | +│ │ └── requestInterceptor.ts # Header injection |
| 163 | +│ └── utils/ |
| 164 | +│ └── requestTracking.ts # Pure functions for tracking |
| 165 | +├── panel/ # Side panel UI |
| 166 | +│ ├── components/ # React components |
| 167 | +│ ├── hooks/ # Custom React hooks |
| 168 | +│ └── App.tsx # Main app |
| 169 | +└── shared/ # Shared types & utilities |
| 170 | +``` |
| 171 | + |
| 172 | +### Data Flow |
| 173 | + |
| 174 | +1. **User adds rule** → Saved to `chrome.storage.sync` |
| 175 | +2. **Storage change event** → Updates rule cache in service worker |
| 176 | +3. **Request interceptor** → Injects `Authorization: Bearer {token}` via `declarativeNetRequest` |
| 177 | +4. **Request tracker** → Monitors `webRequest` events, updates stats |
| 178 | +5. **Side panel UI** → Reads stats via `chrome.storage.local`, displays real-time |
| 179 | + |
| 180 | +### Performance Optimizations |
| 181 | + |
| 182 | +- ✅ **Rule caching** - Rules stored in memory, ~0ms lookup |
| 183 | +- ✅ **Batched writes** - Stats written every 3s, reduces I/O by ~90% |
| 184 | +- ✅ **Request debouncing** - Duplicate requests ignored for 1s |
| 185 | +- ✅ **Event-driven UI** - Updates via `chrome.storage.onChanged`, no polling |
| 186 | + |
| 187 | +## API & Permissions |
| 188 | + |
| 189 | +### Required Permissions |
| 190 | + |
| 191 | +```json |
| 192 | +{ |
| 193 | + "permissions": [ |
| 194 | + "declarativeNetRequest", // Inject headers |
| 195 | + "storage", // Persist rules & stats |
| 196 | + "tabs", // Get current tab URL |
| 197 | + "sidePanel", // Side panel UI |
| 198 | + "webRequest" // Track requests |
| 199 | + ], |
| 200 | + "host_permissions": [ |
| 201 | + "<all_urls>" // Match any domain |
| 202 | + ] |
| 203 | +} |
| 204 | +``` |
| 205 | + |
| 206 | +### Storage Schema |
| 207 | + |
| 208 | +**Sync Storage** (rules, synced across devices) |
| 209 | +```typescript |
| 210 | +{ |
| 211 | + auth_rules: AuthRule[] |
| 212 | +} |
| 213 | + |
| 214 | +interface AuthRule { |
| 215 | + id: string; |
| 216 | + pattern: string; // URL pattern |
| 217 | + token: string; // Bearer token |
| 218 | + label?: string; // Optional label |
| 219 | + enabled: boolean; |
| 220 | + createdAt: number; |
| 221 | + updatedAt: number; |
| 222 | +} |
| 223 | +``` |
| 224 | + |
| 225 | +**Local Storage** (stats, device-specific) |
| 226 | +```typescript |
| 227 | +{ |
| 228 | + request_stats: { |
| 229 | + [domain: string]: { |
| 230 | + count: number; |
| 231 | + lastSeen: number; // timestamp |
| 232 | + ruleIds: string[]; |
| 233 | + } |
| 234 | + } |
| 235 | +} |
| 236 | +``` |
| 237 | + |
| 238 | +## Development |
| 239 | + |
| 240 | +### Commands |
| 241 | + |
| 242 | +```bash |
| 243 | +# Install dependencies |
| 244 | +pnpm install |
| 245 | + |
| 246 | +# Start dev server (watch mode) |
| 247 | +pnpm dev |
| 248 | + |
| 249 | +# Build for production |
| 250 | +pnpm build |
| 251 | + |
| 252 | +# Run tests |
| 253 | +pnpm test |
| 254 | + |
| 255 | +# Run tests in watch mode |
| 256 | +pnpm test:watch |
| 257 | + |
| 258 | +# Lint & format |
| 259 | +pnpm lint |
| 260 | +pnpm format |
| 261 | + |
| 262 | +# Type check |
| 263 | +pnpm type-check |
| 264 | +``` |
| 265 | + |
| 266 | +### Project Scripts |
| 267 | + |
| 268 | +- `dev` - Vite watch mode with auto-rebuild |
| 269 | +- `build` - Production build to `dist/` |
| 270 | +- `test` - Run Vitest tests |
| 271 | +- `lint-staged` - Pre-commit hooks (Biome + TypeScript) |
| 272 | + |
| 273 | +### Adding a New Feature |
| 274 | + |
| 275 | +1. **Update types** in `src/shared/types.ts` |
| 276 | +2. **Add business logic** in `src/background/` or hooks |
| 277 | +3. **Update UI** in `src/panel/components/` |
| 278 | +4. **Write tests** in `tests/` or colocated `.test.ts` |
| 279 | +5. **Update README** with usage docs |
| 280 | + |
| 281 | +## Testing |
| 282 | + |
| 283 | +### Running Tests |
| 284 | + |
| 285 | +```bash |
| 286 | +# Run all tests |
| 287 | +pnpm test |
| 288 | + |
| 289 | +# Watch mode |
| 290 | +pnpm test:watch |
| 291 | + |
| 292 | +# With coverage |
| 293 | +pnpm test -- --coverage |
| 294 | +``` |
| 295 | + |
| 296 | +### Test Structure |
| 297 | + |
| 298 | +``` |
| 299 | +tests/ |
| 300 | +├── setup.ts # Global test setup (Chrome API mocks) |
| 301 | +└── src/ |
| 302 | + └── background/ |
| 303 | + └── plugins/ |
| 304 | + ├── chromeStorage.test.ts |
| 305 | + ├── patternMatcher.test.ts |
| 306 | + └── requestInterceptor.test.ts |
| 307 | +``` |
| 308 | + |
| 309 | +Tests use **Vitest** with mocked Chrome APIs. See `tests/setup.ts` for mock implementations. |
| 310 | + |
| 311 | +## Troubleshooting |
| 312 | + |
| 313 | +### Rules not matching requests |
| 314 | + |
| 315 | +**Problem:** You added a rule but don't see request counts increasing. |
| 316 | + |
| 317 | +**Solutions:** |
| 318 | +1. Check your pattern - use `*domain.com` instead of `*.domain.com` if targeting the base domain |
| 319 | +2. Ensure the rule is **enabled** (toggle in the rules list) |
| 320 | +3. Ensure the **extension is enabled** (toggle at top) |
| 321 | +4. Check the Service Worker console for `[Request Tracker]` logs |
| 322 | +5. Verify the site makes API calls (some sites use GraphQL or WebSockets) |
| 323 | + |
| 324 | +### Extension not injecting headers |
| 325 | + |
| 326 | +**Problem:** Rules show active but headers aren't being sent. |
| 327 | + |
| 328 | +**Solutions:** |
| 329 | +1. Check `chrome://extensions` for errors |
| 330 | +2. Ensure pattern uses correct syntax (test with `*://domain.com/*`) |
| 331 | +3. Verify token format (should be just the token, NOT `Bearer {token}`) |
| 332 | +4. Check Network tab in DevTools → Request headers |
| 333 | +5. Some sites block extension-injected headers (rare, but possible) |
| 334 | + |
| 335 | +### Service Worker crashes |
| 336 | + |
| 337 | +**Problem:** Extension stops working after a while. |
| 338 | + |
| 339 | +**Solutions:** |
| 340 | +1. Chrome kills idle service workers after ~30s (normal behavior) |
| 341 | +2. Extension auto-restarts on next event (opening side panel, new request) |
| 342 | +3. Check for errors in Service Worker console |
| 343 | +4. Reload extension if persistent issues |
| 344 | + |
| 345 | +## Contributing |
| 346 | + |
| 347 | +Contributions welcome! Please: |
| 348 | + |
| 349 | +1. Fork the repo |
| 350 | +2. Create a feature branch (`git checkout -b feat/amazing-feature`) |
| 351 | +3. Commit your changes (`git commit -m 'feat: add amazing feature'`) |
| 352 | +4. Push to the branch (`git push origin feat/amazing-feature`) |
| 353 | +5. Open a Pull Request |
| 354 | + |
| 355 | +### Commit Convention |
| 356 | + |
| 357 | +We use [Conventional Commits](https://www.conventionalcommits.org/): |
| 358 | + |
| 359 | +- `feat:` - New feature |
| 360 | +- `fix:` - Bug fix |
| 361 | +- `docs:` - Documentation changes |
| 362 | +- `style:` - Code style changes (formatting, no logic change) |
| 363 | +- `refactor:` - Code refactoring |
| 364 | +- `test:` - Adding/updating tests |
| 365 | +- `chore:` - Maintenance tasks |
| 366 | + |
| 367 | +## Roadmap |
| 368 | + |
| 369 | +- [ ] Export/import rules as JSON |
| 370 | +- [ ] Multiple auth header types (API-Key, Basic Auth, Custom) |
| 371 | +- [ ] Rule templates for popular APIs (GitHub, AWS, etc.) |
| 372 | +- [ ] Request/response logging |
| 373 | +- [ ] Statistics dashboard |
| 374 | +- [ ] Cloud sync with encryption |
| 375 | + |
| 376 | +## License |
| 377 | + |
| 378 | +MIT License - see [LICENSE](LICENSE) for details |
| 379 | + |
| 380 | +## Acknowledgments |
| 381 | + |
| 382 | +- [SDK Kit](https://github.com/yourusername/sdk-kit) - Plugin architecture |
| 383 | +- [Shadcn UI](https://ui.shadcn.com/) - Component library |
| 384 | +- [Lucide Icons](https://lucide.dev/) - Icon set |
| 385 | +- [Chrome Extensions Docs](https://developer.chrome.com/docs/extensions/) - API reference |
| 386 | + |
| 387 | +--- |
| 388 | + |
| 389 | +**Built with ❤️ for developers who live in the browser** |
| 390 | + |
0 commit comments