@aloma.io/integration-sdk 3.7.49 → 3.7.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/build/internal/connector/config.d.mts +9 -0
  2. package/build/internal/connector/config.mjs +50 -0
  3. package/build/internal/connector/index.d.mts +16 -0
  4. package/build/internal/connector/index.mjs +39 -0
  5. package/build/internal/connector/metrics.d.mts +5 -0
  6. package/build/internal/connector/metrics.mjs +27 -0
  7. package/build/internal/connector/server/index.d.mts +10 -0
  8. package/build/internal/connector/server/index.mjs +29 -0
  9. package/build/internal/connector/server/on-connect/decrypt-config.d.mts +5 -0
  10. package/build/internal/connector/server/on-connect/decrypt-config.mjs +24 -0
  11. package/build/internal/connector/server/on-connect/finish-oauth.d.mts +9 -0
  12. package/build/internal/connector/server/on-connect/finish-oauth.mjs +90 -0
  13. package/build/internal/connector/server/on-connect/index.d.mts +8 -0
  14. package/build/internal/connector/server/on-connect/index.mjs +95 -0
  15. package/build/internal/connector/server/on-connect/make-oauth.d.mts +9 -0
  16. package/build/internal/connector/server/on-connect/make-oauth.mjs +77 -0
  17. package/build/internal/connector/server/on-connect/start-oauth.d.mts +4 -0
  18. package/build/internal/connector/server/on-connect/start-oauth.mjs +27 -0
  19. package/build/internal/connector/server/on-connect.d.mts +8 -0
  20. package/build/internal/connector/server/on-connect.mjs +297 -0
  21. package/build/internal/connector/server/on-message.d.mts +1 -0
  22. package/build/internal/connector/server/on-message.mjs +14 -0
  23. package/build/internal/dispatcher/index.d.mts +12 -2
  24. package/build/internal/dispatcher/index.mjs +4 -3
  25. package/build/internal/index.d.mts +1 -16
  26. package/build/internal/index.mjs +1 -423
  27. package/package.json +1 -1
  28. package/src/internal/connector/config.mts +57 -0
  29. package/src/internal/connector/index.mts +48 -0
  30. package/src/internal/connector/metrics.mts +35 -0
  31. package/src/internal/connector/server/index.mts +39 -0
  32. package/src/internal/connector/server/on-connect/decrypt-config.mts +27 -0
  33. package/src/internal/connector/server/on-connect/finish-oauth.mts +111 -0
  34. package/src/internal/connector/server/on-connect/index.mts +142 -0
  35. package/src/internal/connector/server/on-connect/make-oauth.mts +101 -0
  36. package/src/internal/connector/server/on-connect/start-oauth.mts +35 -0
  37. package/src/internal/connector/server/on-message.mts +11 -0
  38. package/src/internal/dispatcher/index.mts +7 -3
  39. package/src/internal/index.mts +1 -536
