Skip to content

Commit fb6c2ce

Browse files
wip
1 parent 05bb0c7 commit fb6c2ce

File tree

181 files changed

+281
-614
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+281
-614
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `domain` on the `Org` table. All the data in the column will be lost.
5+
6+
*/
7+
-- DropIndex
8+
DROP INDEX "Org_domain_key";
9+
10+
-- AlterTable
11+
ALTER TABLE "Org" DROP COLUMN "domain";

packages/db/prisma/schema.prisma

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ model AccountRequest {
265265
model Org {
266266
id Int @id @default(autoincrement())
267267
name String
268-
domain String @unique
269268
createdAt DateTime @default(now())
270269
updatedAt DateTime @updatedAt
271270
members UserToOrg[]

packages/web/src/__mocks__/prisma.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SINGLE_TENANT_ORG_DOMAIN, SINGLE_TENANT_ORG_ID, SINGLE_TENANT_ORG_NAME } from '@/lib/constants';
1+
import { SINGLE_TENANT_ORG_ID, SINGLE_TENANT_ORG_NAME } from '@/lib/constants';
22
import { Account, ApiKey, OAuthRefreshToken, OAuthToken, Org, PrismaClient, User } from '@prisma/client';
33
import { beforeEach, vi } from 'vitest';
44
import { mockDeep, mockReset } from 'vitest-mock-extended';
@@ -12,7 +12,6 @@ export const prisma = mockDeep<PrismaClient>();
1212
export const MOCK_ORG: Org = {
1313
id: SINGLE_TENANT_ORG_ID,
1414
name: SINGLE_TENANT_ORG_NAME,
15-
domain: SINGLE_TENANT_ORG_DOMAIN,
1615
createdAt: new Date(),
1716
updatedAt: new Date(),
1817
isOnboarded: true,

packages/web/src/actions.ts

Lines changed: 17 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { notFound, orgNotFound, ServiceError } from "@/lib/serviceError";
88
import { getOrgMetadata, isHttpError, isServiceError } from "@/lib/utils";
99
import { prisma } from "@/prisma";
1010
import { render } from "@react-email/components";
11-
import { generateApiKey, getTokenFromConfig, hashSecret } from "@sourcebot/shared";
12-
import { ApiKey, ConnectionSyncJobStatus, OrgRole, Prisma, RepoIndexingJobStatus, RepoIndexingJobType } from "@sourcebot/db";
11+
import { generateApiKey, getTokenFromConfig } from "@sourcebot/shared";
12+
import { ConnectionSyncJobStatus, OrgRole, Prisma, RepoIndexingJobStatus, RepoIndexingJobType } from "@sourcebot/db";
1313
import { createLogger } from "@sourcebot/shared";
1414
import { GiteaConnectionConfig } from "@sourcebot/schemas/v3/gitea.type";
1515
import { GithubConnectionConfig } from "@sourcebot/schemas/v3/github.type";
@@ -19,15 +19,14 @@ import { StatusCodes } from "http-status-codes";
1919
import { cookies } from "next/headers";
2020
import { createTransport } from "nodemailer";
2121
import { Octokit } from "octokit";
22-
import { getOrgFromDomain } from "./data/org";
2322
import InviteUserEmail from "./emails/inviteUserEmail";
2423
import JoinRequestApprovedEmail from "./emails/joinRequestApprovedEmail";
2524
import JoinRequestSubmittedEmail from "./emails/joinRequestSubmittedEmail";
26-
import { AGENTIC_SEARCH_TUTORIAL_DISMISSED_COOKIE_NAME, MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME, SOURCEBOT_SUPPORT_EMAIL } from "./lib/constants";
27-
import { ApiKeyPayload, RepositoryQuery } from "./lib/types";
25+
import { AGENTIC_SEARCH_TUTORIAL_DISMISSED_COOKIE_NAME, MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME, SINGLE_TENANT_ORG_ID, SOURCEBOT_SUPPORT_EMAIL } from "./lib/constants";
26+
import { RepositoryQuery } from "./lib/types";
2827
import { withAuth, withOptionalAuth, withAuth_skipOrgMembershipCheck } from "./middleware/withAuth";
2928
import { withMinimumOrgRole } from "./middleware/withMinimumOrgRole";
30-
import { getBrowsePath } from "./app/[domain]/browse/hooks/utils";
29+
import { getBrowsePath } from "./app/(app)/browse/hooks/utils";
3130
import { sew } from "@/middleware/sew";
3231

3332
const logger = createLogger('web-actions');
@@ -48,59 +47,6 @@ export const completeOnboarding = async (): Promise<{ success: boolean } | Servi
4847
}
4948
}));
5049

