feat(fork)!: remove all frontend Enterprise-Edition code (community build)

Strip the proprietary client EE so the fork ships a clean community/AGPL
edition, mirroring Forkmost. Delete apps/client/src/ee (201 files) and
packages/ee, and patch every consumer that imported from @/ee/*.

- gate-out EE features (useHasFeature -> false): API keys, SSO, MFA, SCIM,
  audit logs, AI / AI-chat, templates, page permissions, page verification,
  comment resolution, trash retention, viewer comments
- drop cloud/billing/trial/entitlement/posthog flows; sign-in is now
  email+password only (no SSO/LDAP/cloud)
- remove EE routes from App.tsx and EE entries from sidebars/settings nav
- restore the community page-share button (ShareModal) that the EE
  PageShareModal used to provide
- remove the dead "Attachments" search filter, dead MFA navigation and
  orphaned route constants

Client type-checks clean; full `pnpm build` is green for all three projects.
This commit is contained in:
vvzvlad
2026-06-16 22:32:39 +03:00
parent 4f05fb5d2e
commit a88b3f776c
240 changed files with 189 additions and 21012 deletions
@@ -18,7 +18,6 @@ import classes from "@/features/auth/components/auth.module.css";
import { useGetInvitationQuery } from "@/features/workspace/queries/workspace-query.ts";
import { useRedirectIfAuthenticated } from "@/features/auth/hooks/use-redirect-if-authenticated.ts";
import { useTranslation } from "react-i18next";
import SsoLogin from "@/ee/components/sso-login.tsx";
import { AuthLayout } from "./auth-layout.tsx";
const formSchema = z.object({
@@ -74,48 +73,44 @@ export function InviteSignUpForm() {
{t("Join the workspace")}
</Title>
<SsoLogin />
<Stack align="stretch" justify="center" gap="xl">
<form onSubmit={form.onSubmit(onSubmit)}>
<TextInput
id="name"
type="text"
label={t("Name")}
placeholder={t("enter your full name")}
variant="filled"
{...form.getInputProps("name")}
/>
{!invitation.enforceSso && (
<Stack align="stretch" justify="center" gap="xl">
<form onSubmit={form.onSubmit(onSubmit)}>
<TextInput
id="name"
type="text"
label={t("Name")}
placeholder={t("enter your full name")}
variant="filled"
{...form.getInputProps("name")}
/>
<TextInput
id="email"
type="email"
label={t("Email")}
value={invitation.email}
disabled
variant="filled"
mt="md"
/>
<TextInput
id="email"
type="email"
label={t("Email")}
value={invitation.email}
disabled
variant="filled"
mt="md"
/>
<PasswordInput
label={t("Password")}
placeholder={t("Your password")}
variant="filled"
mt="md"
visibilityToggleButtonProps={{
"aria-label": t("Toggle password visibility"),
"aria-hidden": false,
tabIndex: 0,
}}
{...form.getInputProps("password")}
/>
<Button type="submit" fullWidth mt="xl" loading={isLoading}>
{t("Sign Up")}
</Button>
</form>
</Stack>
)}
<PasswordInput
label={t("Password")}
placeholder={t("Your password")}
variant="filled"
mt="md"
visibilityToggleButtonProps={{
"aria-label": t("Toggle password visibility"),
"aria-hidden": false,
tabIndex: 0,
}}
{...form.getInputProps("password")}
/>
<Button type="submit" fullWidth mt="xl" loading={isLoading}>
{t("Sign Up")}
</Button>
</form>
</Stack>
</Box>
</Container>
</AuthLayout>
@@ -17,7 +17,6 @@ import { useRedirectIfAuthenticated } from "@/features/auth/hooks/use-redirect-i
import { Link } from "react-router-dom";
import APP_ROUTE from "@/lib/app-route.ts";
import { useTranslation } from "react-i18next";
import SsoLogin from "@/ee/components/sso-login.tsx";
import { useWorkspacePublicDataQuery } from "@/features/workspace/queries/workspace-query.ts";
import { Error404 } from "@/components/ui/error-404.tsx";
import React from "react";
@@ -36,7 +35,6 @@ export function LoginForm() {
const { signIn, isLoading } = useAuth();
useRedirectIfAuthenticated();
const {
data,
isLoading: isDataLoading,
isError,
error,
@@ -77,55 +75,49 @@ export function LoginForm() {
{t("Login")}
</Title>
<SsoLogin />
<form onSubmit={form.onSubmit(onSubmit, handleValidationFailure)}>
<TextInput
id="email"
type="email"
label={t("Email")}
placeholder="email@example.com"
variant="filled"
autoComplete="email"
errorProps={{ role: "alert" }}
{...form.getInputProps("email")}
/>
{!data?.enforceSso && (
<>
<form onSubmit={form.onSubmit(onSubmit, handleValidationFailure)}>
<TextInput
id="email"
type="email"
label={t("Email")}
placeholder="email@example.com"
variant="filled"
autoComplete="email"
errorProps={{ role: "alert" }}
{...form.getInputProps("email")}
/>
<PasswordInput
id="password"
label={t("Password")}
placeholder={t("Your password")}
variant="filled"
mt="md"
autoComplete="current-password"
errorProps={{ role: "alert" }}
visibilityToggleButtonProps={{
"aria-label": t("Toggle password visibility"),
"aria-hidden": false,
tabIndex: 0,
}}
{...form.getInputProps("password")}
/>
<PasswordInput
id="password"
label={t("Password")}
placeholder={t("Your password")}
variant="filled"
mt="md"
autoComplete="current-password"
errorProps={{ role: "alert" }}
visibilityToggleButtonProps={{
"aria-label": t("Toggle password visibility"),
"aria-hidden": false,
tabIndex: 0,
}}
{...form.getInputProps("password")}
/>
<Group justify="flex-end" mt="sm">
<Anchor
to={APP_ROUTE.AUTH.FORGOT_PASSWORD}
component={Link}
underline="never"
size="sm"
>
{t("Forgot your password?")}
</Anchor>
</Group>
<Group justify="flex-end" mt="sm">
<Anchor
to={APP_ROUTE.AUTH.FORGOT_PASSWORD}
component={Link}
underline="never"
size="sm"
>
{t("Forgot your password?")}
</Anchor>
</Group>
<Button type="submit" fullWidth mt="md" loading={isLoading}>
{t("Sign In")}
</Button>
</form>
</>
)}
<Button type="submit" fullWidth mt="md" loading={isLoading}>
{t("Sign In")}
</Button>
</form>
</Box>
</Container>
</AuthLayout>
@@ -9,16 +9,10 @@ import {
Button,
PasswordInput,
Box,
Anchor,
Text,
} from "@mantine/core";
import useAuth from "@/features/auth/hooks/use-auth";
import classes from "@/features/auth/components/auth.module.css";
import { useTranslation } from "react-i18next";
import SsoCloudSignup from "@/ee/components/sso-cloud-signup.tsx";
import { isCloud } from "@/lib/config.ts";
import { Link } from "react-router-dom";
import APP_ROUTE from "@/lib/app-route.ts";
import { AuthLayout } from "./auth-layout.tsx";
const formSchema = z.object({
@@ -58,20 +52,16 @@ export function SetupWorkspaceForm() {
{t("Create workspace")}
</Title>
{isCloud() && <SsoCloudSignup />}
<form onSubmit={form.onSubmit(onSubmit)}>
{!isCloud() && (
<TextInput
id="workspaceName"
type="text"
label={t("Workspace Name")}
placeholder={t("e.g ACME Inc")}
variant="filled"
mt="md"
{...form.getInputProps("workspaceName")}
/>
)}
<TextInput
id="workspaceName"
type="text"
label={t("Workspace Name")}
placeholder={t("e.g ACME Inc")}
variant="filled"
mt="md"
{...form.getInputProps("workspaceName")}
/>
<TextInput
id="name"
@@ -111,18 +101,6 @@ export function SetupWorkspaceForm() {
</form>
</Box>
</Container>
{isCloud() && (
<Text ta="center">
{t("Already part of an existing workspace?")}{" "}
<Anchor
component={Link}
to={APP_ROUTE.AUTH.SELECT_WORKSPACE}
fw={500}
>
{t("Sign-in")}
</Anchor>
</Text>
)}
</AuthLayout>
);
}