Skip to content

Add anonymous access option to core #385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 19, 2025
Merged

Add anonymous access option to core #385

merged 12 commits into from
Jul 19, 2025

Conversation

msukkari
Copy link
Contributor

@msukkari msukkari commented Jul 18, 2025

  • Adds an anonymous access option to core, allowing a Sourcebot instance to be accessed without needing to log in.

    • Note that deployments with an enterprise license cannot enable this option. If you're using an IAP please configure an IAP bridge. If your IAP isn't supported please reach out
  • Adds a toggle to control this in onboarding and in a new Access page in the settings

  • Also adds the FORCE_ENABLE_ANONYMOUS_ACCESS env var to force enable anonymous access

image

Summary by CodeRabbit

  • New Features

    • Introduced an "Anonymous Access" setting with UI controls and updated documentation.
    • Added FORCE_ENABLE_ANONYMOUS_ACCESS environment variable to enforce anonymous access.
    • Added onboarding and settings pages/components for managing access controls.
  • Improvements

    • Replaced all "public access" references with "anonymous access" across the app and docs.
    • Updated entitlement and access logic to use "anonymous-access" instead of "public-access".
    • Enhanced documentation structure and navigation for access settings and environment variables.
  • Bug Fixes

    • Fixed a syntax error on the repositories page preventing proper rendering.
  • Removals

    • Removed legacy "public access" configuration options, code, and related components.

@msukkari msukkari requested a review from brendan-kellam July 18, 2025 02:43
Copy link

coderabbitai bot commented Jul 18, 2025

"""

Walkthrough

This change removes the "public access" feature and replaces it with "anonymous access" throughout the codebase, schemas, configuration, and documentation. It renames entitlements, updates environment variables, and introduces new React components for managing anonymous access and member approval. Related logic, UI, and documentation are updated accordingly.

Changes

File(s) / Path(s) Change Summary
demo-site-config.json, schemas/v3/index.json, docs/snippets/schemas/v3/index.schema.mdx, packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/index.type.ts Removed enablePublicAccess property from config, schemas, and types; marked as deprecated and replaced with FORCE_ENABLE_ANONYMOUS_ACCESS env variable.
packages/backend/src/constants.ts Marked enablePublicAccess as deprecated in DEFAULT_SETTINGS with comment; value set to false.
packages/shared/src/entitlements.ts Renamed "public-access" entitlement to "anonymous-access" in all entitlements and plans.
packages/web/src/actions.ts Replaced public access logic with anonymous access; added getAnonymousAccessStatus and setAnonymousAccessStatus.
packages/web/src/app/[domain]/layout.tsx Replaced public access checks with anonymous access checks and entitlements.
packages/web/src/app/[domain]/repos/page.tsx Fixed missing closing brace in conditional rendering.
packages/web/src/app/[domain]/settings/access/page.tsx Added new Access Control settings page component.
packages/web/src/app/[domain]/settings/layout.tsx Added "Access" sidebar item for owners.
packages/web/src/app/[domain]/settings/members/page.tsx Removed member approval toggle UI and related invite link construction logic.
packages/web/src/app/components/anonymousAccessToggle.tsx Added new component for toggling anonymous access.
packages/web/src/app/components/memberApprovalRequiredToggle.tsx Added new component for toggling member approval requirement.
packages/web/src/app/components/organizationAccessSettings.tsx Added server component for organization access settings.
packages/web/src/app/components/organizationAccessSettingsWrapper.tsx Added wrapper component for access settings toggles.
packages/web/src/app/onboard/components/memberApprovalRequiredToggle.tsx Deleted old member approval toggle component.
packages/web/src/app/onboard/page.tsx Updated onboarding to use new access settings component and logic.
packages/web/src/ee/features/analytics/actions.ts, packages/web/src/ee/features/audit/actions.ts, packages/web/src/features/codeNav/actions.ts Renamed access control flag from allowSingleTenantUnauthedAccess to allowAnonymousAccess in function calls/comments.
packages/web/src/ee/features/publicAccess/publicAccess.tsx Deleted all public access server-side logic.
packages/web/src/env.mjs, docs/docs/configuration/environment-variables.mdx Added FORCE_ENABLE_ANONYMOUS_ACCESS environment variable.
packages/web/src/features/fileTree/actions.ts, packages/web/src/features/search/fileSourceApi.ts, packages/web/src/features/search/listReposApi.ts, packages/web/src/features/search/searchApi.ts Renamed access control flag in function calls and comments.
packages/web/src/initialize.ts Replaced all public access setup logic with anonymous access logic and guest user creation.
packages/web/src/lib/authUtils.ts Added createGuestUser function for anonymous access.
packages/web/src/types.ts Renamed publicAccessEnabled to anonymousAccessEnabled in org metadata; added getOrgMetadata function.
docs/docs.json, docs/docs/configuration/auth/access-settings.mdx, docs/docs/deployment-guide.mdx Updated navigation, documentation, and removed walkthrough video section.
packages/web/src/lib/newsData.ts Added news item for anonymous access feature; updated URL for member approval news item.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WebApp
    participant Backend
    participant DB

    User->>WebApp: Visit organization page
    WebApp->>Backend: getAnonymousAccessStatus(domain)
    Backend->>DB: Fetch organization by domain
    DB-->>Backend: Organization data
    Backend-->>WebApp: anonymousAccessEnabled (true/false)
    alt anonymousAccessEnabled is true
        WebApp-->>User: Allow anonymous access
    else
        WebApp-->>User: Redirect to login
    end
Loading
sequenceDiagram
    participant Owner
    participant WebApp
    participant Backend
    participant DB

    Owner->>WebApp: Toggle Anonymous Access
    WebApp->>Backend: setAnonymousAccessStatus(domain, enabled)
    Backend->>DB: Update organization metadata
    DB-->>Backend: Success/Failure
    Backend-->>WebApp: Result
    WebApp-->>Owner: Show updated toggle state / error message
Loading

Suggested reviewers

  • brendan-kellam

Poem

In the warren, toggles gleam anew,
"Anonymous" is now the name we chew.
No more public hops, just secret ways,
Entitlements checked in burrowed arrays.
Settings and schemas, all in a row—
The rabbits have spoken: let anonymous flow!
🐇✨
"""

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

