2023-08-29 10:01:28 +02:00
|
|
|
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
|
|
|
|
import { z } from 'zod'
|
|
|
|
|
import got from 'got'
|
|
|
|
|
import { TRPCError } from '@trpc/server'
|
|
|
|
|
import { WhatsAppCredentials } from '@typebot.io/schemas/features/whatsapp'
|
2023-09-20 15:26:52 +02:00
|
|
|
import prisma from '@typebot.io/lib/prisma'
|
2023-10-06 16:34:10 +02:00
|
|
|
import { decrypt } from '@typebot.io/lib/api/encryption/decrypt'
|
2024-01-25 07:53:57 -03:00
|
|
|
import { env } from '@typebot.io/env'
|
2023-08-29 10:01:28 +02:00
|
|
|
|
|
|
|
|
const inputSchema = z.object({
|
|
|
|
|
token: z.string().optional(),
|
|
|
|
|
credentialsId: z.string().optional(),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export const getSystemTokenInfo = authenticatedProcedure
|
|
|
|
|
.input(inputSchema)
|
|
|
|
|
.query(async ({ input, ctx: { user } }) => {
|
|
|
|
|
if (!input.token && !input.credentialsId)
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: 'BAD_REQUEST',
|
|
|
|
|
message: 'Either token or credentialsId must be provided',
|
|
|
|
|
})
|
|
|
|
|
const credentials = await getCredentials(user.id, input)
|
|
|
|
|
if (!credentials)
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: 'NOT_FOUND',
|
|
|
|
|
message: 'Credentials not found',
|
|
|
|
|
})
|
|
|
|
|
const {
|
|
|
|
|
data: { expires_at, scopes, app_id, application },
|
|
|
|
|
} = (await got(
|
2024-01-25 07:53:57 -03:00
|
|
|
`${env.WHATSAPP_CLOUD_API_URL}/v17.0/debug_token?input_token=${credentials.systemUserAccessToken}`,
|
2023-08-29 10:01:28 +02:00
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Bearer ${credentials.systemUserAccessToken}`,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
).json()) as {
|
|
|
|
|
data: {
|
|
|
|
|
app_id: string
|
|
|
|
|
application: string
|
|
|
|
|
expires_at: number
|
|
|
|
|
scopes: string[]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
appId: app_id,
|
|
|
|
|
appName: application,
|
|
|
|
|
expiresAt: expires_at,
|
|
|
|
|
scopes,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const getCredentials = async (
|
|
|
|
|
userId: string,
|
|
|
|
|
input: z.infer<typeof inputSchema>
|
|
|
|
|
): Promise<Omit<WhatsAppCredentials['data'], 'phoneNumberId'> | undefined> => {
|
|
|
|
|
if (input.token)
|
|
|
|
|
return {
|
|
|
|
|
systemUserAccessToken: input.token,
|
|
|
|
|
}
|
|
|
|
|
const credentials = await prisma.credentials.findUnique({
|
|
|
|
|
where: {
|
|
|
|
|
id: input.credentialsId,
|
|
|
|
|
workspace: { members: { some: { userId } } },
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
if (!credentials) return
|
|
|
|
|
return (await decrypt(
|
|
|
|
|
credentials.data,
|
|
|
|
|
credentials.iv
|
|
|
|
|
)) as WhatsAppCredentials['data']
|
|
|
|
|
}
|