Skip to content

chore(web): Improved security settings#1303

Merged
brendan-kellam merged 15 commits into
mainfrom
bkellam/security-settings
Jun 12, 2026
Merged

chore(web): Improved security settings#1303
brendan-kellam merged 15 commits into
mainfrom
bkellam/security-settings

Conversation

@brendan-kellam

@brendan-kellam brendan-kellam commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR does a couple of things:

  1. Primarily, it redesigns the security settings page (previously the access page) to include some new settings & views, namely:
    a. setting to configure if email & password login is enabled.
    b. setting to configure if email code login is enabled.
    c. list to view configured SSO providers.

  2. In order to achieve (a) and (b), I've added isCredentialsLoginEnabled and isEmailCodeLoginEnabled fields to the database. Additionally, I moved the isAnonymousAccessEnabled setting from the org.metadata JSON blob into a dedicated field. The migration handles back-compat.

  3. The 4 environment variables that can control these settings (REQUIRE_APPROVAL_NEW_MEMBERS, AUTH_CREDENTIALS_LOGIN_ENABLED, AUTH_EMAIL_CODE_LOGIN_ENABLED, and FORCE_ENABLE_ANONYMOUS_ACCESS) have now been marked deprecated, but will still be respected for the current major version.

TODO:

  • Fix email code login
  • Run through different migration scenarios
  • Delete the metadata field from Org (?)
  • Update docs

Screenshots

Security page (w/o entitlement):
image

Security page (w/ entitlement):
image

SSO (w/o configured providers):
image

SSO (w/ configured providers):
image

Email login (w/o configured SMTP server):
image

Summary by CodeRabbit

  • New Features

    • Settings → Security page with centralized toggles for Email & password, Email-code, Anonymous access, Invite links, and Require approval
    • Onboarding step components and improved invite-link UX; new login error page and email verification flow
    • In-app upsell for Single Sign-On
  • Documentation

    • Updated auth/provider and environment-variable docs to reflect UI-controlled settings and disabling constraints
  • Deprecations

    • Several auth-related env vars deprecated in favor of UI/org-level settings
  • Other

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR migrates org auth/access flags into DB fields, adds shared helpers, init sync, server actions and UI for security settings, updates auth/provider wiring and entitlements, refactors onboarding and verification flows, and removes legacy metadata helpers and components.

Changes

Org-Level Auth Settings & Access Control