@@ -0,0 +1,297 @@
1
+ import { init } from "@paralleldrive/cuid2";
2
+ import Fetcher from "../../fetcher/fetcher.mjs";
3
+ import { OAuth } from "../../fetcher/oauth-fetcher.mjs";
4
+ const cuid = init({ length: 32 });
5
+ export const onConnect = ({ dispatcher, configSchema, config, start }) => {
6
+ return (transport) => {
7
+ dispatcher.onConfig = async function (secrets) {
8
+ const decrypted = {};
9
+ const fields = configSchema().fields;
10
+ const keys = Object.keys(secrets);
11
+ const jwe = await config.validateKeys("RSA-OAEP-256");
12
+ for (var i = 0; i < keys.length; ++i) {
13
+ const key = keys[i];
14
+ const value = secrets[key];
15
+ if (!value)
16
+ continue;
17
+ if (fields[key]?.plain || ["endpointUrl"].includes(key)) {
18
+ decrypted[key] = value;
19
+ }
20
+ else {
21
+ try {
22
+ decrypted[key] = await jwe.decrypt(value, config.id());
23
+ }
24
+ catch (e) {
25
+ console.log("failed to decrypt key", key, config.id(), e);
26
+ }
27
+ }
28
+ }
29
+ dispatcher.startOAuth = async function () {
30
+ if (!dispatcher._oauth)
31
+ throw new Error("oauth not configured");
32
+ const authorizationURL = process.env.OAUTH_AUTHORIZATION_URL ||
33
+ decrypted.authorizationURL ||
34
+ that._oauth.authorizationURL;
35
+ if (!authorizationURL)
36
+ throw new Error("authorizationURL not configured");
37
+ const clientId = decrypted.clientId ||
38
+ process.env.OAUTH_CLIENT_ID ||
39
+ dispatcher._oauth.clientId;
40
+ if (!clientId)
41
+ throw new Error("clientId not configured");
42
+ const scopes = process.env.OAUTH_SCOPE ||
43
+ decrypted.scope ||
44
+ dispatcher._oauth.scope ||
45
+ "";
46
+ const useCodeChallenge = !!that._oauth.useCodeChallenge;
47
+ return {
48
+ url: authorizationURL
49
+ .replace(/\{\{clientId\}\}/gi, encodeURIComponent(clientId))
50
+ .replace(/\{\{scope\}\}/gi, encodeURIComponent(scopes)),
51
+ useCodeChallenge,
52
+ };
53
+ };
54
+ dispatcher.finishOAuth = async function (arg) {
55
+ var that = this;
56
+ const tokenURL = process.env.OAUTH_TOKEN_URL ||
57
+ decrypted.tokenURL ||
58
+ that._oauth.tokenURL;
59
+ if (!dispatcher._oauth)
60
+ throw new Error("oauth not configured");
61
+ if (!tokenURL && !dispatcher._oauth.finishOAuth)
62
+ throw new Error("need tokenURL or finishOAuth(arg)");
63
+ var data = null;
64
+ const doFinish = async () => {
65
+ if (!arg.code || !arg.redirectURI)
66
+ throw new Error("need code and redirectUri");
67
+ const clientId = decrypted.clientId ||
68
+ process.env.OAUTH_CLIENT_ID ||
69
+ that._oauth.clientId;
70
+ if (!clientId)
71
+ throw new Error("clientId not configured");
72
+ const clientSecret = decrypted.clientSecret ||
73
+ process.env.OAUTH_CLIENT_SECRET ||
74
+ that._oauth.clientSecret;
75
+ if (!clientSecret)
76
+ throw new Error("clientSecret not configured");
77
+ const additionalTokenArgs = that._oauth.additionalTokenArgs || {};
78
+ const useAuthHeader = !!that._oauth.useAuthHeader;
79
+ const useCodeChallenge = !!that._oauth.useCodeChallenge;
80
+ let body = {
81
+ grant_type: "authorization_code",
82
+ ...additionalTokenArgs,
83
+ code: arg.code,
84
+ redirect_uri: arg.redirectURI,
85
+ };
86
+ if (useCodeChallenge) {
87
+ body.code_verifier = arg.codeVerifier;
88
+ }
89
+ let headers = {
90
+ "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
91
+ Accept: "application/json",
92
+ };
93
+ if (useAuthHeader) {
94
+ headers = {
95
+ ...headers,
96
+ Authorization: `Basic ${btoa(`${clientId}:${clientSecret}`)}`,
97
+ };
98
+ }
99
+ else {
100
+ body = {
101
+ ...body,
102
+ client_id: clientId,
103
+ client_secret: clientSecret,
104
+ };
105
+ }
106
+ const response = await fetch(tokenURL, {
107
+ method: "POST",
108
+ body: new URLSearchParams(body),
109
+ headers,
110
+ signal: AbortSignal.timeout(60 * 1000),
111
+ });
112
+ const status = await response.status;
113
+ const text = await response.text();
114
+ if (status === 200) {
115
+ const ret = JSON.parse(text);
116
+ if (ret.error) {
117
+ throw new Error(`${status} ${ret.error} ${ret.error_description || ""}`);
118
+ }
119
+ else if (ret.access_token) {
120
+ return { ...ret };
121
+ }
122
+ else {
123
+ throw new Error(status + " response has no access_token - " + text);
124
+ }
125
+ }
126
+ else {
127
+ throw new Error(status + " " + text);
128
+ }
129
+ };
130
+ if (dispatcher._oauth.finishOAuth) {
131
+ data = await dispatcher._oauth.finishOAuth({
132
+ arg,
133
+ doFinish,
134
+ transport,
135
+ });
136
+ }
137
+ else {
138
+ data = await doFinish();
139
+ }
140
+ const jwe = await config.validateKeys("RSA-OAEP-256");
141
+ return { value: await jwe.encrypt(data, "none", config.id()) };
142
+ };
143
+ const saveOAuthResult = async (what) => {
144
+ const jwe = await config.validateKeys("RSA-OAEP-256");
145
+ const value = await jwe.encrypt(what, "none", config.id());
146
+ const packet = transport.newPacket({});
147
+ packet.method("connector.config-update");
148
+ packet.args({
149
+ value,
150
+ });
151
+ transport.send(packet);
152
+ };
153
+ const that = this;
154
+ const getRefreshToken = async (refreshToken) => {
155
+ const tokenURL = process.env.OAUTH_TOKEN_URL ||
156
+ decrypted.tokenURL ||
157
+ that._oauth.tokenURL;
158
+ const clientId = decrypted.clientId ||
159
+ process.env.OAUTH_CLIENT_ID ||
160
+ that._oauth.clientId;
161
+ if (!clientId)
162
+ throw new Error("clientId not configured");
163
+ const clientSecret = decrypted.clientSecret ||
164
+ process.env.OAUTH_CLIENT_SECRET ||
165
+ that._oauth.clientSecret;
166
+ if (!clientSecret)
167
+ throw new Error("clientSecret not configured");
168
+ const useAuthHeader = !!that._oauth.useAuthHeader;
169
+ let headers = {};
170
+ if (useAuthHeader) {
171
+ headers = {
172
+ ...headers,
173
+ Authorization: `Basic ${btoa(`${clientId}:${clientSecret}`)}`,
174
+ };
175
+ }
176
+ const response = await fetch(tokenURL, {
177
+ method: "POST",
178
+ body: new URLSearchParams({
179
+ grant_type: "refresh_token",
180
+ refresh_token: refreshToken,
181
+ client_id: clientId,
182
+ client_secret: clientSecret,
183
+ }),
184
+ headers: {
185
+ "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
186
+ Accept: "application/json",
187
+ ...headers,
188
+ },
189
+ signal: AbortSignal.timeout(60 * 1000),
190
+ });
191
+ const status = await response.status;
192
+ const text = await response.text();
193
+ if (status === 200) {
194
+ return JSON.parse(text);
195
+ }
196
+ else {
197
+ throw new Error("could not get refresh token " + status + " " + text);
198
+ }
199
+ };
200
+ const theOAuth = that._oauth
201
+ ? new OAuth(decrypted.oauthResult, saveOAuthResult, getRefreshToken)
202
+ : null;
203
+ if (theOAuth) {
204
+ clearInterval(dispatcher._refreshOAuthToken);
205
+ if (!(dispatcher._oauth.noPeriodicTokenRefresh === false)) {
206
+ dispatcher._refreshOAuthToken = setInterval(async () => {
207
+ try {
208
+ console.log("refreshing oauth token");
209
+ await theOAuth.periodicRefresh();
210
+ }
211
+ catch (e) {
212
+ console.log("periodic refresh", e);
213
+ }
214
+ }, dispatcher._oauth.tokenRefreshPeriod || 4 * 60 * 60 * 15000);
215
+ }
216
+ }
217
+ const getBlob = (id) => {
218
+ return new Promise((resolve, reject) => {
219
+ const packet = transport.newPacket({}, (ret) => (ret?.error ? reject(ret.error) : resolve(ret)), `_req-${cuid()}`);
220
+ packet.method("connector.blob.get");
221
+ packet.args({
222
+ id,
223
+ });
224
+ transport.send(packet);
225
+ });
226
+ };
227
+ const getBlobContent = (id) => {
228
+ return new Promise((resolve, reject) => {
229
+ const packet = transport.newPacket({}, (ret) => ret?.error ? reject(ret.error) : resolve(ret?.content), `_req-${cuid()}`);
230
+ packet.method("connector.blob.get-content");
231
+ packet.args({
232
+ id,
233
+ });
234
+ transport.send(packet);
235
+ });
236
+ };
237
+ const createBlob = (args = {}) => {
238
+ return new Promise((resolve, reject) => {
239
+ const packet = transport.newPacket({}, (ret) => (ret?.error ? reject(ret.error) : resolve(ret?.id)), `_req-${cuid()}`);
240
+ packet.method("connector.blob.create");
241
+ packet.args(args);
242
+ transport.send(packet);
243
+ });
244
+ };
245
+ let oauthClient;
246
+ start({
247
+ config: decrypted,
248
+ oauth: theOAuth,
249
+ getBlob,
250
+ getBlobContent,
251
+ createBlob,
252
+ healthCheck: async (controller) => {
253
+ let result = { ok: true, error: null };
254
+ try {
255
+ if (oauthClient) {
256
+ await oauthClient.__healthCheck();
257
+ }
258
+ await controller.__healthCheck();
259
+ }
260
+ catch (e) {
261
+ result.ok = false;
262
+ result.error = e.message;
263
+ }
264
+ const packet = transport.newPacket({});
265
+ packet.method("connector.health.check");
266
+ packet.args(result);
267
+ transport.send(packet);
268
+ },
269
+ getClient: (arg) => theOAuth
270
+ ? (oauthClient = theOAuth.getClient(arg))
271
+ : new Fetcher(arg),
272
+ newTask: (name, data) => {
273
+ return new Promise((resolve, reject) => {
274
+ const packet = transport.newPacket({}, (ret) => (ret?.error ? reject(ret.error) : resolve(ret)), `_req-${cuid()}`);
275
+ packet.method("connector.task.new");
276
+ packet.args({
277
+ name,
278
+ a: data,
279
+ });
280
+ transport.send(packet);
281
+ });
282
+ },
283
+ updateTask: (id, data) => {
284
+ return new Promise((resolve, reject) => {
285
+ const packet = transport.newPacket({}, (ret) => (ret?.error ? reject(ret.error) : resolve(ret)), `_req-${cuid()}`);
286
+ packet.method("connector.task.update");
287
+ packet.args({
288
+ id,
289
+ a: data,
290
+ });
291
+ transport.send(packet);
292
+ });
293
+ },
294
+ });
295
+ };
296
+ };
297
+ };
@@ -0,0 +1 @@
1
+ export declare const onMessage: (processPacket: any) => (packet: any, transport: any) => Promise<void>;
@@ -0,0 +1,14 @@
1
+ import { handlePacketError, reply } from "../../util/index.mjs";
2
+ export const onMessage = (processPacket) => {
3
+ return async (packet, transport) => {
4
+ try {
5
+ const ret = await processPacket(packet);
6
+ if (ret)
7
+ reply(ret, packet, transport);
8
+ }
9
+ catch (e) {
10
+ console.log(e);
11
+ handlePacketError(packet, e, transport);
12
+ }
13
+ };
14
+ };
@@ -4,6 +4,7 @@ export default class Dispatcher {
4
4
  _oauth: any;
5
5
  private _types;
6
6
  private _resolvers;
7
+ _refreshOAuthToken?: any;
7
8
  constructor();
8
9
  main(what: any): this;
9
10
  oauth(arg: any): this;
@@ -11,8 +12,17 @@ export default class Dispatcher {
11
12
  config({ fields, oauth, description, summary }: any): this;
12
13
  resolvers(what: any): this;
13
14
  endpoint(what: any, notOptional: any): this;
14
- startOAuth(): void;
15
- finishOAuth(): void;
15
+ startOAuth(): Promise<{
16
+ url: string;
17
+ useCodeChallenge: boolean;
18
+ }>;
19
+ finishOAuth(arg: {
20
+ code: string;
21
+ redirectURI: string;
22
+ codeVerifier?: string;
23
+ }): Promise<{
24
+ value: string;
25
+ }>;
16
26
  build(): {
17
27
  introspect: () => any;
18
28
  configSchema: () => any;
@@ -4,6 +4,7 @@ export default class Dispatcher {
4
4
  _oauth;
5
5
  _types;
6
6
  _resolvers;
7
+ _refreshOAuthToken;
7
8
  constructor() {
8
9
  this._config = { fields: {} };
9
10
  }
@@ -68,7 +69,7 @@ export default class Dispatcher {
68
69
  placeholder: "e.g. x y z",
69
70
  type: "line",
70
71
  description: `Default Scope:
71
-
72
+
72
73
  ${arg.configurableClientScope}
73
74
  `,
74
75
  optional: true,
@@ -109,10 +110,10 @@ ${arg.configurableClientScope}
109
110
  this.resolvers({ _endpoint: what });
110
111
  return this;
111
112
  }
112
- startOAuth() {
113
+ async startOAuth() {
113
114
  throw new Error("oauth not configured");
114
115
  }
115
- finishOAuth() {
116
+ async finishOAuth(arg) {
116
117
  throw new Error("oauth not configured");
117
118
  }
118
119
  build() {
@@ -1,17 +1,2 @@
1
- import { Dispatcher } from "./dispatcher/index.mjs";
2
- declare class Connector {
3
- id: any;
4
- version: any;
5
- name: any;
6
- icon: any;
7
- dispatcher?: Dispatcher;
8
- constructor({ version, id, name, icon }: {
9
- version: any;
10
- id: any;
11
- name: any;
12
- icon: any;
13
- });
14
- configure(): Dispatcher;
15
- run(): Promise<void>;
16
- }
1
+ import { Connector } from './connector/index.mjs';
17
2
  export { Connector };