New doc: Kinde auth in Chrome extension#743
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughNew MDX guide documenting Kinde PKCE authentication for a Plasmo MV3 Chrome extension, including setup, popup and dashboard UI, background token exchange and silent renewal, shared JWT/session helpers, styling, testing, production, and troubleshooting guidance. ChangesChrome Extension with Kinde PKCE Authentication
Estimated code review effort: 3 (Moderate) | ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying kinde-docs-preview with
|
| Latest commit: |
2624971
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://6d549371.kinde-docs-preview.pages.dev |
| Branch Preview URL: | https://tamal-new-kinde-chrome-exten.kinde-docs-preview.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/content/docs/developer-tools/guides/browser-extension.mdx (1)
111-114: 💤 Low valueConsider documenting or expanding regional host permissions.
The
host_permissionsinclude*.kinde.comand*.au.kinde.com, but Kinde has other regional domains (e.g.,*.eu.kinde.com,*.us.kinde.com). Users in other regions may need to add their region's domain. Consider either:
- Adding a note explaining users should add their region's domain if applicable, or
- Including common regional patterns in the example.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/content/docs/developer-tools/guides/browser-extension.mdx` around lines 111 - 114, The host_permissions example only lists "https://*.kinde.com/*" and "https://*.au.kinde.com/*", which may miss other regional domains; update the browser extension docs around the host_permissions example to either add a short note telling users to include their regional domain (e.g., *.eu.kinde.com, *.us.kinde.com) or expand the example to include common regional patterns, referencing the host_permissions array and the URL patterns shown so readers know where to add their region-specific entries.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/content/docs/developer-tools/guides/browser-extension.mdx`:
- Around line 806-808: The doc claims lib/session.ts avoids importing
chrome.identity and keeping the dashboard bundle free of it, but signOut in
lib/session.ts directly calls chrome.identity.getRedirectURL and
chrome.identity.launchWebAuthFlow; either update the documentation to remove the
"keeps bundle free" claim or refactor signOut to mirror the login flow by
delegating the auth work to the background worker (e.g., add a bg message
handler and call chrome.runtime.sendMessage from signOut), remove direct
chrome.identity calls from signOut, and ensure the background handler performs
getRedirectURL/launchWebAuthFlow and returns the result to the dashboard caller.
- Around line 121-123: In the "8. Update environment variables" section update
the sentence that currently reads "add your Kinde credentials the **Details**
page" to include the missing preposition so it reads "add your Kinde credentials
from the **Details** page"; locate this text in
src/content/docs/developer-tools/guides/browser-extension.mdx within the "8.
Update environment variables" heading and insert "from" between "credentials"
and "the".
- Around line 95-97: The document has a step-numbering gap and an editorial
TODO: remove the stray "TODO: Review this section." and either renumber the "###
7. Update `package.json`" heading to the correct sequential step after "### 3.
Install Kinde dependency" (e.g., change to "### 4. Update `package.json`") or,
if actual steps 4–6 were intended, insert the missing steps content between "###
3. Install Kinde dependency" and the current update-package.json section; ensure
all headings (e.g., "### 3. Install Kinde dependency" and "### 7. Update
`package.json`") are sequential and consistent before publishing.
- Around line 1099-1128: Clarify the docs around the patch-expo-stub.mjs stub:
explain that `@kinde/js-utils`' ExpoSecureStore uses await
import("expo-secure-store") inside loadExpoStore() wrapped in a try/catch so the
import is lazy/optional, but because the script creates a real module under
node_modules/expo-secure-store the dynamic import will succeed (and the
try/catch won’t be exercised) — the stub only makes sense when you only use
ChromeStore and may still cause runtime errors if ExpoSecureStore is
instantiated outside Expo; also note that the script writes version "11.0.0"
which satisfies the peer range (>=11.0.0) and explicitly call out the fragility
of writing into node_modules (may require re-running after npm ci or tooling
changes).
---
Nitpick comments:
In `@src/content/docs/developer-tools/guides/browser-extension.mdx`:
- Around line 111-114: The host_permissions example only lists
"https://*.kinde.com/*" and "https://*.au.kinde.com/*", which may miss other
regional domains; update the browser extension docs around the host_permissions
example to either add a short note telling users to include their regional
domain (e.g., *.eu.kinde.com, *.us.kinde.com) or expand the example to include
common regional patterns, referencing the host_permissions array and the URL
patterns shown so readers know where to add their region-specific entries.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 207d279a-a3be-4904-906d-8f433069efd7
📒 Files selected for processing (1)
src/content/docs/developer-tools/guides/browser-extension.mdx
| ### 7. Update `package.json` | ||
|
|
||
| TODO: Review this section. |
There was a problem hiding this comment.
Step numbering gap and TODO comment need attention.
The section jumps from "### 3. Install Kinde dependency" directly to "### 7. Update package.json" — steps 4, 5, and 6 are missing. Additionally, line 97 contains a TODO: Review this section. comment that should be removed before publishing.
📝 Suggested fix
-### 7. Update `package.json`
-
-TODO: Review this section.
+### 4. Update `package.json`Or add the missing steps 4-6 if they were intended to exist.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### 7. Update `package.json` | |
| TODO: Review this section. | |
| ### 4. Update `package.json` |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/content/docs/developer-tools/guides/browser-extension.mdx` around lines
95 - 97, The document has a step-numbering gap and an editorial TODO: remove the
stray "TODO: Review this section." and either renumber the "### 7. Update
`package.json`" heading to the correct sequential step after "### 3. Install
Kinde dependency" (e.g., change to "### 4. Update `package.json`") or, if actual
steps 4–6 were intended, insert the missing steps content between "### 3.
Install Kinde dependency" and the current update-package.json section; ensure
all headings (e.g., "### 3. Install Kinde dependency" and "### 7. Update
`package.json`") are sequential and consistent before publishing.
| ### 8. Update environment variables | ||
|
|
||
| 1. Create a `.env` file at the project root and add your Kinde credentials the **Details** page: |
There was a problem hiding this comment.
Fix grammar: missing preposition.
Line 123 reads "add your Kinde credentials the Details page" — the word "from" is missing.
📝 Suggested fix
-1. Create a `.env` file at the project root and add your Kinde credentials the **Details** page:
+1. Create a `.env` file at the project root and add your Kinde credentials from the **Details** page:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### 8. Update environment variables | |
| 1. Create a `.env` file at the project root and add your Kinde credentials the **Details** page: | |
| ### 8. Update environment variables | |
| 1. Create a `.env` file at the project root and add your Kinde credentials from the **Details** page: |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/content/docs/developer-tools/guides/browser-extension.mdx` around lines
121 - 123, In the "8. Update environment variables" section update the sentence
that currently reads "add your Kinde credentials the **Details** page" to
include the missing preposition so it reads "add your Kinde credentials from the
**Details** page"; locate this text in
src/content/docs/developer-tools/guides/browser-extension.mdx within the "8.
Update environment variables" heading and insert "from" between "credentials"
and "the".
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/content/docs/developer-tools/guides/chrome-extension.mdx (1)
110-113: 💤 Low valueConsider documenting additional Kinde regional domains.
The
host_permissionsonly explicitly lists*.au.kinde.com/*. Kinde operates in multiple regions (US, EU, AU, etc.), and while*.kinde.com/*may cover most cases, users with custom domains or region-specific subdomains might need guidance.Consider adding a note that users should include their specific custom domain if applicable (as done in the troubleshooting section at lines 1681-1688).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/content/docs/developer-tools/guides/chrome-extension.mdx` around lines 110 - 113, Update the manifest example's host_permissions entry to clarify regional and custom domains: in the documentation around the "host_permissions" example that currently shows "https://*.kinde.com/*" and "https://*.au.kinde.com/*", add a short note telling users to include other regional domains (e.g., EU/US subdomains) and any custom domains they use, and reference the existing troubleshooting section that instructs adding custom domains so readers know to add their own host_permissions when needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/content/docs/developer-tools/guides/chrome-extension.mdx`:
- Line 1175: Replace the misspelled word "devltools" with "devtools" in the
sentence "In the devltools, go to **Console** tab and run the following code:"
so the line reads "In the devtools, go to **Console** tab and run the following
code:"; update the string in the document content (the sentence containing
"devltools") to fix the typo.
---
Nitpick comments:
In `@src/content/docs/developer-tools/guides/chrome-extension.mdx`:
- Around line 110-113: Update the manifest example's host_permissions entry to
clarify regional and custom domains: in the documentation around the
"host_permissions" example that currently shows "https://*.kinde.com/*" and
"https://*.au.kinde.com/*", add a short note telling users to include other
regional domains (e.g., EU/US subdomains) and any custom domains they use, and
reference the existing troubleshooting section that instructs adding custom
domains so readers know to add their own host_permissions when needed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 47fcef04-ecf6-47bc-ac5f-8ed656e2d0d5
📒 Files selected for processing (1)
src/content/docs/developer-tools/guides/chrome-extension.mdx
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
src/content/docs/developer-tools/guides/chrome-extension.mdx (5)
118-138:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse the exact Kinde host in
host_permissions.The setup path already allows a custom domain, but this manifest example only whitelists
*.kinde.com/*.au.kinde.com. Readers who setPLASMO_PUBLIC_KINDE_DOMAINto a custom host will copy this config and hit token-exchange/CORS failures until they reach troubleshooting, and the wildcard is broader than the extension needs. Document this here as “use the same exact Kinde domain you put in.env.”Suggested doc tweak
- "host_permissions": [ - "https://*.kinde.com/*", - "https://*.au.kinde.com/*" - ] + "host_permissions": [ + "https://your-kinde-domain.example/*" + ]-The `host_permissions` are required so the background service worker can make cross-origin requests to Kinde's token endpoint without being blocked by CORS. +The `host_permissions` entry must match the exact Kinde domain your extension uses in `.env` (including a custom domain, if you have one). This lets the background service worker call Kinde's token endpoint without CORS failures.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/content/docs/developer-tools/guides/chrome-extension.mdx` around lines 118 - 138, Update the manifest example in the package.json snippet so the host_permissions entry uses the exact Kinde domain that readers set in their environment (the PLASMO_PUBLIC_KINDE_DOMAIN value) rather than broad wildcards; specifically, change the explanatory text around the "manifest" / "host_permissions" example to instruct readers to copy the exact host they configured in their .env (e.g., use the exact Kinde host used by PLASMO_PUBLIC_KINDE_DOMAIN) to avoid CORS token-exchange failures and to remove/avoid overly permissive wildcards like "*.kinde.com".
1483-1490:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDerive JWKS from the configured issuer, not a fixed
.kinde.comhost.The rest of the guide supports AU domains and custom domains, but this section tells readers to validate against
https://<your-subdomain>.kinde.com/.well-known/jwks. That points those deployments at the wrong key set. Phrase it as “append/.well-known/jwksto the same Kinde domain/issuer you configured for the extension.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/content/docs/developer-tools/guides/chrome-extension.mdx` around lines 1483 - 1490, Replace the hardcoded example URL "https://<your-subdomain>.kinde.com/.well-known/jwks" with guidance to derive the JWKS URL from the configured Kinde issuer/domain for the extension; instruct readers to append "/.well-known/jwks" to the same issuer/domain they configured (rather than assuming ".kinde.com") and update the surrounding sentence to mention support for AU and custom domains and using a JWKS-capable JWT library (e.g., "jose") to verify signature, expiry, and audience.
726-736:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRestore
=padding before callingatobindecodeJwt
decodeJwt()converts base64url → base64 but never re-adds the=padding thatatobexpects. Since JWT base64url omits trailing=characters, decoding can throw (or fail) for valid tokens whose segment length isn’t a multiple of 4.Suggested fix
export function decodeJwt(token: string): Record<string, unknown> { try { const base64Url = token.split(".")[1] - const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/") + const base64 = base64Url + .replace(/-/g, "+") + .replace(/_/g, "/") + .padEnd(Math.ceil(base64Url.length / 4) * 4, "=") const jsonPayload = decodeURIComponent( atob(base64) .split("") .map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)) .join(""), ) return JSON.parse(jsonPayload)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/content/docs/developer-tools/guides/chrome-extension.mdx` around lines 726 - 736, The decodeJwt function is missing re-addition of '=' padding before calling atob; update the logic in decodeJwt (using the base64 variable derived from base64Url) to compute required padding ((4 - (base64.length % 4)) % 4) and append that many '=' characters to base64 prior to calling atob so base64 length is a multiple of 4, then proceed to build jsonPayload and JSON.parse as before; modify the code around the base64 and atob usage in decodeJwt to insert this padding step.
1455-1470:⚠️ Potential issue | 🟠 Major | ⚡ Quick winNormalize
options.headerswithHeadersbefore settingAuthorization.
fetchRequestInit.headersacceptsHeadersInit(aHeadersinstance, a plain object, or an array of[name, value]tuples). Spreadingoptions.headersinto an object literal can silently drop/garble the caller-provided values (e.g., spreading aHeadersinstance yields no enumerable header entries; spreading tuple arrays produces numeric keys like{"0": [...]}), so this helper may send incorrect headers.Suggested fix
export async function fetchWithAuth( url: string, options: RequestInit = {}, ): Promise<Response> { const state = await getAuthState() if (!state.isAuthenticated || !state.accessToken) { throw new Error("Not authenticated") } + const headers = new Headers(options.headers) + headers.set("Authorization", `Bearer ${state.accessToken}`) + return fetch(url, { ...options, - headers: { - ...options.headers, - Authorization: `Bearer ${state.accessToken}`, - }, + headers, }) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/content/docs/developer-tools/guides/chrome-extension.mdx` around lines 1455 - 1470, The fetchWithAuth helper currently spreads options.headers into an object which can drop or corrupt headers when callers pass a Headers instance or header tuples; change fetchWithAuth to normalize headers by creating a new Headers from options.headers (e.g., new Headers(options.headers)), call headers.set("Authorization", `Bearer ${state.accessToken}`) on that Headers instance, and pass that Headers instance as the headers property in the fetch call so Authorization is added reliably without mutating the caller's input; reference the fetchWithAuth function and getAuthState to locate where to apply this change.
799-807:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFix login() error handling: don’t swallow all
chrome.runtime.sendMessagefailures
- In
src/content/docs/developer-tools/guides/chrome-extension.mdxthecatch { return }inlogin()(and the same pattern in thelogin(orgCode?: string)overload) suppresses every message error, masking real background/listener failures instead of only the expected macOS popup-close/port-closed scenario.- Re-throw everything except the specific “message port/channel closed before response” case.
Suggested fix
- } catch { - // Popup closed before background responded (expected on macOS). - return + } catch (err) { + const message = err instanceof Error ? err.message : String(err) + if ( + message.includes("message port closed") || + message.includes("message channel closed") + ) { + // Popup closed before background responded (expected on macOS). + return + } + throw err }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/content/docs/developer-tools/guides/chrome-extension.mdx` around lines 799 - 807, The catch in login() (and its overload login(orgCode?: string)) currently swallows all errors from chrome.runtime.sendMessage; change it to only ignore the specific "message port/channel closed before response" error and re-throw any other failures. Concretely, catch the thrown error as e, inspect e.message (or e.toString()) for the known Chrome message like "The message port closed before a response was received" or "Could not establish connection. Receiving end does not exist.", return silently only for those cases, and otherwise re-throw the error so real background/listener failures surface.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/content/docs/developer-tools/guides/chrome-extension.mdx`:
- Around line 118-138: Update the manifest example in the package.json snippet
so the host_permissions entry uses the exact Kinde domain that readers set in
their environment (the PLASMO_PUBLIC_KINDE_DOMAIN value) rather than broad
wildcards; specifically, change the explanatory text around the "manifest" /
"host_permissions" example to instruct readers to copy the exact host they
configured in their .env (e.g., use the exact Kinde host used by
PLASMO_PUBLIC_KINDE_DOMAIN) to avoid CORS token-exchange failures and to
remove/avoid overly permissive wildcards like "*.kinde.com".
- Around line 1483-1490: Replace the hardcoded example URL
"https://<your-subdomain>.kinde.com/.well-known/jwks" with guidance to derive
the JWKS URL from the configured Kinde issuer/domain for the extension; instruct
readers to append "/.well-known/jwks" to the same issuer/domain they configured
(rather than assuming ".kinde.com") and update the surrounding sentence to
mention support for AU and custom domains and using a JWKS-capable JWT library
(e.g., "jose") to verify signature, expiry, and audience.
- Around line 726-736: The decodeJwt function is missing re-addition of '='
padding before calling atob; update the logic in decodeJwt (using the base64
variable derived from base64Url) to compute required padding ((4 -
(base64.length % 4)) % 4) and append that many '=' characters to base64 prior to
calling atob so base64 length is a multiple of 4, then proceed to build
jsonPayload and JSON.parse as before; modify the code around the base64 and atob
usage in decodeJwt to insert this padding step.
- Around line 1455-1470: The fetchWithAuth helper currently spreads
options.headers into an object which can drop or corrupt headers when callers
pass a Headers instance or header tuples; change fetchWithAuth to normalize
headers by creating a new Headers from options.headers (e.g., new
Headers(options.headers)), call headers.set("Authorization", `Bearer
${state.accessToken}`) on that Headers instance, and pass that Headers instance
as the headers property in the fetch call so Authorization is added reliably
without mutating the caller's input; reference the fetchWithAuth function and
getAuthState to locate where to apply this change.
- Around line 799-807: The catch in login() (and its overload login(orgCode?:
string)) currently swallows all errors from chrome.runtime.sendMessage; change
it to only ignore the specific "message port/channel closed before response"
error and re-throw any other failures. Concretely, catch the thrown error as e,
inspect e.message (or e.toString()) for the known Chrome message like "The
message port closed before a response was received" or "Could not establish
connection. Receiving end does not exist.", return silently only for those
cases, and otherwise re-throw the error so real background/listener failures
surface.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: a4cc5cb9-435c-4844-bd8b-b875cdea285f
📒 Files selected for processing (1)
src/content/docs/developer-tools/guides/chrome-extension.mdx
shafaladhikari
left a comment
There was a problem hiding this comment.
Good work. Please have a look at the comments where few changes can be done for better docs.
| }, | ||
| "manifest": { | ||
| "permissions": ["identity", "storage"], | ||
| "host_permissions": [ |
There was a problem hiding this comment.
Could the setup example use the exact Kinde domain from .env rather than *.kinde.com wildcards? Custom-domain users will hit CORS until they reach troubleshooting otherwise.
|
|
||
| ```ts | ||
| // lib/jwt.ts | ||
| export function decodeJwt(token: string): Record<string, unknown> { |
There was a problem hiding this comment.
The sample decodeJwt is missing base64 padding before atob(). Some valid JWTs will fail to decode — worth adding .padEnd(...).
|
|
||
| ### `lib/kinde.ts` | ||
|
|
||
| Core auth helpers used by the popup. `login()` delegates the interactive OAuth flow to the background via `KINDE_LOGIN`. `getAuthState()` automatically attempts a silent re-authentication via `KINDE_SILENT_AUTH` when the stored token is expired — if the user's Kinde browser session is still alive, fresh tokens are returned with no user prompt. If the session has also expired, the user is prompted to sign in again. |
There was a problem hiding this comment.
KINDE_SILENT_AUTH re-runs the authorization code flow with interactive: false — it's session-based silent re-auth, not a refresh-token grant. Refresh tokens are stored after exchangeAuthCode but never read for renewal. Consider renaming "silent token renewal" to "silent re-authentication" in the doc and noting that it only works while the Kinde SSO session is still active.
| response = await chrome.runtime.sendMessage<LoginMessage, LoginResponse>({ | ||
| type: "KINDE_LOGIN", | ||
| }) | ||
| } catch { |
There was a problem hiding this comment.
The login() sample uses a bare catch { return }, which silently ignores every chrome.runtime.sendMessage failure — not just the expected macOS popup-close case.
On macOS, when the OAuth window opens, Chrome often tears down the popup before the background worker responds. That produces errors like:
"The message port closed before a response was received."
"Could not establish connection. Receiving end does not exist."
Those are expected and safe to ignore. But other failures — a missing background listener, a service worker that failed to start, a misconfigured manifest — get swallowed too, so developers copying this code won't see real bugs during setup.
Suggest narrowing the catch to only those known popup-lifecycle errors and re-throwing everything else:
} catch (err) {
const message = err instanceof Error ? err.message : String(err)
if (
message.includes("message port closed") ||
message.includes("message channel closed") ||
message.includes("Receiving end does not exist")
) {
// Popup closed before background responded (expected on macOS).
return
}
throw err
}The same pattern appears in the Organizations section (login(orgCode?) around line 1430) — worth applying there too for consistency.
|
|
||
| return fetch(url, { | ||
| ...options, | ||
| headers: { |
There was a problem hiding this comment.
The fetchWithAuth helper spreads options.headers into a plain object:
headers: {
...options.headers,
Authorization: `Bearer ${state.accessToken}`,
}That works when callers pass a simple object like { "Content-Type": "application/json" }, but fetch's headers option accepts HeadersInit — which can also be a Headers instance or an array of [name, value] tuples.
Spreading a Headers object yields no enumerable entries, so caller-provided headers are dropped. Spreading a tuple array produces numeric keys ({ "0": ["Content-Type", "application/json"] }), which fetch won't interpret correctly. In both cases, Authorization may be the only header actually sent.
Since this is copy-paste sample code, it's worth normalizing headers with the Headers constructor before setting Authorization:
export async function fetchWithAuth(
url: string,
options: RequestInit = {},
): Promise<Response> {
const state = await getAuthState()
if (!state.isAuthenticated || !state.accessToken) {
throw new Error("Not authenticated")
}
const headers = new Headers(options.headers)
headers.set("Authorization", `Bearer ${state.accessToken}`)
return fetch(url, {
...options,
headers,
})
}This handles plain objects, Headers instances, and tuple arrays reliably, and avoids mutating the caller's input.
|
Hi @shafaladhikari thanks for this detailed and helpful review. learned a lot. I made some improvements; kindly have a look. |
shafaladhikari
left a comment
There was a problem hiding this comment.
Great. Everything has been addressed and looks good to me.
Based on @DanielRivers's notes: this PR creates a new doc to integrate Kinde auth in a Chrome extension. The doc covers quick setup with PKCE auth, setup steps for development and production. It also covers using Kinde core features in the extension.
Summary by CodeRabbit
Summary by CodeRabbit