This comment has been minimized.

Copy link

@coderabbitai coderabbitai bot left a comment

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 (4)
packages/schemas/src/v2/index.schema.ts (1)

2261-2261: Please avoid committing no-op edits to auto-generated files

Line 2261 is flagged only because of trailing-newline / whitespace churn. Since the file is explicitly marked as auto-generated, any manual touch (even just formatting) creates noisy diffs and needless merge conflicts. Regenerate the schema or drop the change altogether.

packages/web/src/app/[domain]/settings/access/page.tsx (1)

10-14: Consider more user-friendly error handling.

Instead of throwing an error when the organization is not found, consider returning a user-friendly error page that matches the application's design patterns.

-    if (!org) {
-        throw new Error("Organization not found");
-    }
+    if (!org) {
+        return (
+            <div className="flex flex-col gap-6">
+                <div className="text-center py-8">
+                    <h3 className="text-lg font-medium mb-2">Organization not found</h3>
+                    <p className="text-sm text-muted-foreground">The requested organization could not be found.</p>
+                </div>
+            </div>
+        );
+    }
packages/web/src/app/onboard/page.tsx (1)

53-56: Remove unused anonymous access status calculation.

The anonymous access status is being calculated but not used anywhere in the component. This appears to be leftover code from development.

-    // Get anonymous access status
-    const anonymousAccessEntitlement = hasEntitlement("anonymous-access");
-    const anonymousAccessStatus = await getAnonymousAccessStatus(SINGLE_TENANT_ORG_DOMAIN);
-    const anonymousAccessEnabled = anonymousAccessEntitlement && !isServiceError(anonymousAccessStatus) && anonymousAccessStatus;
packages/web/src/lib/authUtils.ts (1)

136-136: Inconsistent error message terminology.

The error message mentions "Public access is not supported" but the function is for anonymous access. This should be updated for consistency.

Apply this diff to fix the terminology:

-            message: "Public access is not supported in your current plan",
+            message: "Anonymous access is not supported in your current plan",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55c8e41 and 7d0ed5d.

