mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-08 22:48:14 -05:00
improvement(tools): added input validation to jira service management routes (#2642)
This commit is contained in:
@@ -1,11 +1,20 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import {
|
||||||
|
validateAlphanumericId,
|
||||||
|
validateEnum,
|
||||||
|
validateJiraCloudId,
|
||||||
|
validateJiraIssueKey,
|
||||||
|
} from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
|
|
||||||
const logger = createLogger('JsmApprovalsAPI')
|
const logger = createLogger('JsmApprovalsAPI')
|
||||||
|
|
||||||
|
const VALID_ACTIONS = ['get', 'answer'] as const
|
||||||
|
const VALID_DECISIONS = ['approve', 'decline'] as const
|
||||||
|
|
||||||
export async function POST(request: Request) {
|
export async function POST(request: Request) {
|
||||||
try {
|
try {
|
||||||
const body = await request.json()
|
const body = await request.json()
|
||||||
@@ -41,7 +50,23 @@ export async function POST(request: Request) {
|
|||||||
return NextResponse.json({ error: 'Action is required' }, { status: 400 })
|
return NextResponse.json({ error: 'Action is required' }, { status: 400 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const actionValidation = validateEnum(action, VALID_ACTIONS, 'action')
|
||||||
|
if (!actionValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: actionValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueIdOrKeyValidation = validateJiraIssueKey(issueIdOrKey, 'issueIdOrKey')
|
||||||
|
if (!issueIdOrKeyValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: issueIdOrKeyValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
if (action === 'get') {
|
if (action === 'get') {
|
||||||
@@ -91,12 +116,14 @@ export async function POST(request: Request) {
|
|||||||
return NextResponse.json({ error: 'Approval ID is required' }, { status: 400 })
|
return NextResponse.json({ error: 'Approval ID is required' }, { status: 400 })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!decision || !['approve', 'decline'].includes(decision)) {
|
const approvalIdValidation = validateAlphanumericId(approvalId, 'approvalId')
|
||||||
logger.error('Invalid or missing decision in request')
|
if (!approvalIdValidation.isValid) {
|
||||||
return NextResponse.json(
|
return NextResponse.json({ error: approvalIdValidation.error }, { status: 400 })
|
||||||
{ error: 'Decision is required and must be "approve" or "decline"' },
|
}
|
||||||
{ status: 400 }
|
|
||||||
)
|
const decisionValidation = validateEnum(decision, VALID_DECISIONS, 'decision')
|
||||||
|
if (!decisionValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: decisionValidation.error }, { status: 400 })
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `${baseUrl}/request/${issueIdOrKey}/approval/${approvalId}`
|
const url = `${baseUrl}/request/${issueIdOrKey}/approval/${approvalId}`
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateJiraCloudId, validateJiraIssueKey } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -38,6 +39,17 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = providedCloudId || (await getJiraCloudId(domain, accessToken))
|
const cloudId = providedCloudId || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueIdOrKeyValidation = validateJiraIssueKey(issueIdOrKey, 'issueIdOrKey')
|
||||||
|
if (!issueIdOrKeyValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: issueIdOrKeyValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const url = `${baseUrl}/request/${issueIdOrKey}/comment`
|
const url = `${baseUrl}/request/${issueIdOrKey}/comment`
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateJiraCloudId, validateJiraIssueKey } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -36,6 +37,17 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueIdOrKeyValidation = validateJiraIssueKey(issueIdOrKey, 'issueIdOrKey')
|
||||||
|
if (!issueIdOrKeyValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: issueIdOrKeyValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -36,6 +37,17 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceDeskIdValidation = validateAlphanumericId(serviceDeskId, 'serviceDeskId')
|
||||||
|
if (!serviceDeskIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: serviceDeskIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const parsedEmails = emails
|
const parsedEmails = emails
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import {
|
||||||
|
validateAlphanumericId,
|
||||||
|
validateEnum,
|
||||||
|
validateJiraCloudId,
|
||||||
|
} from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
|
|
||||||
const logger = createLogger('JsmOrganizationAPI')
|
const logger = createLogger('JsmOrganizationAPI')
|
||||||
|
|
||||||
|
const VALID_ACTIONS = ['create', 'add_to_service_desk'] as const
|
||||||
|
|
||||||
export async function POST(request: Request) {
|
export async function POST(request: Request) {
|
||||||
try {
|
try {
|
||||||
const body = await request.json()
|
const body = await request.json()
|
||||||
@@ -34,7 +41,18 @@ export async function POST(request: Request) {
|
|||||||
return NextResponse.json({ error: 'Action is required' }, { status: 400 })
|
return NextResponse.json({ error: 'Action is required' }, { status: 400 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const actionValidation = validateEnum(action, VALID_ACTIONS, 'action')
|
||||||
|
if (!actionValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: actionValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
if (action === 'create') {
|
if (action === 'create') {
|
||||||
@@ -90,6 +108,16 @@ export async function POST(request: Request) {
|
|||||||
return NextResponse.json({ error: 'Organization ID is required' }, { status: 400 })
|
return NextResponse.json({ error: 'Organization ID is required' }, { status: 400 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const serviceDeskIdValidation = validateAlphanumericId(serviceDeskId, 'serviceDeskId')
|
||||||
|
if (!serviceDeskIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: serviceDeskIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const organizationIdValidation = validateAlphanumericId(organizationId, 'organizationId')
|
||||||
|
if (!organizationIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: organizationIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const url = `${baseUrl}/servicedesk/${serviceDeskId}/organization`
|
const url = `${baseUrl}/servicedesk/${serviceDeskId}/organization`
|
||||||
|
|
||||||
logger.info('Adding organization to service desk:', { serviceDeskId, organizationId })
|
logger.info('Adding organization to service desk:', { serviceDeskId, organizationId })
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -27,6 +28,17 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceDeskIdValidation = validateAlphanumericId(serviceDeskId, 'serviceDeskId')
|
||||||
|
if (!serviceDeskIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: serviceDeskIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import {
|
||||||
|
validateEnum,
|
||||||
|
validateJiraCloudId,
|
||||||
|
validateJiraIssueKey,
|
||||||
|
} from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
|
|
||||||
const logger = createLogger('JsmParticipantsAPI')
|
const logger = createLogger('JsmParticipantsAPI')
|
||||||
|
|
||||||
|
const VALID_ACTIONS = ['get', 'add'] as const
|
||||||
|
|
||||||
export async function POST(request: Request) {
|
export async function POST(request: Request) {
|
||||||
try {
|
try {
|
||||||
const body = await request.json()
|
const body = await request.json()
|
||||||
@@ -40,7 +47,23 @@ export async function POST(request: Request) {
|
|||||||
return NextResponse.json({ error: 'Action is required' }, { status: 400 })
|
return NextResponse.json({ error: 'Action is required' }, { status: 400 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const actionValidation = validateEnum(action, VALID_ACTIONS, 'action')
|
||||||
|
if (!actionValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: actionValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueIdOrKeyValidation = validateJiraIssueKey(issueIdOrKey, 'issueIdOrKey')
|
||||||
|
if (!issueIdOrKeyValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: issueIdOrKeyValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
if (action === 'get') {
|
if (action === 'get') {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -35,6 +36,17 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceDeskIdValidation = validateAlphanumericId(serviceDeskId, 'serviceDeskId')
|
||||||
|
if (!serviceDeskIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: serviceDeskIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import {
|
||||||
|
validateAlphanumericId,
|
||||||
|
validateJiraCloudId,
|
||||||
|
validateJiraIssueKey,
|
||||||
|
} from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -33,11 +38,26 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const isCreateOperation = serviceDeskId && requestTypeId && summary
|
const isCreateOperation = serviceDeskId && requestTypeId && summary
|
||||||
|
|
||||||
if (isCreateOperation) {
|
if (isCreateOperation) {
|
||||||
|
const serviceDeskIdValidation = validateAlphanumericId(serviceDeskId, 'serviceDeskId')
|
||||||
|
if (!serviceDeskIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: serviceDeskIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestTypeIdValidation = validateAlphanumericId(requestTypeId, 'requestTypeId')
|
||||||
|
if (!requestTypeIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: requestTypeIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
const url = `${baseUrl}/request`
|
const url = `${baseUrl}/request`
|
||||||
|
|
||||||
logger.info('Creating request at:', url)
|
logger.info('Creating request at:', url)
|
||||||
@@ -95,6 +115,11 @@ export async function POST(request: Request) {
|
|||||||
return NextResponse.json({ error: 'Issue ID or key is required' }, { status: 400 })
|
return NextResponse.json({ error: 'Issue ID or key is required' }, { status: 400 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const issueIdOrKeyValidation = validateJiraIssueKey(issueIdOrKey, 'issueIdOrKey')
|
||||||
|
if (!issueIdOrKeyValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: issueIdOrKeyValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const url = `${baseUrl}/request/${issueIdOrKey}`
|
const url = `${baseUrl}/request/${issueIdOrKey}`
|
||||||
|
|
||||||
logger.info('Fetching request from:', url)
|
logger.info('Fetching request from:', url)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -32,6 +33,19 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serviceDeskId) {
|
||||||
|
const serviceDeskIdValidation = validateAlphanumericId(serviceDeskId, 'serviceDeskId')
|
||||||
|
if (!serviceDeskIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: serviceDeskIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -27,6 +28,17 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceDeskIdValidation = validateAlphanumericId(serviceDeskId, 'serviceDeskId')
|
||||||
|
if (!serviceDeskIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: serviceDeskIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateJiraCloudId } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -22,6 +23,12 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateJiraCloudId, validateJiraIssueKey } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -27,6 +28,17 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueIdOrKeyValidation = validateJiraIssueKey(issueIdOrKey, 'issueIdOrKey')
|
||||||
|
if (!issueIdOrKeyValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: issueIdOrKeyValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import {
|
||||||
|
validateAlphanumericId,
|
||||||
|
validateJiraCloudId,
|
||||||
|
validateJiraIssueKey,
|
||||||
|
} from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -38,6 +43,22 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = providedCloudId || (await getJiraCloudId(domain, accessToken))
|
const cloudId = providedCloudId || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueIdOrKeyValidation = validateJiraIssueKey(issueIdOrKey, 'issueIdOrKey')
|
||||||
|
if (!issueIdOrKeyValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: issueIdOrKeyValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const transitionIdValidation = validateAlphanumericId(transitionId, 'transitionId')
|
||||||
|
if (!transitionIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: transitionIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const url = `${baseUrl}/request/${issueIdOrKey}/transition`
|
const url = `${baseUrl}/request/${issueIdOrKey}/transition`
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
import { validateJiraCloudId, validateJiraIssueKey } from '@/lib/core/security/input-validation'
|
||||||
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
import { getJiraCloudId, getJsmApiBaseUrl, getJsmHeaders } from '@/tools/jsm/utils'
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -27,6 +28,17 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
const cloudId = cloudIdParam || (await getJiraCloudId(domain, accessToken))
|
||||||
|
|
||||||
|
const cloudIdValidation = validateJiraCloudId(cloudId, 'cloudId')
|
||||||
|
if (!cloudIdValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: cloudIdValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueIdOrKeyValidation = validateJiraIssueKey(issueIdOrKey, 'issueIdOrKey')
|
||||||
|
if (!issueIdOrKeyValidation.isValid) {
|
||||||
|
return NextResponse.json({ error: issueIdOrKeyValidation.error }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = getJsmApiBaseUrl(cloudId)
|
const baseUrl = getJsmApiBaseUrl(cloudId)
|
||||||
|
|
||||||
const url = `${baseUrl}/request/${issueIdOrKey}/transition`
|
const url = `${baseUrl}/request/${issueIdOrKey}/transition`
|
||||||
|
|||||||
Reference in New Issue
Block a user