Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 })
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