📒 Files selected for processing (36)
  • demo-site-config.json (1 hunks)
  • docs/docs.json (1 hunks)
  • docs/docs/configuration/auth/access-settings.mdx (1 hunks)
  • docs/docs/configuration/environment-variables.mdx (1 hunks)
  • docs/docs/deployment-guide.mdx (0 hunks)
  • docs/snippets/schemas/v3/index.schema.mdx (0 hunks)
  • packages/backend/src/constants.ts (1 hunks)
  • packages/schemas/src/v2/index.schema.ts (1 hunks)
  • packages/schemas/src/v3/index.schema.ts (0 hunks)
  • packages/schemas/src/v3/index.type.ts (0 hunks)
  • packages/shared/src/entitlements.ts (2 hunks)
  • packages/web/src/actions.ts (8 hunks)
  • packages/web/src/app/[domain]/layout.tsx (3 hunks)
  • packages/web/src/app/[domain]/repos/page.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/access/page.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/layout.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/members/page.tsx (0 hunks)
  • packages/web/src/app/components/anonymousAccessToggle.tsx (1 hunks)
  • packages/web/src/app/components/memberApprovalRequiredToggle.tsx (1 hunks)
  • packages/web/src/app/components/organizationAccessSettings.tsx (1 hunks)
  • packages/web/src/app/components/organizationAccessSettingsWrapper.tsx (1 hunks)
  • packages/web/src/app/onboard/components/memberApprovalRequiredToggle.tsx (0 hunks)
  • packages/web/src/app/onboard/page.tsx (4 hunks)
  • packages/web/src/ee/features/analytics/actions.ts (1 hunks)
  • packages/web/src/ee/features/audit/actions.ts (2 hunks)
  • packages/web/src/ee/features/publicAccess/publicAccess.tsx (0 hunks)
  • packages/web/src/env.mjs (1 hunks)
  • packages/web/src/features/codeNav/actions.ts (2 hunks)
  • packages/web/src/features/fileTree/actions.ts (3 hunks)
  • packages/web/src/features/search/fileSourceApi.ts (1 hunks)
  • packages/web/src/features/search/listReposApi.ts (1 hunks)
  • packages/web/src/features/search/searchApi.ts (1 hunks)
  • packages/web/src/initialize.ts (3 hunks)
  • packages/web/src/lib/authUtils.ts (3 hunks)
  • packages/web/src/types.ts (1 hunks)
  • schemas/v3/index.json (0 hunks)
💤 Files with no reviewable changes (8)
  • docs/docs/deployment-guide.mdx
  • packages/schemas/src/v3/index.type.ts
  • packages/web/src/app/[domain]/settings/members/page.tsx
  • docs/snippets/schemas/v3/index.schema.mdx
  • schemas/v3/index.json
  • packages/web/src/app/onboard/components/memberApprovalRequiredToggle.tsx
  • packages/web/src/ee/features/publicAccess/publicAccess.tsx
  • packages/schemas/src/v3/index.schema.ts
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
demo-site-config.json (1)
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
docs/docs/configuration/auth/access-settings.mdx (1)
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
docs/docs/configuration/environment-variables.mdx (1)
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
packages/web/src/env.mjs (1)
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
packages/backend/src/constants.ts (1)
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
packages/web/src/initialize.ts (1)
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
🧬 Code Graph Analysis (8)
packages/web/src/app/[domain]/settings/access/page.tsx (2)
packages/web/src/data/org.ts (1)
  • getOrgFromDomain (4-19)
packages/web/src/app/components/organizationAccessSettings.tsx (1)
  • OrganizationAccessSettings (11-44)
packages/web/src/app/[domain]/layout.tsx (2)
packages/shared/src/entitlements.ts (1)
  • hasEntitlement (117-120)
packages/web/src/actions.ts (1)
  • getAnonymousAccessStatus (1940-1965)
packages/web/src/app/onboard/page.tsx (5)
packages/shared/src/entitlements.ts (1)
  • hasEntitlement (117-120)
packages/web/src/actions.ts (1)
  • getAnonymousAccessStatus (1940-1965)
packages/web/src/lib/constants.ts (1)
  • SINGLE_TENANT_ORG_DOMAIN (32-32)
packages/web/src/lib/utils.ts (1)
  • isServiceError (317-323)
packages/web/src/app/components/organizationAccessSettings.tsx (1)
  • OrganizationAccessSettings (11-44)
packages/web/src/app/components/memberApprovalRequiredToggle.tsx (3)
packages/web/src/components/hooks/use-toast.ts (2)
  • useToast (194-194)
  • toast (194-194)
packages/web/src/actions.ts (1)
  • setMemberApprovalRequired (1688-1701)
packages/web/src/lib/constants.ts (1)
  • SINGLE_TENANT_ORG_DOMAIN (32-32)
packages/web/src/lib/authUtils.ts (3)
packages/shared/src/entitlements.ts (2)
  • hasEntitlement (117-120)
  • getPlan (89-110)
packages/web/src/lib/constants.ts (3)
  • SOURCEBOT_SUPPORT_EMAIL (35-35)
  • SOURCEBOT_GUEST_USER_ID (29-29)
  • SOURCEBOT_GUEST_USER_EMAIL (30-30)
