Skip to content

Commit 37eb540

Browse files
committed
address comments
1 parent bc3ca78 commit 37eb540

File tree

6 files changed

+16
-28
lines changed

6 files changed

+16
-28
lines changed

apps/sim/app/api/invitations/[id]/reject/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
5151
actorEmail: session.user.email ?? undefined,
5252
action:
5353
inv.kind === 'workspace'
54-
? AuditAction.INVITATION_REVOKED
54+
? AuditAction.INVITATION_REJECTED
5555
: AuditAction.ORG_INVITATION_REJECTED,
5656
resourceType:
5757
inv.kind === 'workspace' ? AuditResourceType.WORKSPACE : AuditResourceType.ORGANIZATION,

apps/sim/app/api/invitations/[id]/resend/route.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { db } from '@sim/db'
2-
import { member, user } from '@sim/db/schema'
2+
import { user } from '@sim/db/schema'
33
import { createLogger } from '@sim/logger'
4-
import { and, eq } from 'drizzle-orm'
4+
import { eq } from 'drizzle-orm'
55
import { type NextRequest, NextResponse } from 'next/server'
66
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
77
import { getSession } from '@/lib/auth'
88
import { getOrganizationSubscription } from '@/lib/billing/core/billing'
9+
import { isOrganizationOwnerOrAdmin } from '@/lib/billing/core/organization'
910
import { isEnterprise, isTeam } from '@/lib/billing/plan-helpers'
1011
import { hasUsableSubscriptionStatus } from '@/lib/billing/subscriptions/utils'
1112
import { getInvitationById } from '@/lib/invitations/core'
@@ -19,15 +20,6 @@ import { getWorkspaceInvitePolicy } from '@/lib/workspaces/policy'
1920

2021
const logger = createLogger('InvitationResendAPI')
2122