51-
export const verifyApiKey = async (apiKeyPayload: ApiKeyPayload): Promise<{ apiKey: ApiKey } | ServiceError> => sew(async () => {
52-
const parts = apiKeyPayload.apiKey.split("-");
53-
if (parts.length !== 2 || parts[0] !== "sourcebot") {
54-
return {
55-
statusCode: StatusCodes.BAD_REQUEST,
56-
errorCode: ErrorCode.INVALID_API_KEY,
57-
message: "Invalid API key",
58-
} satisfies ServiceError;
59-
}
60-
61-
const hash = hashSecret(parts[1])
62-
const apiKey = await prisma.apiKey.findUnique({
63-
where: {
64-
hash,
65-
},
66-
});
67-
68-
if (!apiKey) {
69-
return {
70-
statusCode: StatusCodes.UNAUTHORIZED,
71-
errorCode: ErrorCode.INVALID_API_KEY,
72-
message: "Invalid API key",
73-
} satisfies ServiceError;
74-
}
75-
76-
const apiKeyTargetOrg = await prisma.org.findUnique({
77-
where: {
78-
domain: apiKeyPayload.domain,
79-
},
80-
});
81-
82-
if (!apiKeyTargetOrg) {
83-
return {
84-
statusCode: StatusCodes.UNAUTHORIZED,
85-
errorCode: ErrorCode.INVALID_API_KEY,
86-
message: `Invalid API key payload. Provided domain ${apiKeyPayload.domain} does not exist.`,
87-
} satisfies ServiceError;
88-
}
89-
90-
if (apiKey.orgId !== apiKeyTargetOrg.id) {
91-
return {
92-
statusCode: StatusCodes.UNAUTHORIZED,
93-
errorCode: ErrorCode.INVALID_API_KEY,
94-
message: `Invalid API key payload. Provided domain ${apiKeyPayload.domain} does not match the API key's org.`,
95-
} satisfies ServiceError;
96-
}
97-
98-
return {
99-
apiKey,
100-
}
101-
});
102-
103-
10450
export const createApiKey = async (name: string): Promise<{ key: string } | ServiceError> => sew(() =>
10551
withAuth(async ({ org, user, role, prisma }) => {
10652
if ((env.DISABLE_API_KEY_CREATION_FOR_NON_OWNER_USERS === 'true' || env.DISABLE_API_KEY_USAGE_FOR_NON_OWNER_USERS === 'true') && role !== OrgRole.OWNER) {
@@ -188,7 +134,7 @@ export const deleteApiKey = async (name: string): Promise<{ success: boolean } |
188134
type: "user"
189135
},
190136
target: {
191-
id: org.domain,
137+
id: org.id.toString(),
192138
type: "org"
193139
},
194140
orgId: org.id,
@@ -600,7 +546,7 @@ export const createInvites = async (emails: string[]): Promise<{ success: boolea
600546
});
601547
}
602548

603-
const hasAvailability = await orgHasAvailability(org.domain);
549+
const hasAvailability = await orgHasAvailability();
604550
if (!hasAvailability) {
605551
await auditService.createAudit({
606552
action: "user.invite_failed",
@@ -807,7 +753,6 @@ export const getMe = async () => sew(() =>
807753
memberships: userWithOrgs.orgs.map((org) => ({
808754
id: org.orgId,
809755
role: org.role,
810-
domain: org.org.domain,
811756
name: org.org.name,
812757
}))
813758
}
@@ -847,7 +792,7 @@ export const redeemInvite = async (inviteId: string): Promise<{ success: boolean
847792
}
848793

849794

850-
const hasAvailability = await orgHasAvailability(invite.org.domain);
795+
const hasAvailability = await orgHasAvailability();
851796
if (!hasAvailability) {
852797
await failAuditCallback("Organization is at max capacity");
853798
return {
@@ -911,7 +856,6 @@ export const getInviteInfo = async (inviteId: string) => sew(() =>
911856
id: invite.id,
912857
orgName: invite.org.name,
913858
orgImageUrl: invite.org.imageUrl ?? undefined,
914-
orgDomain: invite.org.domain,
915859
host: {
916860
name: invite.host.name ?? undefined,
917861
email: invite.host.email!,
@@ -983,7 +927,7 @@ export const getOrgAccountRequests = async () => sew(() =>
983927
}));
984928
}));
985929

986-
export const createAccountRequest = async (userId: string, domain: string) => sew(async () => {
930+
export const createAccountRequest = async (userId: string) => sew(async () => {
987931
const user = await prisma.user.findUnique({
988932
where: {
989933
id: userId,
@@ -996,7 +940,7 @@ export const createAccountRequest = async (userId: string, domain: string) => se
996940

997941
const org = await prisma.org.findUnique({
998942
where: {
999-
domain,
943+
id: SINGLE_TENANT_ORG_ID,
1000944
},
1001945
});
1002946

@@ -1057,7 +1001,6 @@ export const createAccountRequest = async (userId: string, domain: string) => se
10571001
avatarUrl: user.image ?? undefined,
10581002
},
10591003
orgName: org.name,
1060-
orgDomain: org.domain,
10611004
orgImageUrl: org.imageUrl ?? undefined,
10621005
}));
10631006

@@ -1086,10 +1029,10 @@ export const createAccountRequest = async (userId: string, domain: string) => se
10861029
}
10871030
});
10881031

1089-
export const getMemberApprovalRequired = async (domain: string): Promise<boolean | ServiceError> => sew(async () => {
1032+
export const getMemberApprovalRequired = async (): Promise<boolean | ServiceError> => sew(async () => {
10901033
const org = await prisma.org.findUnique({
10911034
where: {
1092-
domain,
1035+
id: SINGLE_TENANT_ORG_ID,
10931036
},
10941037
});
10951038

@@ -1182,7 +1125,6 @@ export const approveAccountRequest = async (requestId: string) => sew(async () =
11821125
avatarUrl: request.requestedBy.image ?? undefined,
11831126
},
11841127
orgName: org.name,
1185-
orgDomain: org.domain
11861128
}));
11871129

11881130
const transport = createTransport(smtpConnectionUrl);
@@ -1191,7 +1133,7 @@ export const approveAccountRequest = async (requestId: string) => sew(async () =
11911133
from: env.EMAIL_FROM_ADDRESS,
11921134
subject: `Your request to join ${org.name} has been approved`,
11931135
html,
1194-
text: `Your request to join ${org.name} on Sourcebot has been approved. You can now access the organization at ${env.AUTH_URL}/${org.domain}`,
1136+
text: `Your request to join ${org.name} on Sourcebot has been approved. You can now access the organization at ${env.AUTH_URL}`,
11951137
});
11961138

11971139
const failed = result.rejected.concat(result.pending).filter(Boolean);
@@ -1334,8 +1276,10 @@ export const getRepoImage = async (repoId: number): Promise<ArrayBuffer | Servic
13341276
})
13351277
});
13361278

