Skip to content

Commit 9e91829

Browse files
committed
fixes
1 parent bc09332 commit 9e91829

31 files changed

Lines changed: 2532 additions & 2005 deletions

app/actions/auth.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"use server"
2+
3+
import { cookies } from "next/headers"
4+
import { redirect } from "next/navigation"
5+
import { getSessionCookieOptions } from "@/lib/auth"
6+
7+
export async function signOutAction() {
8+
const cookieStore = await cookies()
9+
const cookieOpts = getSessionCookieOptions()
10+
11+
cookieStore.set(cookieOpts.name, "", {
12+
httpOnly: cookieOpts.httpOnly,
13+
secure: cookieOpts.secure,
14+
sameSite: cookieOpts.sameSite,
15+
path: cookieOpts.path,
16+
maxAge: 0,
17+
})
18+
19+
redirect("/")
20+
}

app/admin/[orgSlug]/actions.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
"use server"
2+
3+
import { headers } from "next/headers"
4+
import { revalidatePath } from "next/cache"
5+
import { z } from "zod"
6+
import { recheckOpenPullRequestsAfterClaUpdate } from "@/lib/cla/recheck-open-prs"
7+
import { createAuditEvent, setOrganizationActive, updateOrganizationCla } from "@/lib/db/queries"
8+
import { authorizeOrgAccess } from "@/lib/server/org-access"
9+
import { getBaseUrlFromHeaders } from "@/lib/cla/signing"
10+
11+
const updateClaSchema = z.object({
12+
orgSlug: z.string().min(1),
13+
claMarkdown: z.string().min(1, "CLA text cannot be empty"),
14+
})
15+
16+
const toggleActiveSchema = z.object({
17+
orgSlug: z.string().min(1),
18+
isActive: z.boolean(),
19+
})
20+
21+
type ActionResult = {
22+
ok: boolean
23+
error?: string
24+
}
25+
26+
export async function updateClaAction(input: unknown): Promise<ActionResult> {
27+
const parsed = updateClaSchema.safeParse(input)
28+
if (!parsed.success) {
29+
return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid input" }
30+
}
31+
32+
const { orgSlug, claMarkdown } = parsed.data
33+
const access = await authorizeOrgAccess(orgSlug)
34+
if (!access.ok) {
35+
return { ok: false, error: access.message }
36+
}
37+
38+
const org = await updateOrganizationCla(orgSlug, claMarkdown)
39+
if (!org) {
40+
return { ok: false, error: "Organization not found" }
41+
}
42+
43+
const headerStore = await headers()
44+
const recheckSummary = await recheckOpenPullRequestsAfterClaUpdate({
45+
orgSlug,
46+
appBaseUrl: getBaseUrlFromHeaders(headerStore),
47+
installationId: org.installationId ?? undefined,
48+
})
49+
50+
await createAuditEvent({
51+
eventType: "cla.updated",
52+
orgId: org.id,
53+
userId: access.user.id,
54+
actorGithubId: access.user.githubId ?? null,
55+
actorGithubUsername: access.user.githubUsername,
56+
payload: {
57+
claSha256: org.claTextSha256,
58+
recheckSummary,
59+
},
60+
})
61+
62+
revalidatePath(`/admin/${orgSlug}`)
63+
revalidatePath("/admin")
64+
65+
return { ok: true }
66+
}
67+
68+
export async function toggleOrganizationActiveAction(input: unknown): Promise<ActionResult> {
69+
const parsed = toggleActiveSchema.safeParse(input)
70+
if (!parsed.success) {
71+
return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid input" }
72+
}
73+
74+
const { orgSlug, isActive } = parsed.data
75+
const access = await authorizeOrgAccess(orgSlug)
76+
if (!access.ok) {
77+
return { ok: false, error: access.message }
78+
}
79+
80+
const org = await setOrganizationActive(orgSlug, isActive)
81+
if (!org) {
82+
return { ok: false, error: "Organization not found" }
83+
}
84+
85+
await createAuditEvent({
86+
eventType: "organization.activation_changed",
87+
orgId: org.id,
88+
userId: access.user.id,
89+
actorGithubId: access.user.githubId ?? null,
90+
actorGithubUsername: access.user.githubUsername,
91+
payload: { isActive },
92+
})
93+
94+
revalidatePath(`/admin/${orgSlug}`)
95+
revalidatePath("/admin")
96+
97+
return { ok: true }
98+
}

0 commit comments

Comments
 (0)