Skip to content

Commit 3a690ec

Browse files
committed
fix webhooks
1 parent 43dea2e commit 3a690ec

File tree

13 files changed

+169
-30
lines changed

13 files changed

+169
-30
lines changed

ui/src/api/orchestrator_orgs.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ export async function getOrgSettings(
4646

4747
if (!response.ok) {
4848
const text = await response.text()
49-
console.log(text)
5049
throw new Error('Failed to get organization settings')
5150
}
5251

ui/src/api/orchestrator_users.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export async function syncUserToBackend(userId: string, userEmail: string, orgId
1515
})
1616
})
1717

18+
if (response.status === 409) {
19+
console.log("User already exists in orchestrator")
20+
return response.json();
21+
}
22+
1823
if (!response.ok) {
1924
throw new Error(`Failed to sync user: ${response.statusText}`);
2025
}

ui/src/api/statesman_orgs.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11

22

3-
export async function syncOrgToStatesman(orgId: string, orgName: string, userId: string, adminEmail: string) {
3+
export async function syncOrgToStatesman(orgId: string, orgName: string, displayName: string, userId: string, adminEmail: string) {
44
const response = await fetch(`${process.env.STATESMAN_BACKEND_URL}/internal/api/orgs`, {
55
method: 'POST',
66
headers: {
77
'Content-Type': 'application/json',
88
'Authorization': `Bearer ${process.env.STATESMAN_BACKEND_WEBHOOK_SECRET}`,
9-
'X-Org-ID': orgId,
9+
'X-Org-ID': "",
1010
'X-User-ID': userId,
1111
'X-Email': adminEmail,
1212
},
1313
body: JSON.stringify({
14-
"org_id": orgId,
14+
"external_org_id": orgId,
1515
"name": orgName,
16+
"display_name": displayName,
1617
"created_by": adminEmail,
1718
})
1819
})
1920

20-
console.log(orgId)
21-
console.log(orgName)
22-
console.log(userId)
23-
console.log(adminEmail)
21+
if (response.status === 409) {
22+
console.log("User already exists in statesman")
23+
return response.json();
24+
}
2425

2526
if (!response.ok) {
2627
throw new Error(`Failed to sync organization to statesman: ${response.statusText}`);

ui/src/api/statesman_users.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ export async function syncUserToStatesman(userId: string, userEmail: string, org
1616
})
1717
})
1818

19+
if (response.status === 409) {
20+
console.log("User already exists in statesman")
21+
return response.json();
22+
}
23+
1924
if (!response.ok) {
25+
console.log(response.text())
2026
throw new Error(`Failed to sync user: ${response.statusText}`);
2127
}
2228

ui/src/authkit/serverFunctions.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { getWorkOS } from './ssr/workos';
66
import type { GetAuthURLOptions, NoUserInfo, UserInfo } from './ssr/interfaces';
77
import { Organization } from '@workos-inc/node';
88
import { WidgetScope } from 'node_modules/@workos-inc/node/lib/widgets/interfaces/get-token';
9+
import { syncOrgToBackend } from '@/api/orchestrator_orgs';
10+
import { syncOrgToStatesman } from '@/api/statesman_orgs';
911

1012
export const getAuthorizationUrl = createServerFn({ method: 'GET' })
1113
.inputValidator((options?: GetAuthURLOptions) => options)
@@ -29,8 +31,8 @@ export const getOrganisationDetails = createServerFn({method: 'GET'})
2931

3032

