-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathroute.ts
More file actions
128 lines (109 loc) · 4.17 KB
/
route.ts
File metadata and controls
128 lines (109 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { authorizeCredentialUse } from '@/lib/auth/credential-access'
import { generateRequestId } from '@/lib/core/utils/request'
import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'
const logger = createLogger('MicrosoftExcelDrivesAPI')
interface GraphDrive {
id: string
name: string
driveType: string
webUrl?: string
}
/**
* List document libraries (drives) for a SharePoint site.
* Used by the microsoft.excel.drives selector to let users pick
* which drive contains their Excel file.
*/
export async function POST(request: NextRequest) {
const requestId = generateRequestId()
try {
const body = await request.json()
const { credential, workflowId, siteId, driveId } = body
if (!credential) {
logger.warn(`[${requestId}] Missing credential in request`)
return NextResponse.json({ error: 'Credential is required' }, { status: 400 })
}
if (!siteId) {
logger.warn(`[${requestId}] Missing siteId in request`)
return NextResponse.json({ error: 'Site ID is required' }, { status: 400 })
}
if (!/^[\w.,;:-]+$/.test(siteId)) {
logger.warn(`[${requestId}] Invalid siteId format`)
return NextResponse.json({ error: 'Invalid site ID format' }, { status: 400 })
}
const authz = await authorizeCredentialUse(request, {
credentialId: credential,
workflowId,
})
if (!authz.ok || !authz.credentialOwnerUserId) {
return NextResponse.json({ error: authz.error || 'Unauthorized' }, { status: 403 })
}
const accessToken = await refreshAccessTokenIfNeeded(
credential,
authz.credentialOwnerUserId,
requestId
)
if (!accessToken) {
logger.warn(`[${requestId}] Failed to obtain valid access token`)
return NextResponse.json(
{ error: 'Failed to obtain valid access token', authRequired: true },
{ status: 401 }
)
}
// Single-drive lookup when driveId is provided (used by fetchById)
if (driveId) {
if (!/^[\w-]+$/.test(driveId)) {
return NextResponse.json({ error: 'Invalid drive ID format' }, { status: 400 })
}
const url = `https://graph.microsoft.com/v1.0/sites/${siteId}/drives/${driveId}?$select=id,name,driveType,webUrl`
const response = await fetch(url, {
headers: { Authorization: `Bearer ${accessToken}` },
})
if (!response.ok) {
const errorData = await response
.json()
.catch(() => ({ error: { message: 'Unknown error' } }))
return NextResponse.json(
{ error: errorData.error?.message || 'Failed to fetch drive' },
{ status: response.status }
)
}
const data: GraphDrive = await response.json()
return NextResponse.json(
{ drive: { id: data.id, name: data.name, driveType: data.driveType } },
{ status: 200 }
)
}
// List all drives for the site
const url = `https://graph.microsoft.com/v1.0/sites/${siteId}/drives?$select=id,name,driveType,webUrl`
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
if (!response.ok) {
const errorData = await response.json().catch(() => ({ error: { message: 'Unknown error' } }))
logger.error(`[${requestId}] Microsoft Graph API error fetching drives`, {
status: response.status,
error: errorData.error?.message,
})
return NextResponse.json(
{ error: errorData.error?.message || 'Failed to fetch drives' },
{ status: response.status }
)
}
const data = await response.json()
const drives = (data.value || []).map((drive: GraphDrive) => ({
id: drive.id,
name: drive.name,
driveType: drive.driveType,
}))
logger.info(`[${requestId}] Successfully fetched ${drives.length} drives for site ${siteId}`)
return NextResponse.json({ drives }, { status: 200 })
} catch (error) {
logger.error(`[${requestId}] Error fetching drives`, error)
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
}
}