forked from PipedreamHQ/pipedream
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsentry.app.js
161 lines (158 loc) · 4.71 KB
/
sentry.app.js
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
const axios = require("axios");
const { createHmac } = require("crypto");
const parseLinkHeader = require("parse-link-header");
const slugify = require("slugify");
module.exports = {
type: "app",
app: "sentry",
propDefinitions: {
organizationSlug: {
type: "string",
label: "Organization",
description: "The organization for which to consider issues events",
async options(context) {
const url = this._organizationsEndpoint();
const params = {}; // We don't need to provide query parameters at the moment.
const { data, next } = await this._propDefinitionsOptions(url, params, context);
const options = data.map(this._organizationObjectToOption);
return {
options,
context: {
nextPage: next,
},
};
},
},
},
methods: {
_apiUrl() {
return "https://sentry.io/api/0";
},
_organizationsEndpoint() {
const baseUrl = this._apiUrl();
return `${baseUrl}/organizations/`;
},
_integrationsEndpoint(integrationSlug) {
const baseUrl = this._apiUrl();
const url = `${baseUrl}/sentry-apps`;
return integrationSlug ? `${url}/${integrationSlug}/` : `${url}/`;
},
_authToken() {
return this.$auth.auth_token;
},
_makeRequestConfig() {
const authToken = this._authToken();
const headers = {
"Authorization": `Bearer ${authToken}`,
"User-Agent": "@PipedreamHQ/pipedream v0.1",
};
return {
headers,
};
},
_organizationObjectToOption(organization) {
const { name, slug } = organization;
const label = `${name} (${slug})`;
return {
label,
value: slug,
};
},
async _propDefinitionsOptions(url, params, { page, prevContext }) {
let requestConfig = this._makeRequestConfig(); // Basic axios request config
if (page === 0) {
// First time the options are being retrieved.
// Include the parameters provided, which will be persisted
// across the different pages.
requestConfig = {
...requestConfig,
params,
};
} else if (prevContext.nextPage) {
// Retrieve next page of options.
url = prevContext.nextPage.url;
} else {
// No more options available.
return { data: [] };
}
const {
data,
headers: { link },
} = await axios.get(url, requestConfig);
// https://docs.sentry.io/api/pagination/
const { next } = parseLinkHeader(link);
return {
data,
next,
};
},
_baseIntegrationParams() {
return {
scopes: [
"event:read",
],
events: [
"issue",
],
isAlertable: true,
isInternal: true,
verifyInstall: false,
};
},
_formatIntegrationName(rawName) {
const options = {
remove: /[()]/g,
lower: true,
};
const enrichedRawName = `pd-${rawName}`;
return slugify(enrichedRawName, options).substring(0, 57);
},
async createIntegration(eventSourceName, organization, webhookUrl) {
const url = this._integrationsEndpoint();
const name = this._formatIntegrationName(eventSourceName);
const requestData = {
...this._baseIntegrationParams(),
name,
organization,
webhookUrl,
};
const requestConfig = this._makeRequestConfig();
const { data } = await axios.post(url, requestData, requestConfig);
return data;
},
async deleteIntegration(integrationSlug) {
const url = this._integrationsEndpoint(integrationSlug);
const requestConfig = this._makeRequestConfig();
await axios.delete(url, requestConfig);
},
async disableIntegration(integrationSlug) {
const url = this._integrationsEndpoint(integrationSlug);
const requestConfig = this._makeRequestConfig();
const requestData = {
events: null,
isAlertable: false,
name: "pipedream (disabled)",
webhookUrl: null,
};
await axios.put(url, requestData, requestConfig);
},
async getClientSecret(integrationSlug) {
const url = this._integrationsEndpoint(integrationSlug);
const requestConfig = this._makeRequestConfig();
const { data } = await axios.get(url, requestConfig);
return data.clientSecret;
},
isValidSource(event, clientSecret) {
const {
headers: {
"sentry-hook-signature": signature,
},
bodyRaw,
} = event;
const hmac = createHmac("sha256", clientSecret);
hmac.update(bodyRaw, "utf8");
const digest = hmac.digest("hex");
return digest === signature;
},
},
};