22-
async function isOrgAdmin(userId: string, organizationId: string): Promise<boolean> {
23-
const [row] = await db
24-
.select({ role: member.role })
25-
.from(member)
26-
.where(and(eq(member.userId, userId), eq(member.organizationId, organizationId)))
27-
.limit(1)
28-
return row?.role === 'owner' || row?.role === 'admin'
29-
}
30-
3123
export async function POST(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
3224
const { id } = await params
3325
const session = await getSession()
@@ -47,7 +39,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
4739

4840
let canResend = false
4941
if (inv.organizationId) {
50-
canResend = await isOrgAdmin(session.user.id, inv.organizationId)
42+
canResend = await isOrganizationOwnerOrAdmin(session.user.id, inv.organizationId)
5143
}
5244
if (!canResend && inv.grants.length > 0) {
5345
const adminChecks = await Promise.all(

apps/sim/app/api/invitations/[id]/route.ts

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
11
import { db } from '@sim/db'
2-
import { invitation, invitationWorkspaceGrant, member } from '@sim/db/schema'
2+
import { invitation, invitationWorkspaceGrant } from '@sim/db/schema'
33
import { createLogger } from '@sim/logger'
44
import { and, eq } from 'drizzle-orm'
55
import { type NextRequest, NextResponse } from 'next/server'
66
import { z } from 'zod'
77
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
88
import { getSession } from '@/lib/auth'
9+
import { isOrganizationOwnerOrAdmin } from '@/lib/billing/core/organization'
910
import { cancelInvitation, getInvitationById, normalizeEmail } from '@/lib/invitations/core'
1011
import { hasWorkspaceAdminAccess } from '@/lib/workspaces/permissions/utils'
1112

1213
const logger = createLogger('InvitationsAPI')
1314

14-
async function isOrgAdmin(userId: string, organizationId: string): Promise<boolean> {
15-
const [row] = await db
16-
.select({ role: member.role })
17-
.from(member)
18-
.where(and(eq(member.userId, userId), eq(member.organizationId, organizationId)))
19-
.limit(1)
20-
return row?.role === 'owner' || row?.role === 'admin'
21-
}
22-
2315
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
2416
const { id } = await params
2517
const session = await getSession()
@@ -40,7 +32,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
4032

4133
let hasAdminView = false
4234
if (inv.organizationId) {
43-
hasAdminView = await isOrgAdmin(session.user.id, inv.organizationId)
35+
hasAdminView = await isOrganizationOwnerOrAdmin(session.user.id, inv.organizationId)
4436
}
4537
if (!hasAdminView && inv.grants.length > 0) {
4638
const adminChecks = await Promise.all(
@@ -131,7 +123,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
131123
{ status: 400 }
132124
)
133125
}
134-
if (!(await isOrgAdmin(session.user.id, inv.organizationId))) {
126+
if (!(await isOrganizationOwnerOrAdmin(session.user.id, inv.organizationId))) {
135127
return NextResponse.json(
136128
{ error: 'Only an organization owner or admin can change invitation roles' },
137129
{ status: 403 }
@@ -181,7 +173,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
181173
actorId: session.user.id,
182174
actorName: session.user.name ?? undefined,
183175
actorEmail: session.user.email ?? undefined,
184-
action: AuditAction.ORG_INVITATION_CREATED,
176+
action: AuditAction.ORG_INVITATION_UPDATED,
185177
resourceType: AuditResourceType.ORGANIZATION,
186178
resourceId: inv.organizationId ?? inv.id,
187179
description: `Updated invitation for ${inv.email}`,
@@ -220,7 +212,7 @@ export async function DELETE(
220212

221213
let canCancel = false
222214
if (inv.organizationId) {
223-
canCancel = await isOrgAdmin(session.user.id, inv.organizationId)
215+
canCancel = await isOrganizationOwnerOrAdmin(session.user.id, inv.organizationId)
224216
}
225217
if (!canCancel && inv.grants.length > 0) {
226218
const adminChecks = await Promise.all(

apps/sim/lib/audit/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export const AuditAction = {
7070

7171
// Invitations
7272
INVITATION_ACCEPTED: 'invitation.accepted',
73+
INVITATION_REJECTED: 'invitation.rejected',
7374
INVITATION_RESENT: 'invitation.resent',
7475
INVITATION_REVOKED: 'invitation.revoked',
7576

@@ -118,6 +119,7 @@ export const AuditAction = {
118119
ORG_MEMBER_REMOVED: 'org_member.removed',
119120
ORG_MEMBER_ROLE_CHANGED: 'org_member.role_changed',
120121
ORG_INVITATION_CREATED: 'org_invitation.created',
122+
ORG_INVITATION_UPDATED: 'org_invitation.updated',
121123
ORG_INVITATION_ACCEPTED: 'org_invitation.accepted',
122124
ORG_INVITATION_REJECTED: 'org_invitation.rejected',
123125
ORG_INVITATION_CANCELLED: 'org_invitation.cancelled',

apps/sim/lib/core/config/feature-flags.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ try {
2929
} catch {
3030
// invalid URL — isHosted stays false
3131
}
32-
export const isHosted = true
32+
export const isHosted = appHostname === 'sim.ai' || appHostname.endsWith('.sim.ai')
3333

3434
/**
3535
* Is billing enforcement enabled

packages/testing/src/mocks/audit.mock.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const auditMock = {
7474
FORM_UPDATED: 'form.updated',
7575
FORM_DELETED: 'form.deleted',
7676
INVITATION_ACCEPTED: 'invitation.accepted',
77+
INVITATION_REJECTED: 'invitation.rejected',
7778
INVITATION_RESENT: 'invitation.resent',
7879
INVITATION_REVOKED: 'invitation.revoked',
7980
CONNECTOR_CREATED: 'connector.created',
@@ -102,6 +103,7 @@ export const auditMock = {
102103
ORG_MEMBER_REMOVED: 'org_member.removed',
103104
ORG_MEMBER_ROLE_CHANGED: 'org_member.role_changed',
104105
ORG_INVITATION_CREATED: 'org_invitation.created',
106+
ORG_INVITATION_UPDATED: 'org_invitation.updated',
105107
ORG_INVITATION_ACCEPTED: 'org_invitation.accepted',
106108
ORG_INVITATION_REJECTED: 'org_invitation.rejected',
107109
ORG_INVITATION_CANCELLED: 'org_invitation.cancelled',

0 commit comments

Comments
 (0)