Add get/list/delete webhook resolver

This commit is contained in:
Hongbo Wu 2022-05-26 13:33:45 +08:00
parent cc07c00a83
commit a75ce3c44d
4 changed files with 158 additions and 7 deletions

View file

@ -32,6 +32,7 @@ import {
deleteLabelResolver,
deleteNewsletterEmailResolver,
deleteReminderResolver,
deleteWebhookResolver,
getAllUsersResolver,
getArticleResolver,
getArticlesResolver,
@ -64,6 +65,7 @@ import {
setShareArticleResolver,
setShareHighlightResolver,
setUserPersonalizationResolver,
setWebhookResolver,
signupResolver,
subscribeResolver,
subscriptionsResolver,
@ -78,8 +80,9 @@ import {
updateUserResolver,
uploadFileRequestResolver,
validateUsernameResolver,
updatePageResolver,
addPopularReadResolver,
webhookResolver,
webhooksResolver,
} from './index'
import { getShareInfoForArticle } from '../datalayer/links/share_info'
import {
@ -88,7 +91,6 @@ import {
} from '../utils/uploads'
import { getPageByParam } from '../elastic/pages'
import { generateApiKeyResolver } from './api_key'
import { setWebhookResolver } from './webhooks'
/* eslint-disable @typescript-eslint/naming-convention */
type ResultResolveType = {
@ -154,6 +156,7 @@ export const functionResolvers = {
subscribe: subscribeResolver,
addPopularRead: addPopularReadResolver,
setWebhook: setWebhookResolver,
deleteWebhook: deleteWebhookResolver,
},
Query: {
me: getMeUserResolver,
@ -173,6 +176,8 @@ export const functionResolvers = {
labels: labelsResolver,
search: searchResolver,
subscriptions: subscriptionsResolver,
webhooks: webhooksResolver,
webhook: webhookResolver,
},
User: {
async sharedArticles(
@ -567,4 +572,7 @@ export const functionResolvers = {
...resultResolveTypeResolver('Subscribe'),
...resultResolveTypeResolver('AddPopularRead'),
...resultResolveTypeResolver('SetWebhook'),
...resultResolveTypeResolver('Webhooks'),
...resultResolveTypeResolver('DeleteWebhook'),
...resultResolveTypeResolver('Webhook'),
}

View file

@ -17,3 +17,4 @@ export * from './labels'
export * from './subscriptions'
export * from './update'
export * from './popular_reads'
export * from './webhooks'

View file

@ -1,10 +1,22 @@
import { authorized } from '../../utils/helpers'
import {
DeleteWebhookError,
DeleteWebhookErrorCode,
DeleteWebhookSuccess,
MutationDeleteWebhookArgs,
MutationSetWebhookArgs,
QueryWebhookArgs,
SetWebhookError,
SetWebhookErrorCode,
SetWebhookSuccess,
Webhook as WebhookResponse,
WebhookError,
WebhookErrorCode,
WebhookEvent,
WebhooksError,
WebhooksErrorCode,
WebhooksSuccess,
WebhookSuccess,
} from '../../generated/graphql'
import { getRepository } from '../../entity/utils'
import { User } from '../../entity/user'
@ -12,6 +24,134 @@ import { Webhook } from '../../entity/webhook'
import { analytics } from '../../utils/analytics'
import { env } from '../../env'
export const webhooksResolver = authorized<WebhooksSuccess, WebhooksError>(
async (_obj, _params, { claims: { uid }, log }) => {
log.info('webhooksResolver')
try {
const user = await getRepository(User).findOneBy({ id: uid })
if (!user) {
return {
errorCodes: [WebhooksErrorCode.Unauthorized],
}
}
const webhooks = await getRepository(Webhook).findBy({
user: { id: uid },
})
return {
webhooks: webhooks.map((webhook) => webhookDataToResponse(webhook)),
}
} catch (error) {
log.error(error)
return {
errorCodes: [WebhooksErrorCode.BadRequest],
}
}
}
)
export const webhookResolver = authorized<
WebhookSuccess,
WebhookError,
QueryWebhookArgs
>(async (_, { id }, { claims: { uid }, log }) => {
log.info('webhookResolver')
try {
const user = await getRepository(User).findOneBy({ id: uid })
if (!user) {
return {
errorCodes: [WebhookErrorCode.Unauthorized],
}
}
const webhook = await getRepository(Webhook).findOne({
where: { id },
relations: ['user'],
})
if (!webhook) {
return {
errorCodes: [WebhookErrorCode.NotFound],
}
}
if (webhook.user.id !== uid) {
return {
errorCodes: [WebhookErrorCode.Unauthorized],
}
}
return {
webhook: webhookDataToResponse(webhook),
}
} catch (error) {
log.error(error)
return {
errorCodes: [WebhookErrorCode.BadRequest],
}
}
})
export const deleteWebhookResolver = authorized<
DeleteWebhookSuccess,
DeleteWebhookError,
MutationDeleteWebhookArgs
>(async (_, { id }, { claims: { uid }, log }) => {
log.info('deleteWebhookResolver')
try {
const user = await getRepository(User).findOneBy({ id: uid })
if (!user) {
return {
errorCodes: [DeleteWebhookErrorCode.Unauthorized],
}
}
const webhook = await getRepository(Webhook).findOne({
where: { id },
relations: ['user'],
})
if (!webhook) {
return {
errorCodes: [DeleteWebhookErrorCode.NotFound],
}
}
if (webhook.user.id !== uid) {
return {
errorCodes: [DeleteWebhookErrorCode.Unauthorized],
}
}
const deletedWebhook = await getRepository(Webhook).remove(webhook)
analytics.track({
userId: uid,
event: 'webhook_delete',
properties: {
webhookId: webhook.id,
env: env.server.apiEnv,
},
})
return {
webhook: webhookDataToResponse(webhook),
}
} catch (error) {
log.error(error)
return {
errorCodes: [DeleteWebhookErrorCode.BadRequest],
}
}
})
export const setWebhookResolver = authorized<
SetWebhookSuccess,
SetWebhookError,
@ -82,10 +222,7 @@ export const setWebhookResolver = authorized<
})
return {
webhook: {
...webhook,
eventTypes: webhook.eventTypes as WebhookEvent[],
},
webhook: webhookDataToResponse(webhook),
}
} catch (error) {
log.error(error)
@ -95,3 +232,8 @@ export const setWebhookResolver = authorized<
}
}
})
const webhookDataToResponse = (webhook: Webhook): WebhookResponse => ({
...webhook,
eventTypes: webhook.eventTypes as WebhookEvent[],
})

View file

@ -47,7 +47,7 @@ describe('Webhooks Router', () => {
.post('/svc/pubsub/webhooks/trigger/created?token=' + token)
.send(data)
.expect(200)
expect(res.body.data).to.eql('OK')
expect(res.text).to.eql('OK')
})
})
})