Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions apps/sim/app/api/function/execute/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ vi.mock('@/lib/execution/isolated-vm', () => ({
vi.mock('@sim/logger', () => loggerMock)

vi.mock('@/lib/auth/hybrid', () => ({
checkHybridAuth: vi.fn().mockResolvedValue({
checkInternalAuth: vi.fn().mockResolvedValue({
success: true,
userId: 'user-123',
authType: 'session',
authType: 'internal_jwt',
}),
}))

Expand Down Expand Up @@ -119,8 +119,8 @@ describe('Function Execute API Route', () => {

describe('Security Tests', () => {
it('should reject unauthorized requests', async () => {
const { checkHybridAuth } = await import('@/lib/auth/hybrid')
vi.mocked(checkHybridAuth).mockResolvedValueOnce({
const { checkInternalAuth } = await import('@/lib/auth/hybrid')
vi.mocked(checkInternalAuth).mockResolvedValueOnce({
success: false,
error: 'Unauthorized',
})
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/function/execute/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { isE2bEnabled } from '@/lib/core/config/feature-flags'
import { generateRequestId } from '@/lib/core/utils/request'
import { executeInE2B } from '@/lib/execution/e2b'
Expand Down Expand Up @@ -582,7 +582,7 @@ export async function POST(req: NextRequest) {
let resolvedCode = '' // Store resolved code for error reporting

try {
const auth = await checkHybridAuth(req)
const auth = await checkInternalAuth(req)
if (!auth.success || !auth.userId) {
logger.warn(`[${requestId}] Unauthorized function execution attempt`)
return NextResponse.json({ error: auth.error || 'Unauthorized' }, { status: 401 })
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/providers/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { account } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils'
import { refreshTokenIfNeeded } from '@/app/api/auth/oauth/utils'
Expand All @@ -22,7 +22,7 @@ export async function POST(request: NextRequest) {
const startTime = Date.now()

try {
const auth = await checkHybridAuth(request, { requireWorkflowId: false })
const auth = await checkInternalAuth(request, { requireWorkflowId: false })
Comment thread
cursor[bot] marked this conversation as resolved.
if (!auth.success || !auth.userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
Expand Down
10 changes: 5 additions & 5 deletions apps/sim/app/api/tools/custom/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ describe('Custom Tools API Routes', () => {
}))

vi.doMock('@/lib/auth/hybrid', () => ({
checkHybridAuth: vi.fn().mockResolvedValue({
checkSessionOrInternalAuth: vi.fn().mockResolvedValue({
success: true,
userId: 'user-123',
authType: 'session',
Expand Down Expand Up @@ -254,7 +254,7 @@ describe('Custom Tools API Routes', () => {
)

vi.doMock('@/lib/auth/hybrid', () => ({
checkHybridAuth: vi.fn().mockResolvedValue({
checkSessionOrInternalAuth: vi.fn().mockResolvedValue({
success: false,
error: 'Unauthorized',
}),
Expand Down Expand Up @@ -304,7 +304,7 @@ describe('Custom Tools API Routes', () => {
describe('POST /api/tools/custom', () => {
it('should reject unauthorized requests', async () => {
vi.doMock('@/lib/auth/hybrid', () => ({
checkHybridAuth: vi.fn().mockResolvedValue({
checkSessionOrInternalAuth: vi.fn().mockResolvedValue({
success: false,
error: 'Unauthorized',
}),
Expand Down Expand Up @@ -390,7 +390,7 @@ describe('Custom Tools API Routes', () => {

it('should prevent unauthorized deletion of user-scoped tool', async () => {
vi.doMock('@/lib/auth/hybrid', () => ({
checkHybridAuth: vi.fn().mockResolvedValue({
checkSessionOrInternalAuth: vi.fn().mockResolvedValue({
success: true,
userId: 'user-456',
authType: 'session',
Expand All @@ -413,7 +413,7 @@ describe('Custom Tools API Routes', () => {

it('should reject unauthorized requests', async () => {
vi.doMock('@/lib/auth/hybrid', () => ({
checkHybridAuth: vi.fn().mockResolvedValue({
checkSessionOrInternalAuth: vi.fn().mockResolvedValue({
success: false,
error: 'Unauthorized',
}),
Expand Down
18 changes: 9 additions & 9 deletions apps/sim/app/api/tools/custom/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createLogger } from '@sim/logger'
import { and, desc, eq, isNull, or } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { upsertCustomTools } from '@/lib/workflows/custom-tools/operations'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
Expand Down Expand Up @@ -42,8 +42,8 @@ export async function GET(request: NextRequest) {
const workflowId = searchParams.get('workflowId')

try {
// Use hybrid auth to support session, API key, and internal JWT
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
// Use session/internal auth to support session and internal JWT (no API key access)
const authResult = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
if (!authResult.success || !authResult.userId) {
logger.warn(`[${requestId}] Unauthorized custom tools access attempt`)
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
Expand All @@ -69,8 +69,8 @@ export async function GET(request: NextRequest) {
}

// Check workspace permissions
// For internal JWT with workflowId: checkHybridAuth already resolved userId from workflow owner
// For session/API key: verify user has access to the workspace
// For internal JWT with workflowId: checkSessionOrInternalAuth already resolved userId from workflow owner
// For session: verify user has access to the workspace
// For legacy (no workspaceId): skip workspace check, rely on userId match
if (resolvedWorkspaceId && !(authResult.authType === 'internal_jwt' && workflowId)) {
const userPermission = await getUserEntityPermissions(
Expand Down Expand Up @@ -116,8 +116,8 @@ export async function POST(req: NextRequest) {
const requestId = generateRequestId()

try {
// Use hybrid auth (though this endpoint is only called from UI)
const authResult = await checkHybridAuth(req, { requireWorkflowId: false })
// Use session/internal auth (no API key access)
const authResult = await checkSessionOrInternalAuth(req, { requireWorkflowId: false })
if (!authResult.success || !authResult.userId) {
logger.warn(`[${requestId}] Unauthorized custom tools update attempt`)
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
Expand Down Expand Up @@ -193,8 +193,8 @@ export async function DELETE(request: NextRequest) {
}

try {
// Use hybrid auth (though this endpoint is only called from UI)
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
// Use session/internal auth (no API key access)
const authResult = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
if (!authResult.success || !authResult.userId) {
logger.warn(`[${requestId}] Unauthorized custom tool deletion attempt`)
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/discord/send-message/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { validateNumericId } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'
import { processFilesToUserFiles } from '@/lib/uploads/utils/file-utils'
Expand All @@ -22,7 +22,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Discord send attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/add-label/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'

Expand All @@ -21,7 +21,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail add label attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/archive/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'

export const dynamic = 'force-dynamic'
Expand All @@ -19,7 +19,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail archive attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/delete/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'

export const dynamic = 'force-dynamic'
Expand All @@ -19,7 +19,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail delete attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/draft/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { processFilesToUserFiles } from '@/lib/uploads/utils/file-utils'
import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server'
Expand Down Expand Up @@ -35,7 +35,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail draft attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/mark-read/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'

export const dynamic = 'force-dynamic'
Expand All @@ -19,7 +19,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail mark read attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/mark-unread/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'

export const dynamic = 'force-dynamic'
Expand All @@ -19,7 +19,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail mark unread attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/move/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'

export const dynamic = 'force-dynamic'
Expand All @@ -21,7 +21,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail move attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/remove-label/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'

Expand All @@ -21,7 +21,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail remove label attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/send/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { processFilesToUserFiles } from '@/lib/uploads/utils/file-utils'
import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server'
Expand Down Expand Up @@ -35,7 +35,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail send attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/gmail/unarchive/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'

export const dynamic = 'force-dynamic'
Expand All @@ -19,7 +19,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Gmail unarchive attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/google_drive/upload/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { processSingleFileToUserFile } from '@/lib/uploads/utils/file-utils'
import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server'
Expand Down Expand Up @@ -56,7 +56,7 @@ export async function POST(request: NextRequest) {
const requestId = generateRequestId()

try {
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })

if (!authResult.success) {
logger.warn(`[${requestId}] Unauthorized Google Drive upload attempt: ${authResult.error}`)
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/tools/image/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { validateImageUrl } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'

Expand All @@ -15,7 +15,7 @@ export async function GET(request: NextRequest) {
const imageUrl = url.searchParams.get('url')
const requestId = generateRequestId()

const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })
if (!authResult.success) {
logger.error(`[${requestId}] Authentication failed for image proxy:`, authResult.error)
return new NextResponse('Unauthorized', { status: 401 })
Expand Down
Loading