Skip to content

Commit 75eb00d

Browse files
authored
Merge pull request #914 from trycompai/mariano/comp-166-osquery-agent-integration
[dev] [Marfuen] mariano/comp-166-osquery-agent-integration
2 parents 3066213 + f7a5590 commit 75eb00d

10 files changed

Lines changed: 1386 additions & 1283 deletions

File tree

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,8 @@
2020
},
2121
"editor.codeActionsOnSave": {
2222
"source.fixAll": "explicit"
23+
},
24+
"[typescriptreact]": {
25+
"editor.defaultFormatter": "esbenp.prettier-vscode"
2326
}
2427
}

apps/app/src/app/(app)/[orgId]/people/layout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getPostHogClient } from "@/app/posthog";
12
import { AppOnboarding } from "@/components/app-onboarding";
23
import { auth } from "@/utils/auth";
34
import { db } from "@comp/db";
@@ -34,7 +35,10 @@ export default async function Layout({
3435
return roles.includes("employee");
3536
});
3637

37-
const isFleetEnabled = process.env.NEXT_PUBLIC_FLEET_ENABLED === "true";
38+
const isFleetEnabled = await getPostHogClient()?.isFeatureEnabled(
39+
"is-fleet-enabled",
40+
session?.session.userId,
41+
);
3842

3943
return (
4044
<div className="m-auto max-w-[1200px]">

apps/portal/src/app/[locale]/(app)/(home)/[orgId]/components/EmployeeTasksList.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface EmployeeTasksListProps {
2222
member: Member;
2323
fleetPolicies: FleetPolicy[];
2424
host: Host;
25+
isFleetEnabled: boolean;
2526
}
2627

2728
export const EmployeeTasksList = ({
@@ -30,6 +31,7 @@ export const EmployeeTasksList = ({
3031
member,
3132
fleetPolicies,
3233
host,
34+
isFleetEnabled,
3335
}: EmployeeTasksListProps) => {
3436
const [isDownloading, setIsDownloading] = useState(false);
3537

@@ -70,14 +72,13 @@ export const EmployeeTasksList = ({
7072
};
7173

7274
const hasPolicies = fleetPolicies.length;
73-
const fleetEnabled = process.env.NEXT_PUBLIC_FLEET_ENABLED === "true";
7475

7576
return (
7677
<Tabs defaultValue="policies">
7778
<TabsList className="mb-1 h-auto w-full justify-start rounded-sm border-b-[1px] bg-transparent p-0 pb-4">
7879
<TabsTrigger value="policies">Policies</TabsTrigger>
7980
<TabsTrigger value="training">Training</TabsTrigger>
80-
{fleetEnabled && <TabsTrigger value="device">Device</TabsTrigger>}
81+
{isFleetEnabled && <TabsTrigger value="device">Device</TabsTrigger>}
8182
</TabsList>
8283
<TabsContent value="policies" className="py-2">
8384
<PolicyList policies={policies} member={member} />
@@ -86,7 +87,7 @@ export const EmployeeTasksList = ({
8687
<VideoCarousel videos={trainingVideos} member={member} />
8788
</TabsContent>
8889
<TabsContent value="device" className="py-2">
89-
{fleetEnabled && hasPolicies ? (
90+
{isFleetEnabled && hasPolicies ? (
9091
<Card>
9192
<CardHeader>
9293
<CardTitle>{host.computer_name}'s Policies</CardTitle>

apps/portal/src/app/[locale]/(app)/(home)/[orgId]/components/OrganizationDashboard.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ interface OrganizationDashboardProps {
1515
member: MemberWithUserOrg; // Pass the full member object for user info etc.
1616
fleetPolicies: FleetPolicy[];
1717
host: Host;
18+
isFleetEnabled: boolean;
1819
}
1920

2021
export async function OrganizationDashboard({
2122
organizationId,
2223
member,
2324
fleetPolicies,
2425
host,
26+
isFleetEnabled,
2527
}: OrganizationDashboardProps) {
2628
// Fetch policies specific to the selected organization
2729
const policies = await db.policy.findMany({
@@ -74,6 +76,7 @@ export async function OrganizationDashboard({
7476
member={member} // Pass the member object down
7577
fleetPolicies={fleetPolicies}
7678
host={host}
79+
isFleetEnabled={isFleetEnabled ?? false}
7780
/>
7881
</div>
7982
);

apps/portal/src/app/[locale]/(app)/(home)/[orgId]/page.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { headers } from "next/headers";
55
import { redirect } from "next/navigation";
66
import { fleet } from "@/utils/fleet";
77
import type { Member } from "@comp/db/types";
8+
import { getPostHogClient } from "@/app/posthog";
89

910
export default async function OrganizationPage({
1011
params,
@@ -37,6 +38,10 @@ export default async function OrganizationPage({
3738
}
3839

3940
const { fleetPolicies, device } = await getFleetPolicies(member);
41+
const isFleetEnabled = await getPostHogClient()?.isFeatureEnabled(
42+
"is-fleet-enabled",
43+
session?.user.id,
44+
);
4045

4146
return (
4247
<OrganizationDashboard
@@ -45,6 +50,7 @@ export default async function OrganizationPage({
4550
member={member}
4651
fleetPolicies={fleetPolicies}
4752
host={device}
53+
isFleetEnabled={isFleetEnabled ?? false}
4854
/>
4955
);
5056
}

apps/portal/src/app/posthog.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"use server";
2+
3+
import { Properties } from "posthog-js";
4+
import { PostHog } from "posthog-node";
5+
6+
let posthogInstance: PostHog | null = null;
7+
8+
function getPostHogClient(): PostHog | null {
9+
if (posthogInstance) {
10+
return posthogInstance;
11+
}
12+
13+
const apiKey = process.env.NEXT_PUBLIC_POSTHOG_KEY;
14+
const apiHost = process.env.NEXT_PUBLIC_POSTHOG_HOST;
15+
16+
if (apiKey && apiHost) {
17+
posthogInstance = new PostHog(apiKey, {
18+
flushAt: 1,
19+
flushInterval: 0,
20+
});
21+
return posthogInstance;
22+
}
23+
24+
// If keys are not set, warn and return null
25+
console.warn(
26+
"PostHog keys (NEXT_PUBLIC_POSTHOG_KEY, NEXT_PUBLIC_POSTHOG_HOST) are not set, tracking is disabled.",
27+
);
28+
return null;
29+
}
30+
31+
// Export the getter function as the primary way to access the client
32+
export { getPostHogClient };
33+
34+
export async function track(
35+
distinctId: string,
36+
eventName: string,
37+
properties?: Properties,
38+
) {
39+
const client = getPostHogClient();
40+
if (!client) return;
41+
42+
console.log("[PostHog]: Tracking server side event:", eventName);
43+
44+
client.capture({
45+
distinctId,
46+
event: eventName,
47+
properties,
48+
});
49+
}
50+
51+
export async function identify(distinctId: string, properties?: Properties) {
52+
const client = getPostHogClient();
53+
if (!client) return;
54+
55+
client.identify({
56+
distinctId,
57+
properties,
58+
});
59+
}
60+
61+
export async function getFeatureFlags(distinctId: string) {
62+
const client = getPostHogClient();
63+
if (!client) return {};
64+
65+
const flags = await client.getAllFlags(distinctId);
66+
return flags;
67+
}

0 commit comments

Comments
 (0)