packages/web/src/data/org.ts (1)
  • getOrgFromDomain (4-19)
packages/web/src/app/components/anonymousAccessToggle.tsx (4)
packages/web/src/components/hooks/use-toast.ts (2)
  • useToast (194-194)
  • toast (194-194)
packages/web/src/actions.ts (1)
  • setAnonymousAccessStatus (1967-1999)
packages/web/src/lib/constants.ts (1)
  • SINGLE_TENANT_ORG_DOMAIN (32-32)
packages/web/src/components/ui/switch.tsx (1)
  • Switch (29-29)
packages/web/src/app/components/organizationAccessSettingsWrapper.tsx (2)
packages/web/src/app/components/memberApprovalRequiredToggle.tsx (1)
  • MemberApprovalRequiredToggle (15-71)
packages/web/src/app/components/inviteLinkToggle.tsx (1)
  • InviteLinkToggle (18-130)
packages/web/src/actions.ts (7)
packages/web/src/lib/constants.ts (2)
  • SINGLE_TENANT_ORG_DOMAIN (32-32)
  • SOURCEBOT_SUPPORT_EMAIL (35-35)
packages/web/src/lib/utils.ts (1)
  • isServiceError (317-323)
packages/shared/src/entitlements.ts (2)
  • hasEntitlement (117-120)
  • getPlan (89-110)
packages/shared/src/index.server.ts (2)
  • hasEntitlement (2-2)
  • getPlan (4-4)
packages/web/src/lib/serviceError.ts (2)
  • notAuthenticated (83-89)
  • ServiceError (11-11)
packages/web/src/data/org.ts (1)
  • getOrgFromDomain (4-19)
packages/web/src/types.ts (1)
  • getOrgMetadata (10-13)
🪛 Biome (1.9.4)
demo-site-config.json

[error] 241-241: expected , but instead found // 24 hours

Remove // 24 hours

(parse)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (55)
packages/web/src/app/[domain]/repos/page.tsx (1)

8-11: Syntax error fixed — ✅

The added closing brace properly terminates the if (!org) block and prevents the subsequent return from being captured by the conditional. The component will now render as intended.

packages/web/src/features/search/searchApi.ts (1)

348-350: allowAnonymousAccess flag is fully propagated
I’ve verified there are no remaining references to the old allowSingleTenantUnauthedAccess flag and all withAuth call sites either use the default (false) or explicitly pass allowAnonymousAccess = true where required. withOrgMembership doesn’t take an anonymous‐access flag, so no further changes are needed.

docs/docs.json (1)

72-78: Navigation entry changed — ensure target page exists

The sidebar now points to docs/configuration/auth/access-settings. Verify that this MDX file is committed and correctly named; otherwise the link will 404 in production.

packages/web/src/features/search/fileSourceApi.ts (1)

51-52: Flag rename acknowledged

Comment & param updated to allowAnonymousAccess; implementation remains consistent with the refactor.

packages/web/src/features/search/listReposApi.ts (1)

48-48: Parameter comment update aligns with the anonymous access refactor.

The comment update from allowSingleTenantUnauthedAccess to allowAnonymousAccess is consistent with the broader terminology change across the codebase. The functionality remains unchanged.

packages/web/src/features/fileTree/actions.ts (3)

80-80: Parameter comment update aligns with the anonymous access refactor.

The comment update from allowSingleTenantUnauthedAccess to allowAnonymousAccess is consistent with the broader terminology change. The functionality remains unchanged.


157-157: Parameter comment update aligns with the anonymous access refactor.

The comment update from allowSingleTenantUnauthedAccess to allowAnonymousAccess is consistent with the broader terminology change. The functionality remains unchanged.


208-208: Parameter comment update aligns with the anonymous access refactor.

The comment update from allowSingleTenantUnauthedAccess to allowAnonymousAccess is consistent with the broader terminology change. The functionality remains unchanged.

packages/web/src/ee/features/analytics/actions.ts (1)

102-102: Anonymous Access Policy Is Consistent—Please Confirm Security Requirements

Both the analytics and code navigation actions use allowAnonymousAccess = true, following the same pattern:

  • packages/web/src/features/codeNav/actions.ts
    • minRequiredRole = OrgRole.GUEST
    • allowAnonymousAccess = true
  • packages/web/src/ee/features/analytics/actions.ts
    • minRequiredRole = OrgRole.MEMBER
    • allowAnonymousAccess = true

No code changes are required—the terminology update is correct and consistent. However, please verify with the product/security team that exposing analytics data anonymously aligns with our intended access policies.

packages/backend/src/constants.ts (1)

