Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions backend/account_v2/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class ErrorMessage:


class DefaultOrg:
ORGANIZATION_NAME = "mock_org"
MOCK_ORG = "mock_org"
ORGANIZATION_NAME = settings.DEFAULT_ORGANIZATION_NAME
Comment thread
greptile-apps[bot] marked this conversation as resolved.
Resolved
MOCK_ORG = settings.DEFAULT_ORGANIZATION_NAME
MOCK_USER = settings.DEFAULT_AUTH_USERNAME
MOCK_USER_ID = "mock_user_id"
MOCK_USER_EMAIL = "email@mock.com"
Expand Down
4 changes: 4 additions & 0 deletions backend/backend/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ def get_required_setting(setting_key: str, default: str | None = None) -> str |

DEFAULT_AUTH_USERNAME = os.environ.get("DEFAULT_AUTH_USERNAME", "unstract")
DEFAULT_AUTH_PASSWORD = os.environ.get("DEFAULT_AUTH_PASSWORD", "unstract")
# Name/id of the default organization created for the open-source (single-tenant)
Comment thread
greptile-apps[bot] marked this conversation as resolved.
Resolved
# deployment. Configurable so the org segment of URLs (e.g. /mock_org/tools) can be
# a meaningful name. Defaults to "mock_org" for backward compatibility.
DEFAULT_ORGANIZATION_NAME = os.environ.get("DEFAULT_ORGANIZATION_NAME", "mock_org")

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.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Keep backend and frontend organization-name configuration in lockstep.

The backend accepts an explicitly empty value, while the frontend silently falls back to mock_org when its value is missing or empty. A custom backend deployment with a missing or mismatched VITE_DEFAULT_ORG_NAME therefore classifies the organization as SaaS instead of OSS; this can expose SaaS-only UI and enable the PostHog PII path.

  • backend/backend/settings/base.py#L175-L178: reject or normalize blank values instead of accepting "".
  • frontend/src/config.js#L21-L26: fail fast on a missing/mismatched frontend value, or source the frontend value from the backend-resolved organization name rather than silently defaulting to mock_org.
📍 Affects 2 files
  • backend/backend/settings/base.py#L175-L178 (this comment)
  • frontend/src/config.js#L21-L26
🤖 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 `@backend/backend/settings/base.py` around lines 175 - 178, Normalize or reject
blank DEFAULT_ORGANIZATION_NAME values in backend/backend/settings/base.py lines
175-178 so the resolved value never becomes empty. Update frontend/src/config.js
lines 21-26 to fail fast on missing or mismatched VITE_DEFAULT_ORG_NAME, or
source it from the backend-resolved organization name instead of silently
defaulting to mock_org; keep both configurations in lockstep.

SYSTEM_ADMIN_USERNAME = get_required_setting("SYSTEM_ADMIN_USERNAME")
SYSTEM_ADMIN_PASSWORD = get_required_setting("SYSTEM_ADMIN_PASSWORD")
SYSTEM_ADMIN_EMAIL = get_required_setting("SYSTEM_ADMIN_EMAIL")
Expand Down
5 changes: 5 additions & 0 deletions backend/sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ API_DEPLOYMENT_RATE_LIMIT_LOCK_BLOCKING_TIMEOUT=5
DEFAULT_AUTH_USERNAME=
DEFAULT_AUTH_PASSWORD=

# Name of the default organization for the open-source (single-tenant) deployment.
# Appears as the org segment of URLs (e.g. /mock_org/tools). Defaults to "mock_org".
# If you change this, set the frontend VITE_DEFAULT_ORG_NAME to the same value.
DEFAULT_ORGANIZATION_NAME=mock_org