1337-
export const getAnonymousAccessStatus = async (domain: string): Promise<boolean | ServiceError> => sew(async () => {
1338-
const org = await getOrgFromDomain(domain);
1279+
export const getAnonymousAccessStatus = async (): Promise<boolean | ServiceError> => sew(async () => {
1280+
const org = await prisma.org.findUnique({
1281+
where: { id: SINGLE_TENANT_ORG_ID },
1282+
});
13391283
if (!org) {
13401284
return {
13411285
statusCode: StatusCodes.NOT_FOUND,

packages/web/src/app/[domain]/agents/page.tsx renamed to packages/web/src/app/(app)/agents/page.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,10 @@ const agents = [
1313
},
1414
];
1515

16-
export default async function AgentsPage(props: { params: Promise<{ domain: string }> }) {
17-
const params = await props.params;
18-
19-
const {
20-
domain
21-
} = params;
22-
16+
export default async function AgentsPage() {
2317
return (
2418
<div className="flex flex-col items-center overflow-hidden min-h-screen">
25-
<NavigationMenu domain={domain} />
19+
<NavigationMenu />
2620
<div className="w-full max-w-6xl px-4 mt-12 mb-24">
2721
<div
2822
className={

packages/web/src/app/[domain]/askgh/[owner]/[repo]/api.ts renamed to packages/web/src/app/(app)/askgh/[owner]/[repo]/api.ts

File renamed without changes.

packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/landingPage.tsx renamed to packages/web/src/app/(app)/askgh/[owner]/[repo]/components/landingPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import Image from 'next/image';
4-
import { SearchModeSelector } from "@/app/[domain]/components/searchModeSelector";
4+
import { SearchModeSelector } from "@/app/(app)/components/searchModeSelector";
55
import { Separator } from "@/components/ui/separator";
66
import { ChatBox } from "@/features/chat/components/chatBox";
77
import { ChatBoxToolbar } from "@/features/chat/components/chatBox/chatBoxToolbar";

packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx renamed to packages/web/src/app/(app)/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx

File renamed without changes.

packages/web/src/app/[domain]/askgh/[owner]/[repo]/page.tsx renamed to packages/web/src/app/(app)/askgh/[owner]/[repo]/page.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { addGithubRepo } from "@/features/workerApi/actions";
22
import { isServiceError } from "@/lib/utils";
33
import { ServiceErrorException } from "@/lib/serviceError";
44
import { prisma } from "@/prisma";
5-
import { SINGLE_TENANT_ORG_ID } from "@/lib/constants";
65
import { getRepoInfo } from "./api";
76
import { CustomSlateEditor } from "@/features/chat/customSlateEditor";
87
import { RepoIndexedGuard } from "./components/repoIndexedGuard";
@@ -24,7 +23,6 @@ export default async function GitHubRepoPage(props: PageProps) {
2423
const displayName = `${owner}/${repo}`;
2524
const existingRepo = await prisma.repo.findFirst({
2625
where: {
27-
orgId: SINGLE_TENANT_ORG_ID,
2826
displayName: displayName,
2927
external_codeHostType: 'github',
3028
external_codeHostUrl: 'https://github.com',

packages/web/src/app/[domain]/askgh/[owner]/[repo]/types.ts renamed to packages/web/src/app/(app)/askgh/[owner]/[repo]/types.ts

File renamed without changes.

0 commit comments

Comments
 (0)