17-17: Removal of enablePublicAccess aligns with the anonymous access refactor.

The removal of the enablePublicAccess property from DEFAULT_SETTINGS is consistent with the broader refactor replacing public access with anonymous access. This aligns with the security-first approach where access should be disabled by default unless explicitly enabled.

packages/web/src/env.mjs (1)

83-83: Addition of FORCE_ENABLE_ANONYMOUS_ACCESS environment variable is well-implemented.

The new environment variable follows the established pattern with a secure default value of 'false'. This provides administrators with the ability to force enable anonymous access when needed while maintaining security by default.

packages/web/src/app/[domain]/settings/layout.tsx (1)

67-72: LGTM! Clean implementation of role-based navigation.

The new "Access" navigation item is properly restricted to organization owners and follows the established patterns for conditional sidebar items.

packages/web/src/features/codeNav/actions.ts (2)

44-44: LGTM! Consistent parameter renaming for anonymous access.

The parameter rename from allowSingleTenantUnauthedAccess to allowAnonymousAccess improves clarity and aligns with the broader codebase refactor.


77-77: LGTM! Consistent parameter renaming for anonymous access.

The parameter rename from allowSingleTenantUnauthedAccess to allowAnonymousAccess improves clarity and aligns with the broader codebase refactor.

packages/web/src/types.ts (1)

1-13: LGTM! Clean schema update and utility function.

The changes properly rename the schema property to align with anonymous access terminology and add a useful utility function with proper error handling using safeParse.

docs/docs/configuration/environment-variables.mdx (1)

24-24: LGTM! Proper documentation for the new environment variable.

The new FORCE_ENABLE_ANONYMOUS_ACCESS environment variable is well-documented with a clear description, appropriate default value, and helpful link to related documentation.

packages/web/src/ee/features/audit/actions.ts (2)

20-20: LGTM! Consistent parameter renaming for anonymous access.

The parameter rename from allowSingleTenantUnauthedAccess to allowAnonymousAccess improves clarity and aligns with the broader codebase refactor.


58-58: LGTM! Consistent parameter renaming for anonymous access.

The parameter rename from allowSingleTenantUnauthedAccess to allowAnonymousAccess improves clarity and aligns with the broader codebase refactor.

docs/docs/configuration/auth/access-settings.mdx (1)

1-38: Comprehensive documentation update for anonymous access feature.

The documentation effectively explains the new anonymous access feature, including:

  • Clear enterprise license restrictions
  • Multiple configuration methods (UI and environment variable)
  • Proper warning notifications
  • Maintains existing member approval content

The structure and content are well-organized and provide users with the necessary information to configure access settings.

packages/web/src/app/[domain]/settings/access/page.tsx (1)

16-34: Well-structured access settings page layout.

The page layout is clean and follows good practices:

  • Clear heading and description
  • External documentation link with proper attributes
  • Integration with the OrganizationAccessSettings component
  • Consistent styling with the application design system
packages/shared/src/entitlements.ts (1)

33-52: Correct entitlement refactor from public-access to anonymous-access.

The entitlement changes are properly implemented:

  • Systematic replacement of "public-access" with "anonymous-access"
  • OSS plan now includes the anonymous access entitlement
  • Enterprise and demo plans maintain the feature
  • No breaking changes to the entitlement system structure

This aligns with the broader refactor and maintains consistency across the codebase.

packages/web/src/app/[domain]/layout.tsx (3)

21-21: Correct import update for anonymous access functionality.

The import has been properly updated to use the new getAnonymousAccessStatus function, aligning with the refactor from public to anonymous access.


41-41: Proper entitlement check and status retrieval for anonymous access.

The entitlement check and status retrieval have been correctly updated:

  • Uses the new "anonymous-access" entitlement
  • Calls the updated getAnonymousAccessStatus function
  • Variable renamed to anonymousAccessEnabled for consistency

86-94: Authentication redirect logic correctly updated.

The authentication redirect logic properly implements the anonymous access feature:

  • Clear comment explaining the behavior
  • Maintains existing SSO and IAP integration
  • Preserves the redirect functionality for unauthenticated users
packages/web/src/app/onboard/page.tsx (3)

9-9: Correct component import for comprehensive access settings.

The import has been properly updated to use the new OrganizationAccessSettings component, which provides a more comprehensive interface for managing access settings compared to the previous member approval toggle.


19-23: Proper imports for anonymous access functionality.

The imports have been correctly updated to include:

  • getAnonymousAccessStatus for retrieving anonymous access status
  • isServiceError for proper error handling

