@unito/integration-cli 0.57.2 → 0.58.0
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.
- package/dist/.eslintrc.d.ts +6 -0
- package/dist/.eslintrc.js +9 -2
- package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/src/index.ts +1 -3
- package/dist/src/commands/dev.d.ts +4 -0
- package/dist/src/commands/dev.js +40 -4
- package/dist/src/commands/init.js +2 -2
- package/dist/src/commands/login.js +1 -1
- package/dist/src/commands/oauth2.js +15 -10
- package/dist/src/commands/test.js +28 -6
- package/dist/src/errors.d.ts +8 -0
- package/dist/src/errors.js +35 -18
- package/dist/src/resources/configuration.js +0 -2
- package/dist/src/resources/credentials.d.ts +3 -0
- package/dist/src/resources/credentials.js +26 -0
- package/dist/src/resources/integrations.d.ts +1 -0
- package/dist/src/resources/integrations.js +37 -2
- package/dist/src/resources/oauth2Helper.d.ts +4 -0
- package/dist/src/resources/oauth2Helper.js +30 -0
- package/dist/src/services/integrationsPlatform.d.ts +1 -0
- package/dist/src/services/integrationsPlatform.js +5 -1
- package/dist/src/services/oauth2Helper.d.ts +77 -3
- package/dist/src/services/oauth2Helper.js +228 -29
- package/dist/test/commands/dev.test.js +21 -0
- package/dist/test/commands/init.test.js +4 -4
- package/dist/test/commands/login.test.js +1 -0
- package/dist/test/commands/oauth2.test.js +2 -1
- package/dist/test/commands/publish.test.js +1 -0
- package/dist/test/commands/test.test.js +22 -0
- package/dist/test/commands/upgrade.test.js +1 -0
- package/dist/test/oauth2Helper/oauth2Helper.test.js +111 -127
- package/dist/test/resources/integrations.test.js +37 -0
- package/dist/test/{services → resources}/oauth2Helper.test.js +12 -42
- package/oclif.manifest.json +64 -9
- package/package.json +8 -8
- package/dist/integrationGenerator/errors.d.ts +0 -2
- package/dist/integrationGenerator/errors.js +0 -6
- package/dist/integrationGenerator/index.d.ts +0 -2
- package/dist/integrationGenerator/index.js +0 -5
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.dockerignore +0 -3
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.eslintrc.js +0 -74
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.nvmrc +0 -1
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierignore +0 -1
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierrc +0 -7
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.unito.json +0 -1
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/Dockerfile +0 -38
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/README.md +0 -21
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/index.ts +0 -94
- package/dist/integrationGenerator/integrationBoilerplate/package.json +0 -43
- package/dist/integrationGenerator/integrationBoilerplate/src/logger.ts +0 -55
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/additionalLoggingContext.ts +0 -22
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/correlationId.ts +0 -13
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/credentials.ts +0 -38
- package/dist/integrationGenerator/integrationBoilerplate/src/request.ts +0 -59
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/index.ts +0 -11
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/me.ts +0 -15
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/root.ts +0 -12
- package/dist/integrationGenerator/integrationBoilerplate/tsconfig.json +0 -37
- package/dist/integrationGenerator/src/index.d.ts +0 -1
- package/dist/integrationGenerator/src/index.js +0 -5
- package/dist/integrationGenerator/src/resources/index.d.ts +0 -1
- package/dist/integrationGenerator/src/resources/index.js +0 -5
- package/dist/integrationGenerator/src/resources/integration.d.ts +0 -9
- package/dist/integrationGenerator/src/resources/integration.js +0 -60
- package/dist/integrationGenerator/test/resources/integration.test.js +0 -50
- package/dist/src/oauth2Helper/oauth2Helper.d.ts +0 -65
- package/dist/src/oauth2Helper/oauth2Helper.js +0 -255
- package/dist/src/oauth2Helper/types.d.ts +0 -22
- package/dist/src/oauth2Helper/types.js +0 -2
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.dockerignore +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.eslintrc.js +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.nvmrc +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.prettierignore +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.prettierrc +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.unito.json +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/Dockerfile +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/README.md +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/package.json +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/logger.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/additionalLoggingContext.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/correlationId.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/credentials.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/request.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/index.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/me.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/root.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/tsconfig.json +0 -0
- /package/dist/{integrationGenerator/test/resources/integration.test.d.ts → test/resources/integrations.test.d.ts} +0 -0
- /package/dist/test/{services → resources}/oauth2Helper.test.d.ts +0 -0
|
@@ -1,4 +1,78 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as openUrl from 'openurl';
|
|
2
|
+
import { Oauth2 } from '../configurationTypes';
|
|
2
3
|
import { Environment } from '../resources/globalConfiguration';
|
|
3
|
-
export declare
|
|
4
|
-
export declare
|
|
4
|
+
export declare const open: typeof openUrl;
|
|
5
|
+
export declare const HTML_ERROR_MSG = "<!doctype html><head><title>Unito</title></head><body style=\"text-align:center\"> An unknown error occured </body>";
|
|
6
|
+
export declare const HTML_SUCCESS_MSG = "<!doctype html><head><title>Unito</title></head><body style=\"text-align:center\"> Redirected to the CLI successfully </body>";
|
|
7
|
+
export interface Oauth2Credentials {
|
|
8
|
+
clientId: string;
|
|
9
|
+
clientSecret: string;
|
|
10
|
+
}
|
|
11
|
+
export interface AuthorizePayload extends Oauth2Credentials {
|
|
12
|
+
providerAuthorizationUrl: string;
|
|
13
|
+
scopes?: string;
|
|
14
|
+
providerAccessTokenUrl: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CallbackPayload {
|
|
17
|
+
code: string;
|
|
18
|
+
}
|
|
19
|
+
export interface Oauth2Response {
|
|
20
|
+
accessToken: string;
|
|
21
|
+
refreshToken?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface TokenPayload extends Oauth2Credentials {
|
|
24
|
+
providerTokenUrl: string;
|
|
25
|
+
code: string;
|
|
26
|
+
}
|
|
27
|
+
export type Oauth2Payload = Oauth2;
|
|
28
|
+
declare class OAuth2Helper {
|
|
29
|
+
private environment;
|
|
30
|
+
private server;
|
|
31
|
+
private clientId;
|
|
32
|
+
private clientSecret;
|
|
33
|
+
private providerAuthorizationUrl;
|
|
34
|
+
private tokenUrl;
|
|
35
|
+
private scopes;
|
|
36
|
+
private grantType;
|
|
37
|
+
private requestContentType;
|
|
38
|
+
private oauth2Response;
|
|
39
|
+
private serverUrl;
|
|
40
|
+
private tokenRequestParameters;
|
|
41
|
+
private refreshRequestParameters;
|
|
42
|
+
/**
|
|
43
|
+
* Constructs an instance of OAuthHelper.
|
|
44
|
+
* @param clientId The client ID for your OAuth application.
|
|
45
|
+
* @param clientSecret The client secret for your OAuth application.
|
|
46
|
+
* @param authorizationUrl The URL for the authorization endpoint of the provider.
|
|
47
|
+
* @param scopes The scopes required for the OAuth authorization.
|
|
48
|
+
* @param providerTokenUrl The URL for the token endpoint of the provider.
|
|
49
|
+
*/
|
|
50
|
+
constructor(authorizationInfo: Oauth2Payload, environment?: Environment);
|
|
51
|
+
/**
|
|
52
|
+
* Initiate the authorization flow and redirects the user to the provider's authorization page.
|
|
53
|
+
*/
|
|
54
|
+
authorize(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Handles the callback request from the provider and stores the authorization code.
|
|
57
|
+
* @param req The express Request object.
|
|
58
|
+
* @param res The express Response object.
|
|
59
|
+
*/
|
|
60
|
+
private handleCallback;
|
|
61
|
+
/**
|
|
62
|
+
* Waits for the authorization code to be set.
|
|
63
|
+
* @returns A promise that resolves when the code is set.
|
|
64
|
+
*/
|
|
65
|
+
callbackIsDone(): Promise<Oauth2Response>;
|
|
66
|
+
private encodeBody;
|
|
67
|
+
updateToken(refreshToken: string): Promise<Oauth2Response>;
|
|
68
|
+
/**
|
|
69
|
+
* Starts the Express server for handling OAuth callbacks.
|
|
70
|
+
* @returns The URL of the server.
|
|
71
|
+
*/
|
|
72
|
+
startServer(): Promise<string>;
|
|
73
|
+
/**
|
|
74
|
+
* Stops the Express server.
|
|
75
|
+
*/
|
|
76
|
+
stopServer(): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
export default OAuth2Helper;
|
|
@@ -1,35 +1,234 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.HTML_SUCCESS_MSG = exports.HTML_ERROR_MSG = exports.open = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const
|
|
5
|
+
const express_1 = tslib_1.__importDefault(require("express"));
|
|
6
|
+
const cors_1 = tslib_1.__importDefault(require("cors"));
|
|
7
|
+
const openUrl = tslib_1.__importStar(require("openurl"));
|
|
8
|
+
const ngrok_1 = tslib_1.__importDefault(require("ngrok"));
|
|
9
|
+
const IntegrationsPlatformClient = tslib_1.__importStar(require("./integrationsPlatform"));
|
|
10
|
+
const configurationTypes_1 = require("../configurationTypes");
|
|
6
11
|
const errors_1 = require("../errors");
|
|
7
12
|
const globalConfiguration_1 = require("../resources/globalConfiguration");
|
|
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
|
-
|
|
13
|
+
// It allows to stub openUrl library in the test
|
|
14
|
+
exports.open = openUrl;
|
|
15
|
+
exports.HTML_ERROR_MSG = `<!doctype html><head><title>Unito</title></head><body style="text-align:center"> An unknown error occured </body>`;
|
|
16
|
+
exports.HTML_SUCCESS_MSG = `<!doctype html><head><title>Unito</title></head><body style="text-align:center"> Redirected to the CLI successfully </body>`;
|
|
17
|
+
class OAuth2Helper {
|
|
18
|
+
environment;
|
|
19
|
+
server = null;
|
|
20
|
+
clientId;
|
|
21
|
+
clientSecret;
|
|
22
|
+
providerAuthorizationUrl;
|
|
23
|
+
tokenUrl;
|
|
24
|
+
scopes;
|
|
25
|
+
grantType;
|
|
26
|
+
requestContentType;
|
|
27
|
+
oauth2Response;
|
|
28
|
+
serverUrl = '';
|
|
29
|
+
tokenRequestParameters;
|
|
30
|
+
refreshRequestParameters;
|
|
31
|
+
/**
|
|
32
|
+
* Constructs an instance of OAuthHelper.
|
|
33
|
+
* @param clientId The client ID for your OAuth application.
|
|
34
|
+
* @param clientSecret The client secret for your OAuth application.
|
|
35
|
+
* @param authorizationUrl The URL for the authorization endpoint of the provider.
|
|
36
|
+
* @param scopes The scopes required for the OAuth authorization.
|
|
37
|
+
* @param providerTokenUrl The URL for the token endpoint of the provider.
|
|
38
|
+
*/
|
|
39
|
+
constructor(authorizationInfo, environment = globalConfiguration_1.Environment.Production) {
|
|
40
|
+
const { clientId, clientSecret, authorizationUrl, scopes, tokenUrl, grantType, requestContentType, refreshRequestParameters, tokenRequestParameters, } = authorizationInfo;
|
|
41
|
+
this.startServer = this.startServer.bind(this);
|
|
42
|
+
this.stopServer = this.stopServer.bind(this);
|
|
43
|
+
this.handleCallback = this.handleCallback.bind(this);
|
|
44
|
+
this.clientId = clientId;
|
|
45
|
+
this.clientSecret = clientSecret;
|
|
46
|
+
this.providerAuthorizationUrl = authorizationUrl;
|
|
47
|
+
this.scopes = scopes.map(scope => scope.name);
|
|
48
|
+
this.tokenUrl = tokenUrl;
|
|
49
|
+
this.grantType = grantType ?? configurationTypes_1.GrantType.AUTHORIZATION_CODE;
|
|
50
|
+
this.requestContentType = requestContentType ?? configurationTypes_1.RequestContentType.URL_ENCODED;
|
|
51
|
+
this.tokenRequestParameters = tokenRequestParameters;
|
|
52
|
+
this.refreshRequestParameters = refreshRequestParameters;
|
|
53
|
+
this.environment = environment;
|
|
54
|
+
if (!Object.values(configurationTypes_1.RequestContentType).includes(this.requestContentType)) {
|
|
55
|
+
throw new errors_1.UnsupportedContentTypeError(`Request content type not supported: ${this.requestContentType}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Initiate the authorization flow and redirects the user to the provider's authorization page.
|
|
60
|
+
*/
|
|
61
|
+
async authorize() {
|
|
62
|
+
if (!this.providerAuthorizationUrl) {
|
|
63
|
+
throw new errors_1.InvalidRequestContentTypeError('authorizationUrl must be defined in .unito.json');
|
|
64
|
+
}
|
|
65
|
+
const authUrl = new URL(this.providerAuthorizationUrl);
|
|
66
|
+
const params = new URLSearchParams(authUrl.search);
|
|
67
|
+
if (this.clientId) {
|
|
68
|
+
params.set('client_id', this.clientId);
|
|
69
|
+
}
|
|
70
|
+
params.set('redirect_uri', `${IntegrationsPlatformClient.Servers[this.environment]}/credentials/new/oauth2/callback-cli`);
|
|
71
|
+
const state = Buffer.from(JSON.stringify({
|
|
72
|
+
cliCallbackUrl: `${this.serverUrl}/oauth2/callback`,
|
|
73
|
+
})).toString('base64');
|
|
74
|
+
params.set('state', state);
|
|
75
|
+
if (this.scopes) {
|
|
76
|
+
params.set('scope', this.scopes.join(' '));
|
|
77
|
+
}
|
|
78
|
+
params.set('response_type', 'code');
|
|
79
|
+
authUrl.search = params.toString();
|
|
80
|
+
exports.open.open(authUrl.toString());
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Handles the callback request from the provider and stores the authorization code.
|
|
84
|
+
* @param req The express Request object.
|
|
85
|
+
* @param res The express Response object.
|
|
86
|
+
*/
|
|
87
|
+
async handleCallback(req, res) {
|
|
88
|
+
// Authorization Response: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2
|
|
89
|
+
// const state = req.state as string;
|
|
90
|
+
// Error response: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2.1
|
|
91
|
+
const error = req.query.error;
|
|
92
|
+
if (error) {
|
|
93
|
+
res.setHeader('Content-Type', 'text/html').send(exports.HTML_ERROR_MSG);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const code = req.query.code;
|
|
97
|
+
const bodyData = {
|
|
98
|
+
code,
|
|
99
|
+
grant_type: this.grantType,
|
|
100
|
+
redirect_uri: `${IntegrationsPlatformClient.Servers[this.environment]}/credentials/new/oauth2/callback-cli`,
|
|
101
|
+
};
|
|
102
|
+
if (this.clientId) {
|
|
103
|
+
bodyData.client_id = this.clientId;
|
|
104
|
+
}
|
|
105
|
+
if (this.clientSecret) {
|
|
106
|
+
bodyData.client_secret = this.clientSecret;
|
|
107
|
+
}
|
|
108
|
+
const fetchOptions = {
|
|
109
|
+
headers: {
|
|
110
|
+
'Content-type': this.requestContentType,
|
|
111
|
+
...(this.tokenRequestParameters?.header ?? {}),
|
|
112
|
+
},
|
|
113
|
+
body: this.encodeBody(bodyData, this.requestContentType),
|
|
114
|
+
method: 'POST',
|
|
115
|
+
};
|
|
116
|
+
try {
|
|
117
|
+
const fetchResult = await fetch(this.tokenUrl, fetchOptions);
|
|
118
|
+
if (fetchResult.status !== 200) {
|
|
119
|
+
res.setHeader('Content-Type', 'text/html');
|
|
120
|
+
res.send(exports.HTML_ERROR_MSG);
|
|
121
|
+
}
|
|
122
|
+
const response = await fetchResult.json();
|
|
123
|
+
this.oauth2Response = {
|
|
124
|
+
accessToken: response.access_token,
|
|
125
|
+
refreshToken: response.refresh_token,
|
|
126
|
+
};
|
|
127
|
+
res.setHeader('Content-Type', 'text/html');
|
|
128
|
+
res.send(exports.HTML_SUCCESS_MSG);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
res.setHeader('Content-Type', 'text/html');
|
|
132
|
+
res.send(exports.HTML_ERROR_MSG);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Waits for the authorization code to be set.
|
|
137
|
+
* @returns A promise that resolves when the code is set.
|
|
138
|
+
*/
|
|
139
|
+
/* istanbul ignore next */
|
|
140
|
+
async callbackIsDone() {
|
|
141
|
+
if (this.oauth2Response) {
|
|
142
|
+
return this.oauth2Response;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
return new Promise(resolve => {
|
|
146
|
+
const interval = setInterval(() => {
|
|
147
|
+
if (this.oauth2Response) {
|
|
148
|
+
clearInterval(interval);
|
|
149
|
+
resolve(this.oauth2Response);
|
|
150
|
+
}
|
|
151
|
+
}, 100);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
encodeBody(bodyData, contentType) {
|
|
156
|
+
switch (contentType) {
|
|
157
|
+
case configurationTypes_1.RequestContentType.URL_ENCODED:
|
|
158
|
+
return new URLSearchParams(bodyData).toString();
|
|
159
|
+
case configurationTypes_1.RequestContentType.JSON:
|
|
160
|
+
return JSON.stringify(bodyData);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async updateToken(refreshToken) {
|
|
164
|
+
if (!Object.values(configurationTypes_1.RequestContentType).includes(this.requestContentType)) {
|
|
165
|
+
throw new errors_1.InvalidRequestContentTypeError(`Request content type not supported: ${this.requestContentType}`);
|
|
166
|
+
}
|
|
167
|
+
const bodyData = {
|
|
168
|
+
grant_type: 'refresh_token',
|
|
169
|
+
refresh_token: refreshToken,
|
|
170
|
+
};
|
|
171
|
+
if (this.clientId) {
|
|
172
|
+
bodyData.client_id = this.clientId;
|
|
173
|
+
}
|
|
174
|
+
if (this.clientSecret) {
|
|
175
|
+
bodyData.client_secret = this.clientSecret;
|
|
176
|
+
}
|
|
177
|
+
const fetchOptions = {
|
|
178
|
+
headers: {
|
|
179
|
+
'Content-type': this.requestContentType,
|
|
180
|
+
...(this.refreshRequestParameters?.header ?? {}),
|
|
181
|
+
},
|
|
182
|
+
body: this.encodeBody(bodyData, this.requestContentType),
|
|
183
|
+
method: 'POST',
|
|
184
|
+
};
|
|
185
|
+
try {
|
|
186
|
+
const fetchResult = await fetch(this.tokenUrl, fetchOptions);
|
|
187
|
+
if (fetchResult.status !== 200) {
|
|
188
|
+
throw new errors_1.FailedToRetrieveAccessTokenError(await fetchResult.text());
|
|
189
|
+
}
|
|
190
|
+
const response = await fetchResult.json();
|
|
191
|
+
const credentialsInfo = {
|
|
192
|
+
accessToken: response.access_token,
|
|
193
|
+
refreshToken: response.refresh_token,
|
|
194
|
+
};
|
|
195
|
+
return credentialsInfo;
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
throw new errors_1.FailedToRetrieveAccessTokenError(JSON.stringify(error));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Starts the Express server for handling OAuth callbacks.
|
|
203
|
+
* @returns The URL of the server.
|
|
204
|
+
*/
|
|
205
|
+
/* istanbul ignore next */
|
|
206
|
+
async startServer() {
|
|
207
|
+
const app = (0, express_1.default)();
|
|
208
|
+
const PORT = process.env.OAUTH2_PORT ?? 9002;
|
|
209
|
+
this.serverUrl = await ngrok_1.default.connect(Number(PORT));
|
|
210
|
+
app.use((0, cors_1.default)({ credentials: true, origin: true }));
|
|
211
|
+
app.use(express_1.default.json());
|
|
212
|
+
app.get('/health', (_req, res) => {
|
|
213
|
+
res.send('pong');
|
|
214
|
+
});
|
|
215
|
+
app.get('/oauth2/callback', this.handleCallback);
|
|
216
|
+
this.server = app.listen(PORT, () => {
|
|
217
|
+
console.log(`Listening at port ${PORT}`);
|
|
218
|
+
});
|
|
219
|
+
return this.serverUrl;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Stops the Express server.
|
|
223
|
+
*/
|
|
224
|
+
/* istanbul ignore next */
|
|
225
|
+
async stopServer() {
|
|
226
|
+
if (this.server) {
|
|
227
|
+
await ngrok_1.default.kill();
|
|
228
|
+
this.server.close(() => {
|
|
229
|
+
console.log('Server has stopped');
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
34
233
|
}
|
|
35
|
-
exports.
|
|
234
|
+
exports.default = OAuth2Helper;
|
|
@@ -9,6 +9,7 @@ const IntegrationsPlatform = tslib_1.__importStar(require("../../src/services/in
|
|
|
9
9
|
const IntegrationsPlatformResource = tslib_1.__importStar(require("../../src/resources/integrationsPlatform"));
|
|
10
10
|
const ConfigurationResource = tslib_1.__importStar(require("../../src/resources/configuration"));
|
|
11
11
|
const IntegrationResource = tslib_1.__importStar(require("../../src/resources/integrations"));
|
|
12
|
+
const CredentialResource = tslib_1.__importStar(require("../../src/resources/credentials"));
|
|
12
13
|
describe('Dev', () => {
|
|
13
14
|
const debuggerConfiguration = {
|
|
14
15
|
...IntegrationDebugger.getDefaultConfiguration(),
|
|
@@ -164,4 +165,24 @@ describe('Dev', () => {
|
|
|
164
165
|
.it('overrides --webhook-acknowledge-relative-url', () => {
|
|
165
166
|
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--webhook-acknowledge-relative-url=bar');
|
|
166
167
|
});
|
|
168
|
+
test_1.test
|
|
169
|
+
.stdout()
|
|
170
|
+
.stub(ConfigurationResource, 'getConfiguration', stub => stub.returns({}))
|
|
171
|
+
.stub(IntegrationResource, 'validateIsIntegrationDirectory', stub => stub.returns(true))
|
|
172
|
+
.stub(CredentialResource, 'fetchCredential', stub => stub.resolves({ payload: { from: 'credential' } }))
|
|
173
|
+
.command(['dev', '--credential-id=123'])
|
|
174
|
+
.it('credential-id', () => {
|
|
175
|
+
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--credential-payload={"from":"credential"}');
|
|
176
|
+
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--read-only');
|
|
177
|
+
});
|
|
178
|
+
test_1.test
|
|
179
|
+
.stdout()
|
|
180
|
+
.stub(ConfigurationResource, 'getConfiguration', stub => stub.returns({}))
|
|
181
|
+
.stub(IntegrationResource, 'validateIsIntegrationDirectory', stub => stub.returns(true))
|
|
182
|
+
.stub(CredentialResource, 'fetchCredential', stub => stub.resolves({ payload: { from: 'credential' } }))
|
|
183
|
+
.command(['dev', '--credential-id=123', '--no-read-only'])
|
|
184
|
+
.it('credential-id && read-only', () => {
|
|
185
|
+
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--credential-payload={"from":"credential"}');
|
|
186
|
+
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.not.include('--read-only');
|
|
187
|
+
});
|
|
167
188
|
});
|
|
@@ -4,7 +4,7 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const test_1 = require("@oclif/test");
|
|
5
5
|
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
6
6
|
const sinon = tslib_1.__importStar(require("sinon"));
|
|
7
|
-
const
|
|
7
|
+
const IntegrationResource = tslib_1.__importStar(require("../../src/resources/integrations"));
|
|
8
8
|
const Configuration = tslib_1.__importStar(require("../../src/resources/configuration"));
|
|
9
9
|
describe('init', () => {
|
|
10
10
|
beforeEach(() => {
|
|
@@ -17,7 +17,7 @@ describe('init', () => {
|
|
|
17
17
|
});
|
|
18
18
|
test_1.test
|
|
19
19
|
.stub(inquirer_1.default, 'prompt', stub => stub.resolves({ name: 'myIntegration' }))
|
|
20
|
-
.stub(
|
|
20
|
+
.stub(IntegrationResource, 'copyBoilerplate', stub => stub.returns('/my/super/path/myIntegration'))
|
|
21
21
|
.stub(process, 'chdir', stub => stub.returns(''))
|
|
22
22
|
.stdout()
|
|
23
23
|
.command(['init'])
|
|
@@ -25,7 +25,7 @@ describe('init', () => {
|
|
|
25
25
|
(0, test_1.expect)(ctx.stdout).to.contain('Your integration is available at');
|
|
26
26
|
});
|
|
27
27
|
test_1.test
|
|
28
|
-
.stub(
|
|
28
|
+
.stub(IntegrationResource, 'copyBoilerplate', stub => stub.returns('/my/super/path/myIntegration'))
|
|
29
29
|
.stub(process, 'chdir', stub => stub.returns(''))
|
|
30
30
|
.stdout()
|
|
31
31
|
.command(['init', '-n', 'myIntegration'])
|
|
@@ -33,7 +33,7 @@ describe('init', () => {
|
|
|
33
33
|
(0, test_1.expect)(ctx.stdout).to.contain('Your integration is available at');
|
|
34
34
|
});
|
|
35
35
|
test_1.test
|
|
36
|
-
.stub(
|
|
36
|
+
.stub(IntegrationResource, 'copyBoilerplate', stub => stub.throws(new Error('boom!')))
|
|
37
37
|
.stdout()
|
|
38
38
|
.command(['init', '-n', 'myIntegration'])
|
|
39
39
|
.catch(ctx => {
|
|
@@ -6,7 +6,7 @@ const core_1 = require("@oclif/core");
|
|
|
6
6
|
const sinon = tslib_1.__importStar(require("sinon"));
|
|
7
7
|
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
8
8
|
const Configuration = tslib_1.__importStar(require("../../src/resources/configuration"));
|
|
9
|
-
const oauth2Service = tslib_1.__importStar(require("../../src/
|
|
9
|
+
const oauth2Service = tslib_1.__importStar(require("../../src/resources/oauth2Helper"));
|
|
10
10
|
const IntegrationsPlatform = tslib_1.__importStar(require("../../src/services/integrationsPlatform"));
|
|
11
11
|
const decryptionResource = tslib_1.__importStar(require("../../src/resources/decryption"));
|
|
12
12
|
const configurationTypes_1 = require("../../src/configurationTypes");
|
|
@@ -59,6 +59,7 @@ describe('oauth2', () => {
|
|
|
59
59
|
});
|
|
60
60
|
test_1.test
|
|
61
61
|
.stdout()
|
|
62
|
+
.stderr()
|
|
62
63
|
.do(() => getConfigurationsStub.returns({
|
|
63
64
|
...baseConfiguration,
|
|
64
65
|
authorizations: [],
|
|
@@ -258,6 +258,7 @@ describe('Publish', () => {
|
|
|
258
258
|
});
|
|
259
259
|
test_1.test
|
|
260
260
|
.stdout()
|
|
261
|
+
.stderr()
|
|
261
262
|
.stub(GlobalConfiguration, 'read', stub => stub.throws(new errors_1.NoConfigurationFileError()))
|
|
262
263
|
.stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from('')))
|
|
263
264
|
.command(['publish'])
|
|
@@ -8,6 +8,7 @@ const IntegrationsPlatform = tslib_1.__importStar(require("../../src/services/in
|
|
|
8
8
|
const IntegrationsPlatformResource = tslib_1.__importStar(require("../../src/resources/integrationsPlatform"));
|
|
9
9
|
const ConfigurationResource = tslib_1.__importStar(require("../../src/resources/configuration"));
|
|
10
10
|
const IntegrationResource = tslib_1.__importStar(require("../../src/resources/integrations"));
|
|
11
|
+
const CredentialResource = tslib_1.__importStar(require("../../src/resources/credentials"));
|
|
11
12
|
const errors_1 = require("../../src/errors");
|
|
12
13
|
describe('Test', () => {
|
|
13
14
|
const cliConfiguration = {
|
|
@@ -50,6 +51,7 @@ describe('Test', () => {
|
|
|
50
51
|
});
|
|
51
52
|
test_1.test
|
|
52
53
|
.stdout()
|
|
54
|
+
.stderr()
|
|
53
55
|
.stub(ConfigurationResource, 'getConfiguration', stub => stub.resolves(cliConfiguration))
|
|
54
56
|
.stub(IntegrationResource, 'validateIsIntegrationDirectory', stub => stub.throws(new Error('boom!')))
|
|
55
57
|
.command(['test'])
|
|
@@ -187,4 +189,24 @@ describe('Test', () => {
|
|
|
187
189
|
.it('overrides --webhook-acknowledge-relative-url', () => {
|
|
188
190
|
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--webhook-acknowledge-relative-url=bar');
|
|
189
191
|
});
|
|
192
|
+
test_1.test
|
|
193
|
+
.stdout()
|
|
194
|
+
.stub(ConfigurationResource, 'getConfiguration', stub => stub.resolves(cliConfiguration))
|
|
195
|
+
.stub(IntegrationResource, 'validateIsIntegrationDirectory', stub => stub.returns(true))
|
|
196
|
+
.stub(CredentialResource, 'fetchCredential', stub => stub.resolves({ payload: { from: 'credential' } }))
|
|
197
|
+
.command(['test', '--credential-id=123'])
|
|
198
|
+
.it('credential-id', () => {
|
|
199
|
+
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--credential-payload={"from":"credential"}');
|
|
200
|
+
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--read-only');
|
|
201
|
+
});
|
|
202
|
+
test_1.test
|
|
203
|
+
.stdout()
|
|
204
|
+
.stub(ConfigurationResource, 'getConfiguration', stub => stub.resolves(cliConfiguration))
|
|
205
|
+
.stub(IntegrationResource, 'validateIsIntegrationDirectory', stub => stub.returns(true))
|
|
206
|
+
.stub(CredentialResource, 'fetchCredential', stub => stub.resolves({ payload: { from: 'credential' } }))
|
|
207
|
+
.command(['test', '--credential-id=123', '--no-read-only'])
|
|
208
|
+
.it('credential-id && read-only', () => {
|
|
209
|
+
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--credential-payload={"from":"credential"}');
|
|
210
|
+
(0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.not.include('--read-only');
|
|
211
|
+
});
|
|
190
212
|
});
|