Skip to content

Commit 7b4597c

Browse files
committed
Merge branch 'staging' into fix/remove-org-fallbacks
2 parents 75ce65c + 99e0b81 commit 7b4597c

File tree

3 files changed

+1
-147
lines changed

3 files changed

+1
-147
lines changed

apps/sim/app/api/organizations/[id]/seats/route.ts

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -258,74 +258,3 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
258258
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
259259
}
260260
}
261-
262-
/**
263-
* GET /api/organizations/[id]/seats
264-
* Get current seat information for an organization
265-
*/
266-
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
267-
try {
268-
const session = await getSession()
269-
270-
if (!session?.user?.id) {
271-
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
272-
}
273-
274-
const { id: organizationId } = await params
275-
276-
// Verify user has access to this organization
277-
const memberEntry = await db
278-
.select()
279-
.from(member)
280-
.where(and(eq(member.organizationId, organizationId), eq(member.userId, session.user.id)))
281-
.limit(1)
282-
283-
if (memberEntry.length === 0) {
284-
return NextResponse.json(
285-
{ error: 'Forbidden - Not a member of this organization' },
286-
{ status: 403 }
287-
)
288-
}
289-
290-
// Get subscription data
291-
const subscriptionRecord = await db
292-
.select()
293-
.from(subscription)
294-
.where(and(eq(subscription.referenceId, organizationId), eq(subscription.status, 'active')))
295-
.limit(1)
296-
297-
if (subscriptionRecord.length === 0) {
298-
return NextResponse.json({ error: 'No active subscription found' }, { status: 404 })
299-
}
300-
301-
// Get member count
302-
const memberCount = await db
303-
.select({ userId: member.userId })
304-
.from(member)
305-
.where(eq(member.organizationId, organizationId))
306-
307-
const orgSubscription = subscriptionRecord[0]
308-
const maxSeats = orgSubscription.seats || 1
309-
const usedSeats = memberCount.length
310-
const availableSeats = Math.max(0, maxSeats - usedSeats)
311-
312-
return NextResponse.json({
313-
success: true,
314-
data: {
315-
maxSeats,
316-
usedSeats,
317-
availableSeats,
318-
plan: orgSubscription.plan,
319-
canModifySeats: orgSubscription.plan === 'team',
320-
},
321-
})
322-
} catch (error) {
323-
const { id: organizationId } = await params
324-
logger.error('Failed to get organization seats', {
325-
organizationId,
326-
error,
327-
})
328-
329-
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
330-
}
331-
}

apps/sim/lib/auth/auth.ts

Lines changed: 1 addition & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ import {
1313
oneTimeToken,
1414
organization,
1515
} from 'better-auth/plugins'
16-
import { and, eq } from 'drizzle-orm'
16+
import { eq } from 'drizzle-orm'
1717
import { headers } from 'next/headers'
1818
import Stripe from 'stripe'
1919
import {
2020
getEmailSubject,
21-
renderInvitationEmail,
2221
renderOTPEmail,
2322
renderPasswordResetEmail,
2423
} from '@/components/emails/render-email'
@@ -2068,79 +2067,6 @@ export const auth = betterAuth({
20682067

20692068
return hasTeamPlan
20702069
},
2071-
// Set a fixed membership limit of 50, but the actual limit will be enforced in the invitation flow
2072-
membershipLimit: 50,
2073-
// Validate seat limits before sending invitations
2074-
beforeInvite: async ({ organization }: { organization: { id: string } }) => {
2075-
const subscriptions = await db
2076-
.select()
2077-
.from(schema.subscription)
2078-
.where(
2079-
and(
2080-
eq(schema.subscription.referenceId, organization.id),
2081-
eq(schema.subscription.status, 'active')
2082-
)
2083-
)
2084-
2085-
const teamOrEnterpriseSubscription = subscriptions.find(
2086-
(sub) => sub.plan === 'team' || sub.plan === 'enterprise'
2087-
)
2088-
2089-
if (!teamOrEnterpriseSubscription) {
2090-
throw new Error('No active team or enterprise subscription for this organization')
2091-
}
2092-
2093-
const members = await db
2094-
.select()
2095-
.from(schema.member)
2096-
.where(eq(schema.member.organizationId, organization.id))
2097-
2098-
const pendingInvites = await db
2099-
.select()
2100-
.from(schema.invitation)
2101-
.where(
2102-
and(
2103-
eq(schema.invitation.organizationId, organization.id),
2104-
eq(schema.invitation.status, 'pending')
2105-
)
2106-
)
2107-
2108-
const totalCount = members.length + pendingInvites.length
2109-
const seatLimit = teamOrEnterpriseSubscription.seats || 1
2110-
2111-
if (totalCount >= seatLimit) {
2112-
throw new Error(`Organization has reached its seat limit of ${seatLimit}`)
2113-
}
2114-
},
2115-
sendInvitationEmail: async (data: any) => {
2116-
try {
2117-
const { invitation, organization, inviter } = data
2118-
2119-
const inviteUrl = `${getBaseUrl()}/invite/${invitation.id}`
2120-
const inviterName = inviter.user?.name || 'A team member'
2121-
2122-
const html = await renderInvitationEmail(
2123-
inviterName,
2124-
organization.name,
2125-
inviteUrl,
2126-
invitation.email
2127-
)
2128-
2129-
const result = await sendEmail({
2130-
to: invitation.email,
2131-
subject: `${inviterName} has invited you to join ${organization.name} on Sim`,
2132-
html,
2133-
from: getFromEmailAddress(),
2134-
emailType: 'transactional',
2135-
})
2136-
2137-
if (!result.success) {
2138-
logger.error('Failed to send organization invitation email:', result.message)
2139-
}
2140-
} catch (error) {
2141-
logger.error('Error sending invitation email', { error })
2142-
}
2143-
},
21442070
organizationCreation: {
21452071
afterCreate: async ({ organization, user }) => {
21462072
logger.info('[organizationCreation.afterCreate] Organization created', {

bun.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)