fix: pre-existing auth bugs in extension and core
- Dominant language
- Jupyter Notebook
- Stars
- 30
- Forks
- 15
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
Several pre-existing auth-related bugs identified during review of #124. These are NOT regressions from #124 — they exist on `master` today.
### Bug 1: OAuth auth URL missing `encodeURIComponent`
**File:** `products/userale/packages/flagon-userale-ext/src/options/auth.tsx` (~line 40)
```typescript
const authUrl = `${issuerUrl}/protocol/openid-connect/auth?` +
`client_id=${clientId}` + // ← NOT URL-encoded
```
`clientId` is concatenated directly without `encodeURIComponent()`. If a client ID contains special characters (`&`, `=`, `#`), it corrupts the OAuth URL and could enable URL parameter injection.
**Fix:** `client_id=${encodeURIComponent(clientId)}`
### Bug 2: OAuth form missing `preventDefault()`
**File:** `products/userale/packages/flagon-userale-ext/src/options/auth.tsx`
The `handleLogin` function is `async` but does not accept or call `e.preventDefault()`. When used as a form `onSubmit` handler, the browser will attempt default form submission (page reload) before the async OAuth flow completes.
**Fix:** Change signature to `const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); ... }`
### Bug 3: Extension `STORAGE_KEYS` constant out of sync
**File:** `products/userale/packages/flagon-userale-ext/src/utils/storage.ts`
After #124, `StoredOptions` includes `apiKey` and `authMode`, but the `STORAGE_KEYS` constant and `DEFAULT_OPTIONS` only list `accessToken`, `allowList`, `loggingUrl`. This inconsistency could confuse contributors and break if code relies on `STORAGE_KEYS` for enumeration.
**Fix:** Add `apiKey`, `authMode` to both `STORAGE_KEYS` and `DEFAULT_OPTIONS`.
### Bug 4: Extension regex validation on partial updates
**File:** `products/userale/packages/flagon-userale-ext/src/utils/storage.ts` (line 60)
```typescript
export async function setStoredOptions(values: Partial) {
try {
new RegExp(values.allowList) // throws if allowList not in partial
new URL(values.loggingUrl) // throws if loggingUrl not in partial
} catch (error) {
return error
}
```
Validation runs unconditionally on `allowList` and `loggingUrl` even when they are not being updated (partial update). `new RegExp(undefined)` creates a regex matching the string `"undefined"` (silent wrong behavior), while `new URL(undefined)` throws.
**Note:** #124 likely fixes this, but confirm the fix is correct (should only validate fields present in the partial update).
### Context
All bugs pre-date #124. Found during security and software engineering review.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading products/userale/packages/flagon-userale-ext/src/options/auth.tsx and products/userale/packages/flagon-userale-ext/src/utils/storage.ts, then compare the current behavior with the changes in #124. Verify the OAuth URL and form handling, keep STORAGE_KEYS and DEFAULT_OPTIONS aligned, and ensure partial updates validate only fields that are present.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- authentication, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100