161-177: Excellent update to comprehensive access settings step.

The onboarding step has been properly updated to:

  • Reflect the broader "Access Settings" scope instead of just member approval
  • Include updated documentation link pointing to the new access settings page
  • Use the comprehensive OrganizationAccessSettings component
  • Maintain clear user guidance with appropriate links

This provides users with a more complete access configuration experience during onboarding.

packages/web/src/app/components/organizationAccessSettings.tsx (4)

12-15: LGTM - Proper error handling for missing organization.

The error handling correctly returns a user-friendly error message when the organization cannot be found, which maintains good UX.


17-18: LGTM - Consistent with retrieved learnings on default values.

The metadata extraction correctly defaults anonymousAccessEnabled to false when not explicitly defined, which aligns with the retrieved learnings about Sourcebot's declarative config system treating undefined settings as false.


24-26: LGTM - Proper entitlement and environment variable handling.

The entitlement check and environment variable parsing follow the expected patterns for feature gating and configuration overrides.


28-43: LGTM - Well-structured component composition.

The component correctly passes all necessary props to child components and maintains a clean separation of concerns between anonymous access toggle and other access settings.

packages/web/src/app/components/memberApprovalRequiredToggle.tsx (3)

15-18: LGTM - Proper state initialization and hook usage.

The component correctly initializes local state from props and sets up necessary hooks for state management and notifications.


20-46: LGTM - Comprehensive error handling and state management.

The async handler properly manages loading state, handles both service errors and exceptions, and maintains consistent error messaging through toast notifications. The early return on error prevents state updates when the operation fails.


48-70: LGTM - Well-structured UI with proper accessibility.

The component structure follows good practices with semantic HTML, proper labeling, and clear visual hierarchy. The loading state correctly disables the switch during operations.

packages/web/src/lib/authUtils.ts (3)

129-138: LGTM - Proper entitlement validation with clear error messaging.

The function correctly checks for the "anonymous-access" entitlement and returns a descriptive error message when not available. The error message appropriately references the support contact for assistance.


140-147: LGTM - Proper organization validation.

The organization lookup and error handling follow established patterns with appropriate ServiceError responses.


149-187: LGTM - Robust user and membership management.

The implementation properly handles guest user creation/update using upsert operations and establishes the organization membership with the GUEST role. The upsert pattern ensures idempotency and prevents duplicate entries.

packages/web/src/app/components/anonymousAccessToggle.tsx (6)

17-21: LGTM - Proper state initialization and hook setup.

The component correctly initializes local state from props and sets up necessary hooks for state management and notifications.


22-48: LGTM - Comprehensive error handling and state management.

The async handler properly manages loading state, handles both service errors and exceptions with appropriate error messages, and maintains consistent error messaging through toast notifications. The early return on error prevents state updates when operations fail.


49-52: LGTM - Clear conditional logic for UI states.

The boolean flags clearly separate the different UI states (disabled, plan message, force-enable message) making the conditional rendering logic easy to follow.


54-94: LGTM - Informative messaging for different states.

The conditional messaging provides clear guidance to users about why the toggle might be disabled, with appropriate links to support when needed. The visual styling with icons and proper contrast enhances the user experience.


95-116: LGTM - Clear force-enable messaging.

The force-enable message clearly explains why the toggle is disabled and uses appropriate code styling for the environment variable name.


119-125: LGTM - Proper switch implementation with accessibility.

The switch correctly reflects the current state and properly handles the disabled state based on the computed conditions.

packages/web/src/app/components/organizationAccessSettingsWrapper.tsx (3)

20-24: Verify the initial state logic for invite link visibility.

The initial state logic memberApprovalRequired && !anonymousAccessEnabled may not align with the expected behavior. This means the invite link is only shown when member approval is required AND anonymous access is disabled.

Could you clarify the business logic? Should the invite link be visible when:

  1. Member approval is required (regardless of anonymous access), or
  2. Member approval is required AND anonymous access is disabled, or
  3. Some other combination?

The current logic seems to hide the invite link when anonymous access is enabled, which might not be the intended behavior.


22-24: LGTM - Clean callback handling for parent-child communication.

The callback properly updates the local state when the member approval toggle changes, maintaining UI consistency.


26-46: LGTM - Smooth animation implementation.

The CSS transitions provide smooth show/hide animations for the invite link toggle, enhancing the user experience. The pointer-events-none prevents interaction when hidden.

packages/web/src/initialize.ts (3)

12-13: LGTM! Appropriate imports for anonymous access functionality.