Layer / File(s) Summary
Database Schema & Migration
packages/db/prisma/migrations/20260611195453_add_org_access_settings/migration.sql, packages/db/prisma/schema.prisma
Adds isCredentialsLoginEnabled, isEmailCodeLoginEnabled, isAnonymousAccessEnabled to Org, with defaults and backfill from legacy metadata.
Environment Variable Deprecation & Sync
packages/shared/src/env.server.ts, packages/web/src/initialize.ts
Moves deprecated auth env vars to a Deprecated block as optional and syncs explicitly-set deprecated env vars into org DB fields on init.
Shared Feature-Flag Helpers
packages/shared/src/utils.ts, packages/shared/src/index.server.ts
Adds isCredentialsLoginEnabled, isEmailCodeLoginEnabled, isMemberApprovalRequired helpers and re-exports them.
Auth Provider Integration
packages/web/src/auth.ts
getProviders() consults org-scoped helpers and org record (plus SMTP/from-address) to decide whether credentials and email-code providers are enabled; sign-in token-update gating tightened; sign-in errors route set to /login/error.
Layout & Invite Flow
packages/web/src/app/(app)/layout.tsx, packages/web/src/app/invite/actions.ts
Replaces direct org.memberApprovalRequired checks with isMemberApprovalRequired(org).
Settings Card Component Enhancements
packages/web/src/app/(app)/settings/components/settingsCard.tsx
SettingsCard/BasicSettingsCard accept optional className, optional description, and footer slot.
Security Settings Server Actions
packages/web/src/app/(app)/settings/security/actions.ts
Adds server-actions for member-approval, credentials login, email-code login, anonymous access, and invite-link toggles with env gating, provider validation, entitlement checks, and OWNER enforcement.
Security Settings UI Cards
packages/web/src/app/(app)/settings/security/components/*.tsx
Adds client-side cards for member approval, credentials login, email-code login, anonymous access, invite links, identity-provider display, and SSO upsell (with toasts, loading, and clipboard UI).
Security Settings Page
packages/web/src/app/(app)/settings/security/page.tsx
New authenticated /settings/security page that fetches org state, entitlements, and configured SSO providers and renders the security sections with conditional upsell.
Entitlements & Middleware Migration
packages/web/src/lib/entitlements.ts, packages/web/src/middleware/withAuth.ts, tests
Anonymous-access entitlement now reads org.isAnonymousAccessEnabled; FORCE_ENABLE_ANONYMOUS_ACCESS override behavior updated; middleware and tests adjusted accordingly.
Error Codes & Analytics
packages/web/src/lib/errorCodes.ts, packages/web/src/lib/posthogEvents.ts
Adds error codes for env-controlled settings and extends UpsellSource with 'sso_settings'.
Onboarding Refactor
packages/web/src/app/onboard/components/*, packages/web/src/app/onboard/page.tsx
Extracts WelcomeStep, OwnerSignupStep, and AccessSettingsStep, reusing new settings cards in the onboarding flow.
Settings Navigation & UI Polish
packages/web/src/app/(app)/settings/layout.tsx, packages/web/src/app/(app)/@sidebar/components/upgradeBadge.tsx
Renames "Access" nav to "Security" and updates upgrade badge styling.
Legacy Component Removal
packages/web/src/app/components/*, packages/web/src/actions.ts, packages/web/src/lib/utils.ts, packages/web/src/types.ts
Removes old access components, legacy server actions, getOrgMetadata, and OrgMetadata type.
Documentation Updates
docs/docs/configuration/environment-variables.mdx, docs/docs/configuration/auth/providers.mdx, docs/docs/configuration/config-file.mdx, .env.development
Removes deprecated env vars from docs, updates auth provider docs to reflect UI control and deprecation, and cleans up commented example in .env.development.
Test Fixture Updates
packages/web/src/__mocks__/prisma.ts, packages/web/src/lib/entitlements.test.ts, packages/web/src/middleware/withAuth.test.ts
Updates mocks and tests to use the new org-level boolean fields for access flags.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • sourcebot-dev/sourcebot#1071: Refactors org-security/action wiring; touches member-approval/invite/anonymous-access flows related to these changes.
  • sourcebot-dev/sourcebot#468: Reintroduces the experimental GitHub self-serve repository action that this PR removed from packages/web/src/actions.ts.
  • sourcebot-dev/sourcebot#376: Onboarding/access behavior changes related to member-approval and invite-link logic updated here.

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main change: redesigning and improving the security settings page with new toggles and authentication controls.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bkellam/security-settings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mintlify

mintlify Bot commented Jun 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
sourcebot 🟢 Ready View Preview Jun 11, 2026, 10:17 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@brendan-kellam brendan-kellam marked this pull request as ready for review June 12, 2026 00:09
@github-actions

This comment has been minimized.

@brendan-kellam brendan-kellam changed the title [wip] Security settings chore(web): Improved security settings Jun 12, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/app/onboard/page.tsx (1)

69-71: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Clamp and validate step before indexing steps.

parseInt() returns NaN for inputs like ?step=abc, and the authenticated branch never caps large values. That makes steps[currentStep] undefined and crashes the render a few lines later when currentStepData.title / subtitle are read.

🐛 Suggested fix
-    const stepParam = searchParams?.step ? parseInt(searchParams.step) : 0;
-    const currentStep = session?.user ? Math.max(2, stepParam) : Math.max(0, Math.min(stepParam, 1));
+    const parsedStep = searchParams?.step ? Number.parseInt(searchParams.step, 10) : 0;
+    const requestedStep = Number.isFinite(parsedStep) ? parsedStep : 0;
@@
-    const currentStepData = steps[currentStep]
+    const unclampedStep = session?.user
+        ? Math.max(2, requestedStep)
+        : Math.max(0, Math.min(requestedStep, 1))
+    const currentStep = Math.min(unclampedStep, steps.length - 1)
+    const currentStepData = steps[currentStep]

Also applies to: 141-143

🤖 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 `@packages/web/src/app/onboard/page.tsx` around lines 69 - 71, Validate and
clamp the parsed step value before using it to index steps: replace raw parseInt
usage with a safe integer parse that treats NaN as 0 for stepParam (e.g., const
stepParam = Number.isInteger(parsed) ? parsed : 0), then compute currentStep by
clamping into the valid index range of the steps array (0 to steps.length - 1);
update both occurrences that set currentStep (the unauthenticated and
authenticated branches) so the authenticated branch still enforces a minimum
(e.g., Math.max(2, clampedStep)) but also applies Math.min against steps.length
- 1 to avoid out-of-bounds access when reading steps[currentStep] (reference
symbols: stepParam, currentStep, steps).
🧹 Nitpick comments (3)
packages/web/src/lib/entitlements.ts (1)

44-61: ⚡ Quick win

Let callers pass a preloaded org into isAnonymousAccessEnabled().

This helper now always re-queries org, which adds a second DB read on paths like withOptionalAuth() that already loaded the org in getAuthContext(). An overload or a small pure resolver that accepts Org would keep the env/license logic centralized without adding extra I/O to public-request hot paths.

🤖 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 `@packages/web/src/lib/entitlements.ts` around lines 44 - 61, Modify
isAnonymousAccessEnabled to accept an optional preloaded Org object (e.g., add a
parameter org?: Org or create an overload) and use that Org if provided instead
of always re-querying the database; only call __unsafePrisma.org.findUnique when
the optional org argument is undefined. Preserve the existing
env.FORCE_ENABLE_ANONYMOUS_ACCESS and isAnonymousAccessAvailable() checks and
return semantics, and update hot-path callers like
getAuthContext()/withOptionalAuth to pass their loaded org into
isAnonymousAccessEnabled to avoid the extra DB read.
packages/web/src/app/onboard/page.tsx (1)

168-179: ⚡ Quick win

Use cn() for these conditional class lists.

These branches still build Tailwind class strings with template literal interpolation. Please move them to cn(...) to match the repo TSX rule and keep the variants easier to scan.

♻️ Suggested cleanup
+import { cn } from "`@/lib/utils`";
@@
-                                                            <div
-                                                                className={`absolute top-10 left-1/2 transform -translate-x-1/2 w-0.5 h-8 transition-all duration-300 ${index < currentStep ? "bg-primary" : "bg-border"
-                                                                    }`}
-                                                            />
+                                                            <div
+                                                                className={cn(
+                                                                    "absolute top-10 left-1/2 transform -translate-x-1/2 w-0.5 h-8 transition-all duration-300",
+                                                                    index < currentStep ? "bg-primary" : "bg-border"
+                                                                )}
+                                                            />
@@
-                                                        <div
-                                                            className={`relative z-10 w-10 h-10 rounded-full border-2 flex items-center justify-center font-semibold text-sm transition-all duration-300 ${index < currentStep
-                                                                    ? "bg-primary border-primary text-primary-foreground"
-                                                                    : index === currentStep
-                                                                        ? "bg-primary border-primary text-primary-foreground scale-110 shadow-lg"
-                                                                        : "bg-background border-border text-muted-foreground"
-                                                                }`}
-                                                        >
+                                                        <div
+                                                            className={cn(
+                                                                "relative z-10 w-10 h-10 rounded-full border-2 flex items-center justify-center font-semibold text-sm transition-all duration-300",
+                                                                index < currentStep
+                                                                    ? "bg-primary border-primary text-primary-foreground"
+                                                                    : index === currentStep
+                                                                        ? "bg-primary border-primary text-primary-foreground scale-110 shadow-lg"
+                                                                        : "bg-background border-border text-muted-foreground"
+                                                            )}
+                                                        >
@@
-                                                        <div className={`font-medium text-sm transition-all duration-200 ${index <= currentStep ? "text-foreground" : "text-muted-foreground"
-                                                            }`}>
+                                                        <div
+                                                            className={cn(
+                                                                "font-medium text-sm transition-all duration-200",
+                                                                index <= currentStep ? "text-foreground" : "text-muted-foreground"
+                                                            )}
+                                                        >

As per coding guidelines, use cn() from @/lib/utils for conditional classNames instead of template literal interpolation.

Also applies to: 191-192

🤖 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 `@packages/web/src/app/onboard/page.tsx` around lines 168 - 179, Replace the
template-literal Tailwind class strings for the vertical line and the circle
div's className with calls to the cn(...) helper from '`@/lib/utils`' (e.g., the
className prop building inside the element rendering the absolute top-10
left-1/2 w-0.5 h-8 line and the div that renders the circle with relative z-10
w-10 h-10 ...). Import cn if missing, convert the conditional expressions (index
< currentStep, index === currentStep) into boolean arguments or ternary branches
inside cn so each variant becomes a separate class argument rather than a
template string, and make the same change for the other occurrences mentioned
around the 191-192 area.

Source: Coding guidelines

packages/web/src/app/(app)/settings/security/components/inviteLinkEnabledSettingsCard.tsx (1)

53-59: ⚡ Quick win

Align this TSX with the repo style rules.

Line 53 still uses a single-line if without braces, and Line 96 uses CSS variable syntax for a color class. Please switch that guard to a braced block and use the matching Tailwind token class instead.

♻️ Suggested cleanup
 const handleCopy = async () => {
-    if (!inviteLink) return
+    if (!inviteLink) {
+        return
+    }

     try {
         await navigator.clipboard.writeText(inviteLink)
         setCopied(true)
         setTimeout(() => setCopied(false), 2000)
@@
                                 >
                                     {copied ? (
-                                        <Check className="h-4 w-4 text-[var(--chart-2)]" />
+                                        <Check className="h-4 w-4 text-chart-2" />
                                     ) : (
                                         <Copy className="h-4 w-4" />
                                     )}
                                 </Button>

As per coding guidelines, always use curly braces for if statements, with the body on a new line, and use Tailwind color classes directly instead of CSS variable syntax.

Also applies to: 95-98

🤖 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
`@packages/web/src/app/`(app)/settings/security/components/inviteLinkEnabledSettingsCard.tsx
around lines 53 - 59, Change the single-line guard "if (!inviteLink) return" in
inviteLinkEnabledSettingsCard.tsx to a braced block with the body on a new line
(e.g., if (!inviteLink) { return; }) so the early-return follows repo style;
also replace the CSS variable color class used in the component's className (the
token using CSS var(...) around the color) with the corresponding Tailwind token
class (e.g., the repo's standard text-<token> utility) so the color uses
Tailwind tokens instead of CSS variable syntax; ensure this touches the same JSX
that calls navigator.clipboard.writeText and setCopied so formatting remains
consistent.

Source: Coding guidelines

🤖 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 `@docs/docs/configuration/auth/providers.mdx`:
- Line 14: Update the navigation text in the documentation: replace the phrase
"Settings → Access" with "Settings → Security" in the sentence that currently
reads "You can toggle it from **Settings → Access** using the **Email login**
setting" so the doc matches the renamed menu entry.

In `@packages/web/src/app/`(app)/settings/security/actions.ts:
- Around line 49-59: The guard that prevents disabling email login only checks
configured providers via getProviders() and hasAlternativeLoginMethod, but
ignores per-organization flags org.isEmailCodeLoginEnabled and
org.isCredentialsLoginEnabled; update the logic in the same block (and the
analogous block around lines 85-95) to treat a provider as "available" only if
it is both configured and enabled for the org—i.e., when computing
hasAlternativeLoginMethod include checks for org.isCredentialsLoginEnabled and
org.isEmailCodeLoginEnabled (and any provider.type !== "credentials SSO" logic)
so the function that currently uses getProviders() and hasAlternativeLoginMethod
refuses to disable the last actually-enabled non-SSO login path for that org.

In
`@packages/web/src/app/`(app)/settings/security/components/emailCodeLoginEnabledSettingsCard.tsx:
- Around line 73-76: The Switch is currently disabled whenever
isEmailServiceConfigured is false, which prevents turning off email-code login
when it's already enabled; update the disabled prop on the Switch (the JSX using
checked={enabled} and onCheckedChange={handleToggle}) to only disable when
loading or when the service is not configured AND the feature is not currently
enabled (e.g. disabled={isLoading || (!isEmailServiceConfigured && !enabled)}),
so users can still toggle off an already-enabled setting.

In
`@packages/web/src/app/`(app)/settings/security/components/identityProviderSettingsCard.tsx:
- Around line 20-25: The Image usage inside identityProviderSettingsCard is
missing intrinsic dimensions so Next.js can't infer size from
providerInfo.icon.src; update the Image call (the JSX that renders when
providerInfo.icon is truthy) to include explicit width and height props (or
switch to layout="fill"/fill with a positioned parent) based on the known icon
dimensions on AuthProviderInfo.icon, e.g., pass numeric width and height or use
fill and ensure the container has relative positioning; modify the JSX where
providerInfo.icon, Image and name are referenced to add these props.

In
`@packages/web/src/app/`(app)/settings/security/components/inviteLinkEnabledSettingsCard.tsx:
- Around line 88-100: The copy Button in inviteLinkEnabledSettingsCard.tsx is an
icon-only control and needs an accessible name; update the Button element (the
one with onClick={handleCopy}, disabled={!inviteLink} and showing copied ?
<Check/> : <Copy/>) to include an aria-label (e.g., aria-label="Copy invite
link") or add visually hidden text; ensure the label reflects its action and
still works when disabled and when the copied state changes.

In `@packages/web/src/auth.ts`:
- Around line 75-79: The code calls __unsafePrisma.org.findUnique and then
passes org! into helpers (e.g., isEmailCodeLoginEnabled) inside getProviders(),
which crashes when the single-tenant org is missing; guard the missing-org path
before evaluating those helpers: after retrieving org from
__unsafePrisma.org.findUnique, check for null and if null use the schema
defaults (credentials = true, email-code = false) or respect env overrides
(e.g., EMAIL_FROM_ADDRESS, getSMTPConnectionURL) instead of dereferencing org;
update all places in getProviders() that use org! (and the other call site that
passes org into isEmailCodeLoginEnabled) to branch on org presence and only call
org-reading helpers when org is non-null so provider resolution falls back
safely.

---

Outside diff comments:
In `@packages/web/src/app/onboard/page.tsx`:
- Around line 69-71: Validate and clamp the parsed step value before using it to
index steps: replace raw parseInt usage with a safe integer parse that treats
NaN as 0 for stepParam (e.g., const stepParam = Number.isInteger(parsed) ?
parsed : 0), then compute currentStep by clamping into the valid index range of
the steps array (0 to steps.length - 1); update both occurrences that set
currentStep (the unauthenticated and authenticated branches) so the
authenticated branch still enforces a minimum (e.g., Math.max(2, clampedStep))
but also applies Math.min against steps.length - 1 to avoid out-of-bounds access
when reading steps[currentStep] (reference symbols: stepParam, currentStep,
steps).

---

Nitpick comments:
In
`@packages/web/src/app/`(app)/settings/security/components/inviteLinkEnabledSettingsCard.tsx:
- Around line 53-59: Change the single-line guard "if (!inviteLink) return" in
inviteLinkEnabledSettingsCard.tsx to a braced block with the body on a new line
(e.g., if (!inviteLink) { return; }) so the early-return follows repo style;
also replace the CSS variable color class used in the component's className (the
token using CSS var(...) around the color) with the corresponding Tailwind token
class (e.g., the repo's standard text-<token> utility) so the color uses
Tailwind tokens instead of CSS variable syntax; ensure this touches the same JSX
that calls navigator.clipboard.writeText and setCopied so formatting remains
consistent.

In `@packages/web/src/app/onboard/page.tsx`:
- Around line 168-179: Replace the template-literal Tailwind class strings for
the vertical line and the circle div's className with calls to the cn(...)
helper from '`@/lib/utils`' (e.g., the className prop building inside the element
rendering the absolute top-10 left-1/2 w-0.5 h-8 line and the div that renders
the circle with relative z-10 w-10 h-10 ...). Import cn if missing, convert the
conditional expressions (index < currentStep, index === currentStep) into
boolean arguments or ternary branches inside cn so each variant becomes a
separate class argument rather than a template string, and make the same change
for the other occurrences mentioned around the 191-192 area.

In `@packages/web/src/lib/entitlements.ts`:
- Around line 44-61: Modify isAnonymousAccessEnabled to accept an optional
preloaded Org object (e.g., add a parameter org?: Org or create an overload) and
use that Org if provided instead of always re-querying the database; only call
__unsafePrisma.org.findUnique when the optional org argument is undefined.
Preserve the existing env.FORCE_ENABLE_ANONYMOUS_ACCESS and
isAnonymousAccessAvailable() checks and return semantics, and update hot-path
callers like getAuthContext()/withOptionalAuth to pass their loaded org into
isAnonymousAccessEnabled to avoid the extra DB read.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5f28f52d-3369-4ba3-a39e-6a722d084eeb

📥 Commits

Reviewing files that changed from the base of the PR and between 1387c46 and 04f03a2.

📒 Files selected for processing (45)
  • .env.development
  • docs/docs/configuration/auth/providers.mdx
  • docs/docs/configuration/config-file.mdx
  • docs/docs/configuration/environment-variables.mdx
  • packages/db/prisma/migrations/20260611195453_add_org_access_settings/migration.sql
  • packages/db/prisma/schema.prisma
  • packages/shared/src/env.server.ts
  • packages/shared/src/index.server.ts
  • packages/shared/src/utils.ts
  • packages/web/src/__mocks__/prisma.ts
  • packages/web/src/actions.ts
  • packages/web/src/app/(app)/@sidebar/components/upgradeBadge.tsx
  • packages/web/src/app/(app)/layout.tsx
  • packages/web/src/app/(app)/settings/access/page.tsx
  • packages/web/src/app/(app)/settings/components/settingsCard.tsx
  • packages/web/src/app/(app)/settings/layout.tsx
  • packages/web/src/app/(app)/settings/security/actions.ts
  • packages/web/src/app/(app)/settings/security/components/anonymousAccessEnabledSettingsCard.tsx
  • packages/web/src/app/(app)/settings/security/components/credentialsLoginEnabledSettingsCard.tsx
  • packages/web/src/app/(app)/settings/security/components/emailCodeLoginEnabledSettingsCard.tsx
  • packages/web/src/app/(app)/settings/security/components/identityProviderSettingsCard.tsx
  • packages/web/src/app/(app)/settings/security/components/identityProviderUpsellCard.tsx
  • packages/web/src/app/(app)/settings/security/components/inviteLinkEnabledSettingsCard.tsx
  • packages/web/src/app/(app)/settings/security/components/memberApprovalRequiredSettingsCard.tsx
  • packages/web/src/app/(app)/settings/security/page.tsx
  • packages/web/src/app/components/anonymousAccessToggle.tsx
  • packages/web/src/app/components/inviteLinkToggle.tsx
  • packages/web/src/app/components/memberApprovalRequiredToggle.tsx
  • packages/web/src/app/components/organizationAccessSettings.tsx
  • packages/web/src/app/components/organizationAccessSettingsWrapper.tsx
  • packages/web/src/app/invite/actions.ts
  • packages/web/src/app/onboard/components/accessSettingsStep.tsx
  • packages/web/src/app/onboard/components/ownerSignupStep.tsx
  • packages/web/src/app/onboard/components/welcomeStep.tsx
  • packages/web/src/app/onboard/page.tsx
  • packages/web/src/auth.ts
  • packages/web/src/initialize.ts
  • packages/web/src/lib/entitlements.test.ts
  • packages/web/src/lib/entitlements.ts
  • packages/web/src/lib/errorCodes.ts
  • packages/web/src/lib/posthogEvents.ts
  • packages/web/src/lib/utils.ts
  • packages/web/src/middleware/withAuth.test.ts
  • packages/web/src/middleware/withAuth.ts
  • packages/web/src/types.ts
💤 Files with no reviewable changes (10)
  • packages/web/src/app/components/anonymousAccessToggle.tsx
  • docs/docs/configuration/config-file.mdx
  • packages/web/src/app/components/inviteLinkToggle.tsx
  • packages/web/src/app/(app)/settings/access/page.tsx
  • packages/web/src/app/components/organizationAccessSettingsWrapper.tsx
  • packages/web/src/app/components/organizationAccessSettings.tsx
  • packages/web/src/app/components/memberApprovalRequiredToggle.tsx
  • .env.development
  • packages/web/src/types.ts
  • docs/docs/configuration/environment-variables.mdx

Comment thread docs/docs/configuration/auth/providers.mdx Outdated
Comment thread packages/web/src/app/(app)/settings/security/actions.ts
Comment thread packages/web/src/auth.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/web/src/app/login/verify/verifyForm.tsx (1)

3-6: 💤 Low value

Consolidate imports from the same module.

These four imports can be combined into a single import statement for better readability.

Suggested consolidation
-import { InputOTPSeparator } from "`@/components/ui/input-otp`"
-import { InputOTPGroup } from "`@/components/ui/input-otp`"
-import { InputOTPSlot } from "`@/components/ui/input-otp`"
-import { InputOTP } from "`@/components/ui/input-otp`"
+import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "`@/components/ui/input-otp`"
🤖 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 `@packages/web/src/app/login/verify/verifyForm.tsx` around lines 3 - 6,
Consolidate the four separate imports from the same module into a single import
statement: replace the individual imports of InputOTPSeparator, InputOTPGroup,
InputOTPSlot, and InputOTP with one combined import from
"`@/components/ui/input-otp`" (referencing the symbols InputOTPSeparator,
InputOTPGroup, InputOTPSlot, InputOTP) so the file imports are cleaner and
easier to maintain.
🤖 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 `@packages/web/src/app/login/verify/verifyForm.tsx`:
- Around line 49-54: The captureEvent call is causing a side effect during
render; remove the synchronous captureEvent("wa_login_verify_page_no_email", {})
from the render return path in verifyForm.tsx and instead invoke it inside a
useEffect that runs when email is falsy (e.g., useEffect(() => { if (!email)
captureEvent(...); }, [email])); keep returning the <Redirect to="/login" />
from render when !email, but ensure the useEffect dependency prevents duplicate
calls (and optionally guard for client-only execution if needed).

---

Nitpick comments:
In `@packages/web/src/app/login/verify/verifyForm.tsx`:
- Around line 3-6: Consolidate the four separate imports from the same module
into a single import statement: replace the individual imports of
InputOTPSeparator, InputOTPGroup, InputOTPSlot, and InputOTP with one combined
import from "`@/components/ui/input-otp`" (referencing the symbols
InputOTPSeparator, InputOTPGroup, InputOTPSlot, InputOTP) so the file imports
are cleaner and easier to maintain.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 41c1cc01-0e50-4fef-b65c-1972840c8f9d

📥 Commits

Reviewing files that changed from the base of the PR and between 04f03a2 and 69c9646.

📒 Files selected for processing (4)
  • packages/web/src/app/login/verify/page.tsx
  • packages/web/src/app/login/verify/verificationFailed.tsx
  • packages/web/src/app/login/verify/verifyForm.tsx
  • packages/web/src/auth.ts
💤 Files with no reviewable changes (1)
  • packages/web/src/app/login/verify/verificationFailed.tsx

Comment thread packages/web/src/app/login/verify/verifyForm.tsx
@brendan-kellam brendan-kellam merged commit a84e7a9 into main Jun 12, 2026
10 checks passed
@brendan-kellam brendan-kellam deleted the bkellam/security-settings branch June 12, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant