fix: simplify settings#1
Conversation
yeabwang
commented
Feb 4, 2026
- Remove Spotify Client ID and Redirect URL from Settings page (pre-configured via environment variables)
- Users only need to enter their OpenAI API key in Settings
- Update apiKeys service to reflect simplified configuration
- Update CI/CD workflows to remove OpenAI key requirement from build
- Update README with simplified setup instructions
- Spotify integration is now pre-configured for users
- Remove Spotify Client ID and Redirect URL from Settings page (pre-configured via environment variables) - Users only need to enter their OpenAI API key in Settings - Update apiKeys service to reflect simplified configuration - Update CI/CD workflows to remove OpenAI key requirement from build - Update README with simplified setup instructions - Spotify integration is now pre-configured for users
There was a problem hiding this comment.
Pull request overview
Simplifies the app’s configuration flow so end users only need to provide an OpenAI API key in the Settings UI, while Spotify configuration is expected to be supplied via environment variables.
Changes:
- Removed Spotify Client ID / Redirect URL fields from the Settings page and updated copy accordingly.
- Simplified the
apiKeysservice to persist only the OpenAI key in localStorage and adjusted “configured” checks. - Updated CI/CD workflows and README to reflect the new configuration expectations.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/services/apiKeys.ts | Drops Spotify key persistence and updates “configured” logic and env lookups. |
| src/pages/Settings/index.tsx | Removes Spotify credential inputs; keeps only OpenAI key management UI. |
| README.md | Updates setup docs to emphasize Settings-based OpenAI key entry and adds a self-hosting section. |
| .github/workflows/deploy.yml | Removes OpenAI key from build env; updates Spotify redirect env fallback. |
| .github/workflows/ci.yml | Removes OpenAI key from build env and tweaks build-time env settings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| {/* Spotify Info Banner */} | ||
| <div className="env-notice"> | ||
| <span className="notice-icon">🎵</span> | ||
| <span>Spotify integration is pre-configured. Just log in with your Spotify account to start!</span> | ||
| </div> |
There was a problem hiding this comment.
This banner claims Spotify is “pre-configured” unconditionally. In self-host/local dev scenarios where REACT_APP_SPOTIFY_CLIENT_ID isn’t set, Spotify login will fail (client_id will be empty). Suggest making this message conditional on the env vars being present, or clarifying that it’s only pre-configured for the hosted deployment.
| 3. **Start the development server** | ||
|
|
||
| Create a `.env` file in the root directory: | ||
|
|
||
| ```env | ||
| # Spotify Configuration | ||
| REACT_APP_SPOTIFY_CLIENT_ID=<your_spotify_client_id> | ||
| REACT_APP_SPOTIFY_REDIRECT_URL=http://localhost:3000/callback | ||
|
|
||
| # OpenAI Configuration (for AI features) | ||
| REACT_APP_OPENAI_API_KEY=<your_openai_api_key> | ||
|
|
||
| # Optional: Customize OpenAI model (defaults to gpt-5.2-chat-latest) | ||
| # REACT_APP_OPENAI_MODEL=gpt-5 | ||
| ```bash | ||
| yarn start | ||
| ``` | ||
| 4. **Open your browser** | ||
|
|
||
| **Get your credentials:** | ||
| Navigate to `http://localhost:3000` | ||
|
|
||
| - **Spotify**: Create an app at [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/applications) | ||
| - **OpenAI**: Get your API key from [OpenAI Platform](https://platform.openai.com/api-keys) | ||
| 5. **Configure your OpenAI API key** | ||
|
|
||
| Go to **Settings** (⚙️) in the app and enter your OpenAI API key. | ||
|
|
There was a problem hiding this comment.
Quick Start no longer includes any step to set REACT_APP_SPOTIFY_CLIENT_ID / redirect URL, but the app’s Spotify OAuth requires a client id at runtime (see .env.dist and getSpotifyClientId() usage). As written, a fresh local checkout followed by yarn start will not be able to log into Spotify. Please either restore the required Spotify env setup in Quick Start, or explicitly state that Quick Start assumes a preconfigured hosted build.
| If you want to self-host with your own Spotify app, create a `.env` file: | ||
|
|
||
| ```env | ||
| # Spotify Configuration (optional - pre-configured for hosted version) | ||
| REACT_APP_SPOTIFY_CLIENT_ID=<your_spotify_client_id> | ||
| REACT_APP_SPOTIFY_REDIRECT_URL=http://localhost:3000 | ||
|
|
||
| # OpenAI Configuration (optional - users can enter in Settings) | ||
| REACT_APP_OPENAI_API_KEY=<your_openai_api_key> | ||
|
|
There was a problem hiding this comment.
In the self-hosting .env example, Spotify configuration is labeled “optional”, but REACT_APP_SPOTIFY_CLIENT_ID appears required for Spotify OAuth to function. Recommend clarifying which variables are truly optional vs required for self-hosting, and aligning this section with .env.dist.
| env: | ||
| REACT_APP_SPOTIFY_CLIENT_ID: ${{ secrets.REACT_APP_SPOTIFY_CLIENT_ID }} | ||
| REACT_APP_SPOTIFY_REDIRECT_URL: ${{ secrets.REACT_APP_SPOTIFY_REDIRECT_URL }} | ||
| REACT_APP_OPENAI_API_KEY: ${{ secrets.REACT_APP_OPENAI_API_KEY }} | ||
| REACT_APP_SPOTIFY_REDIRECT_URL: ${{ secrets.REACT_APP_SPOTIFY_REDIRECT_URL || 'https://spotify-ai.vercel.app' }} | ||
| CI: false |
There was a problem hiding this comment.
The fallback REACT_APP_SPOTIFY_REDIRECT_URL is hard-coded to https://spotify-ai.vercel.app, but this workflow deploys to GitHub Pages (or a custom domain). If the secret isn’t set (or differs), the built app will embed a redirect URI that doesn’t match the actual deployment URL, breaking Spotify OAuth. Consider removing the fallback (fail fast) or deriving the default from the deployment target/custom domain.
| REACT_APP_SPOTIFY_CLIENT_ID: ${{ secrets.REACT_APP_SPOTIFY_CLIENT_ID || 'test-client-id' }} | ||
| REACT_APP_SPOTIFY_REDIRECT_URL: ${{ secrets.REACT_APP_SPOTIFY_REDIRECT_URL || 'http://localhost:3000' }} | ||
| REACT_APP_OPENAI_API_KEY: ${{ secrets.REACT_APP_OPENAI_API_KEY || 'test-key' }} | ||
| CI: false |
There was a problem hiding this comment.
Setting CI: false for the build step in the CI workflow prevents CRA from failing the build on warnings, which can allow issues to slip through (especially since the ESLint job currently can’t fail due to || echo). Recommend keeping CI builds strict (omit this override or set CI: true) and fixing any resulting warnings instead.
| CI: false | |
| CI: true |
| * Securely manages user-provided API keys in localStorage. | ||
| * Keys are stored encrypted using a simple obfuscation (for basic protection). | ||
| * | ||
| * IMPORTANT: This is client-side storage. For production, consider: | ||
| * - Using a backend proxy for API calls | ||
| * - Never exposing API keys in network requests visible to users | ||
| * Note: Spotify Client ID and Redirect URL are pre-configured via environment variables. | ||
| * Users only need to provide their OpenAI API key. |
There was a problem hiding this comment.
The updated header comment removed the prior warning about client-side key storage and now describes the keys as being stored “securely” / “encrypted”, even though the implementation is only reversible obfuscation in localStorage. Please reintroduce the security caveats (client-side exposure, recommend backend proxy, etc.) and adjust wording to avoid implying real encryption.
| export const isFullyConfigured = (): { configured: boolean; missing: string[] } => { | ||
| const missing: string[] = []; | ||
|
|
||
| if (!getSpotifyClientId()) missing.push('Spotify Client ID'); | ||
| if (!getOpenAIApiKey()) missing.push('OpenAI API Key'); | ||
|
|
There was a problem hiding this comment.
isFullyConfigured() now only checks the OpenAI key, but the app’s Spotify OAuth flow still requires a non-empty Spotify client id (getSpotifyClientId() is used in src/utils/spotify/login.ts). If REACT_APP_SPOTIFY_CLIENT_ID is missing (common in self-host/local dev), Settings will report “configured” even though Spotify login cannot work. Consider including a Spotify client-id check here (or split into separate “AI configured” vs “Spotify configured” statuses).
- Restore security caveats in apiKeys.ts about client-side storage - Fix isFullyConfigured() to check both Spotify and OpenAI config - Add separate spotifyConfigured and aiConfigured status fields - Make Settings page Spotify banner conditional on env var presence - Update README Quick Start to include required Spotify env setup - Clarify required vs optional env vars in self-hosting docs - Remove hardcoded fallback URL from deploy workflow (fail fast) - Remove CI: false from CI workflow to keep builds strict - Update security notice to accurately describe obfuscation vs encryption
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** | ||
| * Check if Spotify is configured (via environment variables) | ||
| */ | ||
| export const isSpotifyConfigured = (): boolean => { | ||
| return !!getSpotifyClientId(); | ||
| }; |
There was a problem hiding this comment.
isSpotifyConfigured() only checks for a Spotify Client ID, but the OAuth flow also depends on having a correct redirect URI. With the Settings UI removed, a missing/mis-set REACT_APP_SPOTIFY_REDIRECT_URL can still break login while the UI reports Spotify as “configured”. Consider treating Spotify as configured only when both client id and redirect URL are set (or otherwise validating that the computed redirect URL is acceptable), and reflect that in isFullyConfigured().missing messaging.
|
|
||
| const handleClear = () => { | ||
| if (window.confirm('Are you sure you want to clear all API keys? You will need to re-enter them to use the app.')) { | ||
| if (window.confirm('Are you sure you want to clear your API key? You will need to re-enter it to use AI features.')) { |
There was a problem hiding this comment.
The clear-confirmation copy implies AI features will stop working until the user re-enters a key, but getOpenAIApiKey() falls back to REACT_APP_OPENAI_API_KEY. If that env var is set, clearing localStorage won’t actually disable AI features, so the message (and possibly the button label) should clarify it only clears the locally stored key.
| if (window.confirm('Are you sure you want to clear your API key? You will need to re-enter it to use AI features.')) { | |
| if (window.confirm('Are you sure you want to clear your locally stored API key? This will remove the key saved in this browser. AI features may still work if your app is configured with an API key elsewhere.')) { |
| Copy `.env.dist` to `.env` and fill in the required values: | ||
|
|
||
| ```bash | ||
| cp .env.dist .env | ||
| ``` | ||
|
|
||
| Edit `.env` with your credentials: | ||
|
|
||
| ```env | ||
| # Spotify Configuration | ||
| # Required: Spotify API Configuration | ||
| REACT_APP_SPOTIFY_CLIENT_ID=<your_spotify_client_id> | ||
| REACT_APP_SPOTIFY_REDIRECT_URL=http://localhost:3000/callback | ||
| REACT_APP_SPOTIFY_REDIRECT_URL=http://localhost:3000 | ||
|
|
||
| # OpenAI Configuration (for AI features) | ||
| # Optional: OpenAI API Key (can also be entered in Settings page) | ||
| REACT_APP_OPENAI_API_KEY=<your_openai_api_key> | ||
|
|
||
| # Optional: Customize OpenAI model (defaults to gpt-5.2-chat-latest) | ||
| # REACT_APP_OPENAI_MODEL=gpt-5 | ||
| ``` |
There was a problem hiding this comment.
README now instructs copying .env.dist but the sample .env block says the OpenAI key is optional and uses http://localhost:3000 for the redirect URL. Since .env.dist currently still labels the OpenAI key as required and uses http://127.0.0.1:3000, this can confuse setup. Either update .env.dist to match the new guidance, or adjust the README to match the current .env.dist contents.
| ### Self-Hosting / Production Deployment | ||
|
|
||
| For self-hosted deployments, the following environment variables are required: | ||
|
|
||
| | Variable | Required | Description | | ||
| |----------|----------|-------------| | ||
| | `REACT_APP_SPOTIFY_CLIENT_ID` | **Yes** | Your Spotify app's Client ID | | ||
| | `REACT_APP_SPOTIFY_REDIRECT_URL` | **Yes** | Must match your deployment URL exactly | | ||
| | `REACT_APP_OPENAI_API_KEY` | No | Optional; users can enter in Settings | | ||
| | `REACT_APP_OPENAI_MODEL` | No | Defaults to `gpt-5.2-chat-latest` | | ||
|
|
There was a problem hiding this comment.
The Self-Hosting section lists REACT_APP_OPENAI_API_KEY as an optional production env var. In CRA, REACT_APP_* variables are embedded into the client bundle, so setting a shared OpenAI key in production effectively exposes it to all users. Add an explicit warning here (and/or recommend not setting it in production, using a backend proxy, or requiring users to provide their own key) to avoid accidental key leakage.
| # Optional: OpenAI API Key (can also be entered in Settings page) | ||
| REACT_APP_OPENAI_API_KEY=<your_openai_api_key> |
There was a problem hiding this comment.
Using REACT_APP_OPENAI_API_KEY in a front-end React app means the OpenAI API key will be baked into the compiled JavaScript bundle and exposed to every user who loads the app. An attacker can simply view the built assets or intercept network requests in the browser DevTools to extract this key and abuse your OpenAI account. For production, avoid using a shared deployment-wide OpenAI key in REACT_APP_OPENAI_API_KEY and instead require per-user keys entered in Settings or proxy OpenAI calls through a backend that keeps the secret key server-side.
| # Optional: OpenAI API Key (can also be entered in Settings page) | |
| REACT_APP_OPENAI_API_KEY=<your_openai_api_key> | |
| # Optional: OpenAI API Key | |
| # For security, do NOT expose your OpenAI API key via REACT_APP_* variables in a front-end build. | |
| # Instead, either: | |
| # - Enter your key in the app's Settings page (per-user key), or | |
| # - Configure it on a backend service as a server-side environment variable. |