# System admin credentials
SYSTEM_ADMIN_USERNAME="admin"
SYSTEM_ADMIN_PASSWORD="admin"
Expand Down
1 change: 1 addition & 0 deletions frontend/generate-runtime-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ window.RUNTIME_CONFIG = {
faviconPath: "${VITE_FAVICON_PATH:-${REACT_APP_FAVICON_PATH}}",
logoUrl: "${VITE_CUSTOM_LOGO_URL:-${REACT_APP_CUSTOM_LOGO_URL}}",
enablePosthog: "${VITE_ENABLE_POSTHOG:-${REACT_APP_ENABLE_POSTHOG}}",
defaultOrgName: "${VITE_DEFAULT_ORG_NAME:-${REACT_APP_DEFAULT_ORG_NAME:-mock_org}}",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
version: "${APP_VERSION}"
};
EOF
Expand Down
5 changes: 5 additions & 0 deletions frontend/sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ VITE_BACKEND_URL=http://localhost:8000
# Default: false for local development
VITE_ENABLE_POSTHOG=false

# Name of the default organization for the open-source deployment (org segment of
# URLs, e.g. /mock_org/tools). Must match the backend DEFAULT_ORGANIZATION_NAME.
# Defaults to "mock_org".
VITE_DEFAULT_ORG_NAME=mock_org

# For development
NODE_ENV=development
# Enable file watching via polling instead of filesystem events
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/helpers/auth/RequireAdmin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useState } from "react";
import { Outlet } from "react-router-dom";

import config from "../../../config";
import { useAxiosPrivate } from "../../../hooks/useAxiosPrivate";
import { useSessionStore } from "../../../store/session-store";
import { NotFound } from "../../error/NotFound/NotFound.jsx";
Expand All @@ -12,7 +13,7 @@ const RequireAdmin = () => {
const [isVerifying, setIsVerifying] = useState(true);
const orgId = sessionDetails?.orgId;
const orgName = sessionDetails?.orgName;
const isOpenSource = orgName === "mock_org";
const isOpenSource = orgName === config.defaultOrgName;

useEffect(() => {
const verifyAdminStatus = async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ function TopNavBar({ isSimpleLayout, topNavBarOptions }) {
const isUnstract = !(effectiveProduct && effectiveProduct !== "unstract");
const isAPIHub = effectiveProduct === "verticals";
const isStaff = sessionDetails?.isStaff || sessionDetails?.is_staff;
const isOpenSource = orgName === "mock_org";
const isOpenSource = orgName === config.defaultOrgName;

// Check user role and whether the onboarding is incomplete
useEffect(() => {
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ const config = {
"/favicon.ico",
logoUrl: runtimeConfig.logoUrl || import.meta.env.VITE_CUSTOM_LOGO_URL,
version: runtimeConfig.version || import.meta.env.VITE_VERSION,
// Name of the default org for the open-source deployment. Must match the backend
// DEFAULT_ORGANIZATION_NAME so the open-source check below stays correct.
defaultOrgName:
runtimeConfig.defaultOrgName ||
import.meta.env.VITE_DEFAULT_ORG_NAME ||
"mock_org",
// Add more values as OR case, if needed for fallback.
};

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/hooks/usePostHogEvents.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { usePostHog } from "posthog-js/react";

import config from "../config";
import { isSaasProdDeployment } from "../helpers/PostHogDeployment";
import { useSessionStore } from "../store/session-store";

Expand Down Expand Up @@ -61,7 +62,7 @@ const usePostHogEvents = () => {
try {
const orgId = sessionDetails?.orgId;
const orgName = sessionDetails?.orgName;
const isOpenSource = orgName === "mock_org";
const isOpenSource = orgName === config.defaultOrgName;
const software = isOpenSource ? "OSS" : "SAAS";
const email = sessionDetails?.email;
const userId = sessionDetails?.id;
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/pages/UnstractAdministrationPage.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "./UnstractAdministrationPage.css";
import config from "../config";
import { useSessionStore } from "../store/session-store";

let UnstractAdministration;
Expand All @@ -23,7 +24,7 @@ function UnstractAdministrationPage() {

const isStaff = sessionDetails?.isStaff || sessionDetails?.is_staff;
const orgName = sessionDetails?.orgName;
const isOpenSource = orgName === "mock_org";
const isOpenSource = orgName === config.defaultOrgName;

// Staff permission check - protects route at component level
if (!isStaff || isOpenSource) {
Expand Down