The imports for createGuestUser and getOrgFromDomain are correctly added to support the new anonymous access feature.


198-213: Excellent implementation of anonymous access initialization.

The logic correctly:

  1. Checks for the "anonymous-access" entitlement instead of the old "public-access"
  2. Creates a guest user when the entitlement is available
  3. Explicitly sets anonymousAccessEnabled: false in org metadata when the entitlement is not available

This aligns perfectly with the retrieved learning that when anonymous access is not explicitly enabled, it should be treated as false and the status should be explicitly set to false.


109-129: Environment variable handling verified

  • FORCE_ENABLE_ANONYMOUS_ACCESS is defined in packages/web/src/env.mjs with a default of false.
  • It’s referenced in packages/web/src/initialize.ts with correct entitlement checks before enabling anonymous access.
  • Fully documented in docs/configuration/environment-variables.mdx (default false) and mentioned in docs/configuration/auth/access-settings.mdx.
  • Behavior aligns with treating anonymous access as disabled by default unless explicitly forced.

No changes required.

packages/web/src/actions.ts (6)

66-66: LGTM! Parameter rename accurately reflects the new anonymous access functionality.

The parameter rename from allowSingleTenantUnauthedAccess to allowAnonymousAccess is more descriptive and aligns with the new feature terminology.


72-72: LGTM! Function call updated to use the new anonymous access status function.

The function call correctly uses the new getAnonymousAccessStatus function instead of the removed getPublicAccessStatus.


102-114: Excellent implementation of anonymous access logic.

The logic correctly:

  1. Uses the renamed allowAnonymousAccess parameter
  2. Checks the anonymous access status and entitlement
  3. Updates the entitlement check from "public-access" to "anonymous-access"
  4. Provides appropriate error messages and logging

675-675: LGTM! Consistent parameter usage across all function calls.

All withAuth calls have been correctly updated to use the new allowAnonymousAccess parameter with appropriate OrgRole.GUEST minimum required role for anonymous access scenarios.

Also applies to: 737-737, 866-866, 936-937, 1937-1938


1940-1965: Well-implemented anonymous access status retrieval function.

The function correctly:

  1. Fetches the organization by domain
  2. Returns appropriate error if organization not found
  3. Handles null metadata gracefully by returning false (good default behavior)
  4. Validates metadata using the getOrgMetadata helper
  5. Returns boolean value for anonymousAccessEnabled flag

1967-1999: Robust implementation of anonymous access status setting.

The function correctly:

  1. Requires authentication and owner role membership
  2. Validates the "anonymous-access" entitlement before allowing changes
  3. Merges the new setting with existing metadata to preserve other properties
  4. Uses appropriate error codes and messages
  5. Provides helpful logging with support contact information

@@ -62,13 +63,13 @@ export const sew = async <T>(fn: () => Promise<T>): Promise<T | ServiceError> =>
}
}