3133
export const createOrganization = createServerFn({method: 'POST'})
32-
.inputValidator((data: {name: string, userId: string}) => data)
33-
.handler(async ({data: {name, userId}}) : Promise<Organization> => {
34+
.inputValidator((data: {name: string, userId: string, email: string}) => data)
35+
.handler(async ({data: {name, userId, email}}) : Promise<Organization> => {
3436
try {
3537
const organization = await getWorkOS().organizations.createOrganization({ name: name });
3638

@@ -40,6 +42,14 @@ export const createOrganization = createServerFn({method: 'POST'})
4042
roleSlug: "admin",
4143
});
4244

45+
try {
46+
await syncOrgToBackend(organization.id, organization.name, email);
47+
await syncOrgToStatesman(organization.id, organization.name, organization.name, userId, email);
48+
} catch (error) {
49+
console.error('Error syncing organization to backend:', error);
50+
throw error;
51+
}
52+
4353
return organization;
4454
} catch (error) {
4555
console.error('Error creating organization:', error);

ui/src/authkit/ssr/workos_api.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ export async function getOrganisationDetails(orgId: string) {
4343
}
4444
}
4545

46+
export async function getOranizationsForUser(userId: string) {
47+
try {
48+
const memberships = await getWorkOS().userManagement.listOrganizationMemberships({
49+
userId: userId,
50+
});
51+
return memberships.data;
52+
} catch (error) {
53+
console.error('Error fetching user organizations:', error);
54+
throw error;
55+
}
56+
}
57+
4658
export async function listUserOrganizationInvitations(email: string) {
4759
try {
4860
const invitations = await getWorkOS().userManagement.listInvitations({

ui/src/components/CreateOrganisationButtonWOS.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ import { useState } from "react";
77
import { useToast } from "@/hooks/use-toast";
88

99

10-
export default function CreateOrganizationBtn({ userId }: { userId: string }) {
10+
export default function CreateOrganizationBtn({ userId, email }: { userId: string, email: string }) {
1111
const [name, setName] = useState("");
1212
const [open, setOpen] = useState(false);
1313
const { toast } = useToast();
1414
async function handleSubmit(e: React.FormEvent) {
1515
e.preventDefault();
1616

1717
try {
18-
const organization = await createOrganization({ data: { name: name, userId: userId } });
18+
const organization = await createOrganization({ data: { name: name, userId: userId, email: email } });
1919
toast({
2020
title: "Organization created",
2121
description: "The page will now reload to refresh organisations list. To use this new organization, select it from the list.",

ui/src/components/WorkosSettings.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ type LoaderData = {
2626

2727
type WorkosSettingsProps = {
2828
userId: string;
29+
email: string;
2930
organisationId: string;
3031
role: 'admin' | 'member' | string;
3132
};
3233

33-
export function WorkosSettings({ userId, organisationId, role }: WorkosSettingsProps) {
34+
export function WorkosSettings({ userId, email, organisationId, role }: WorkosSettingsProps) {
3435
const [authToken, setAuthToken] = React.useState<string | null>(null);
3536
const [error, setError] = React.useState<string | null>(null);
3637
const [loading, setLoading] = React.useState(true);
@@ -65,7 +66,7 @@ export function WorkosSettings({ userId, organisationId, role }: WorkosSettingsP
6566
/>
6667
<div className="h-4" />
6768
{/* Add your org creation UI here */}
68-
<CreateOrganizationBtn userId={userId} />
69+
<CreateOrganizationBtn userId={userId} email={email} />
6970
<div className="h-4" />
7071
<UserProfile authToken={authToken} />
7172
<div className="h-4" />

ui/src/routeTree.gen.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { Route as rootRouteImport } from './routes/__root'
1212
import { Route as LogoutRouteImport } from './routes/logout'
1313
import { Route as AuthenticatedRouteImport } from './routes/_authenticated'
1414
import { Route as IndexRouteImport } from './routes/index'
15+
import { Route as TfeSplatRouteImport } from './routes/tfe/$'
16+
import { Route as WellKnownTerraform_jsonRouteImport } from './routes/_well-known.terraform_json'
1517
import { Route as OrchestratorJob_artefactsRouteImport } from './routes/_orchestrator/job_artefacts'
1618
import { Route as AuthenticatedDashboardRouteImport } from './routes/_authenticated/_dashboard'
1719
import { Route as OrchestratorGithubWebhookRouteImport } from './routes/orchestrator/github/webhook'
@@ -54,6 +56,16 @@ const IndexRoute = IndexRouteImport.update({
5456
path: '/',
5557
getParentRoute: () => rootRouteImport,
5658
} as any)
59+
const TfeSplatRoute = TfeSplatRouteImport.update({
60+
id: '/tfe/$',
61+
path: '/tfe/$',
62+
getParentRoute: () => rootRouteImport,
63+
} as any)
64+
const WellKnownTerraform_jsonRoute = WellKnownTerraform_jsonRouteImport.update({
65+
id: '/_well-known/terraform_json',
66+
path: '/terraform_json',
67+
getParentRoute: () => rootRouteImport,
68+
} as any)
5769
const OrchestratorJob_artefactsRoute =
5870
OrchestratorJob_artefactsRouteImport.update({
5971
id: '/_orchestrator/job_artefacts',
@@ -218,6 +230,8 @@ export interface FileRoutesByFullPath {
218230
'/': typeof IndexRoute
219231
'/logout': typeof LogoutRoute
220232
'/job_artefacts': typeof OrchestratorJob_artefactsRoute
233+
'/terraform_json': typeof WellKnownTerraform_jsonRoute
234+
'/tfe/$': typeof TfeSplatRoute
221235
'/api/auth/callback': typeof ApiAuthCallbackRoute
222236
'/orchestrator/github/callback': typeof OrchestratorGithubCallbackRoute
223237
'/orchestrator/github/webhook': typeof OrchestratorGithubWebhookRoute
@@ -248,6 +262,8 @@ export interface FileRoutesByTo {
248262
'/': typeof IndexRoute
249263
'/logout': typeof LogoutRoute
250264
'/job_artefacts': typeof OrchestratorJob_artefactsRoute
265+
'/terraform_json': typeof WellKnownTerraform_jsonRoute
266+
'/tfe/$': typeof TfeSplatRoute
251267
'/api/auth/callback': typeof ApiAuthCallbackRoute
252268
'/orchestrator/github/callback': typeof OrchestratorGithubCallbackRoute
253269
'/orchestrator/github/webhook': typeof OrchestratorGithubWebhookRoute
@@ -279,6 +295,8 @@ export interface FileRoutesById {
279295
'/logout': typeof LogoutRoute
280296
'/_authenticated/_dashboard': typeof AuthenticatedDashboardRouteWithChildren
281297
'/_orchestrator/job_artefacts': typeof OrchestratorJob_artefactsRoute
298+
'/_well-known/terraform_json': typeof WellKnownTerraform_jsonRoute
299+
'/tfe/$': typeof TfeSplatRoute
282300
'/api/auth/callback': typeof ApiAuthCallbackRoute
283301
'/orchestrator/github/callback': typeof OrchestratorGithubCallbackRoute
284302
'/orchestrator/github/webhook': typeof OrchestratorGithubWebhookRoute
@@ -311,6 +329,8 @@ export interface FileRouteTypes {
311329
| '/'
312330
| '/logout'
313331
| '/job_artefacts'
332+
| '/terraform_json'
333+
| '/tfe/$'
314334
| '/api/auth/callback'
315335
| '/orchestrator/github/callback'
316336
| '/orchestrator/github/webhook'
@@ -341,6 +361,8 @@ export interface FileRouteTypes {
341361
| '/'
342362
| '/logout'
343363
| '/job_artefacts'
364+
| '/terraform_json'
365+
| '/tfe/$'
344366
| '/api/auth/callback'
345367
| '/orchestrator/github/callback'
346368
| '/orchestrator/github/webhook'
@@ -371,6 +393,8 @@ export interface FileRouteTypes {
371393
| '/logout'
372394
| '/_authenticated/_dashboard'
373395
| '/_orchestrator/job_artefacts'
396+
| '/_well-known/terraform_json'
397+
| '/tfe/$'
374398
| '/api/auth/callback'
375399
| '/orchestrator/github/callback'
376400
| '/orchestrator/github/webhook'
@@ -403,6 +427,8 @@ export interface RootRouteChildren {
403427
AuthenticatedRoute: typeof AuthenticatedRouteWithChildren
404428
LogoutRoute: typeof LogoutRoute
405429
OrchestratorJob_artefactsRoute: typeof OrchestratorJob_artefactsRoute
430+
WellKnownTerraform_jsonRoute: typeof WellKnownTerraform_jsonRoute
431+
TfeSplatRoute: typeof TfeSplatRoute
406432
ApiAuthCallbackRoute: typeof ApiAuthCallbackRoute
407433
OrchestratorGithubCallbackRoute: typeof OrchestratorGithubCallbackRoute
408434
OrchestratorGithubWebhookRoute: typeof OrchestratorGithubWebhookRoute
@@ -439,6 +465,20 @@ declare module '@tanstack/react-router' {
439465
preLoaderRoute: typeof IndexRouteImport
440466
parentRoute: typeof rootRouteImport
441467
}
468+
'/tfe/$': {
469+
id: '/tfe/$'
470+
path: '/tfe/$'
471+
fullPath: '/tfe/$'
472+
preLoaderRoute: typeof TfeSplatRouteImport
473+
parentRoute: typeof rootRouteImport
474+
}
475+
'/_well-known/terraform_json': {
476+
id: '/_well-known/terraform_json'
477+
path: '/terraform_json'
478+
fullPath: '/terraform_json'
479+
preLoaderRoute: typeof WellKnownTerraform_jsonRouteImport
480+
parentRoute: typeof rootRouteImport
481+
}
442482
'/_orchestrator/job_artefacts': {
443483
id: '/_orchestrator/job_artefacts'
444484
path: '/job_artefacts'
@@ -738,6 +778,8 @@ const rootRouteChildren: RootRouteChildren = {
738778
AuthenticatedRoute: AuthenticatedRouteWithChildren,
739779
LogoutRoute: LogoutRoute,
740780
OrchestratorJob_artefactsRoute: OrchestratorJob_artefactsRoute,
781+
WellKnownTerraform_jsonRoute: WellKnownTerraform_jsonRoute,
782+
TfeSplatRoute: TfeSplatRoute,
741783
ApiAuthCallbackRoute: ApiAuthCallbackRoute,
742784
OrchestratorGithubCallbackRoute: OrchestratorGithubCallbackRoute,
743785
OrchestratorGithubWebhookRoute: OrchestratorGithubWebhookRoute,

ui/src/routes/_authenticated/_dashboard/dashboard/settings.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ function RouteComponent() {
1616
const { user, role, organisationId } = Route.useLoaderData()
1717

1818
return (
19-
<WorkosSettings userId={user?.id || ''} role={role || ''} organisationId={organisationId || ''} />
19+
<WorkosSettings userId={user?.id || ''} email={user?.email || ''} role={role || ''} organisationId={organisationId || ''} />
2020
)
2121
}

0 commit comments

Comments
 (0)