export const withAuth = async <T>(fn: (userId: string, apiKeyHash: string | undefined) => Promise<T>, allowSingleTenantUnauthedAccess: boolean = false, apiKey: ApiKeyPayload | undefined = undefined) => {
export const withAuth = async <T>(fn: (userId: string, apiKeyHash: string | undefined) => Promise<T>, allowAnonymousAccess: boolean = false, apiKey: ApiKeyPayload | undefined = undefined) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not asking for us to do this in this PR, but I feel like this allowAnonymous flag is a bit of a code-smell. I'm pretty sure that in all scenarios where this is set to true, the minimum organization role will be GUEST anyways. If a organization has anonymous access enabled, then the minimum role remains at GUEST. If not, then the minimum role for all actions is raised to MEMBER.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thinking about it more, we could probably eliminate the need for the concept of our sentinel guestUser entirely, since everywhere where a user is actually required (i.e., besides verifying they are a member of the organization), the role would be MEMBER or above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it definitely isn't ideal, but the reason this is needed rn is how we're chaining withAuth and withOrgMembership. The withOrgMembership expects withAuth to pass, so we're required to create the sentinel Guest user because it expects a userId. We need to pass in the allowAnonymous flag to know whether or not to return a Guest user or nothing

Copy link
Contributor

Choose a reason for hiding this comment

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

Right. We should probably just combine withOrgMembership and withAuth into a single middleware function that handles both the authentication and authorization checks.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
docs/docs/configuration/auth/access-settings.mdx (1)

37-37: Consider using "invitation link" for formal documentation.

For consistency with formal documentation style, consider using "invitation link" instead of "invite link".

-If member approval is required, an owner of the deployment can enable an invite link. When enabled, users
+If member approval is required, an owner of the deployment can enable an invitation link. When enabled, users
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 048650c and b41828e.

📒 Files selected for processing (15)
  • CHANGELOG.md (1 hunks)
  • docs/docs/configuration/auth/access-settings.mdx (1 hunks)
  • docs/docs/configuration/auth/roles-and-permissions.mdx (1 hunks)
  • packages/web/src/actions.ts (8 hunks)
  • packages/web/src/app/[domain]/components/submitJoinRequest.tsx (1 hunks)
  • packages/web/src/app/[domain]/settings/access/page.tsx (1 hunks)
  • packages/web/src/app/components/anonymousAccessToggle.tsx (1 hunks)
  • packages/web/src/app/components/joinOrganizationButton.tsx (1 hunks)
  • packages/web/src/app/components/organizationAccessSettings.tsx (1 hunks)
  • packages/web/src/app/login/components/credentialsForm.tsx (0 hunks)
  • packages/web/src/app/onboard/components/completeOnboardingButton.tsx (1 hunks)
  • packages/web/src/app/onboard/page.tsx (4 hunks)
  • packages/web/src/initialize.ts (3 hunks)
  • packages/web/src/lib/utils.ts (2 hunks)
  • packages/web/src/types.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/web/src/app/login/components/credentialsForm.tsx
✅ Files skipped from review due to trivial changes (5)
  • packages/web/src/types.ts
  • packages/web/src/app/[domain]/components/submitJoinRequest.tsx
  • docs/docs/configuration/auth/roles-and-permissions.mdx
  • packages/web/src/app/components/joinOrganizationButton.tsx
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/web/src/app/[domain]/settings/access/page.tsx
  • packages/web/src/app/onboard/page.tsx
  • packages/web/src/app/components/anonymousAccessToggle.tsx
  • packages/web/src/app/components/organizationAccessSettings.tsx
  • packages/web/src/initialize.ts
  • packages/web/src/actions.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
docs/docs/configuration/auth/access-settings.mdx (1)
Learnt from: msukkari
PR: sourcebot-dev/sourcebot#311
File: packages/web/src/initialize.ts:142-155
Timestamp: 2025-05-23T18:48:23.999Z
Learning: In Sourcebot's declarative config system, when the enablePublicAccess setting is not explicitly defined in the config file, it should be treated as false and the public access status should be explicitly set to false. This is the intended behavior to ensure public access is disabled by default unless explicitly enabled in the configuration.
🧬 Code Graph Analysis (1)
packages/web/src/lib/utils.ts (1)
packages/web/src/types.ts (2)
  • OrgMetadata (7-7)
  • orgMetadataSchema (3-5)
🪛 LanguageTool
docs/docs/configuration/auth/access-settings.mdx

[style] ~37-~37: The noun “invitation” is usually used instead of ‘invite’ in formal writing.
Context: ...n owner of the deployment can enable an invite link. When enabled, users can use this ...

(AN_INVITE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (4)
packages/web/src/app/onboard/components/completeOnboardingButton.tsx (1)

48-48: Good simplification of button styling.

Removing the explicit CSS classes in favor of just w-full improves maintainability and consistency by relying on the default button component styling. This aligns well with the broader UI streamlining effort mentioned in the summary.

Please verify that the button's visual appearance and user experience remain appropriate without the explicit height, background color, hover effects, and other styling that was removed.

packages/web/src/lib/utils.ts (2)

17-18: LGTM! Clean imports for the new utility function.

The imports for Org and metadata types are properly added to support the new getOrgMetadata function.


458-461: Excellent utility function implementation.

The getOrgMetadata function provides a safe way to parse organization metadata using Zod schema validation. The use of safeParse() appropriately handles potential parsing failures by returning null instead of throwing errors, which aligns with defensive programming practices.

This utility will be essential for the anonymous access feature migration, ensuring consistent and safe access to organization metadata throughout the codebase.

docs/docs/configuration/auth/access-settings.mdx (1)

1-40: Excellent comprehensive documentation for access settings.

This documentation effectively covers all aspects of the new access control features, including anonymous access, member approval, and invite links. The structure is clear and the explanations are thorough, addressing the transition from "public access" to "anonymous access" features.

The documentation properly addresses enterprise license restrictions and clearly explains the Guest role permissions for anonymous users, which aligns with the past review feedback.

@msukkari msukkari merged commit aac1d45 into main Jul 19, 2025
7 checks passed
@msukkari msukkari deleted the msukkarieh/auth branch July 26, 2025 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants