@makeplane/plane-node-sdk 0.1.0 → 0.1.1
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/README.md +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/oauth/api.d.ts +54 -0
- package/dist/oauth/api.js +237 -0
- package/dist/oauth/models.d.ts +28 -0
- package/dist/oauth/models.js +2 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/oauth/api.ts +176 -0
- package/src/oauth/models.ts +30 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
## @makeplane/plane-node-sdk@0.1.
|
|
1
|
+
## @makeplane/plane-node-sdk@0.1.1
|
|
2
2
|
|
|
3
3
|
This generator creates TypeScript/JavaScript client that utilizes [Fetch API](https://fetch.spec.whatwg.org/). The generated Node module can be used in the following environments:
|
|
4
4
|
|
|
@@ -36,7 +36,7 @@ navigate to the folder of your consuming project and run one of the following co
|
|
|
36
36
|
_published:_
|
|
37
37
|
|
|
38
38
|
```
|
|
39
|
-
npm install @makeplane/plane-node-sdk@0.1.
|
|
39
|
+
npm install @makeplane/plane-node-sdk@0.1.1 --save
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
_unPublished (not recommended):_
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as runtime from "../runtime";
|
|
2
|
+
import { PlaneOAuthTokenResponse, PlaneOAuthAppInstallation } from "./models";
|
|
3
|
+
/**
|
|
4
|
+
* OAuth API helper class
|
|
5
|
+
*/
|
|
6
|
+
export declare class OAuthApi extends runtime.BaseAPI {
|
|
7
|
+
private clientId;
|
|
8
|
+
private clientSecret;
|
|
9
|
+
private redirectUri;
|
|
10
|
+
private baseUrl;
|
|
11
|
+
constructor(configuration: runtime.Configuration, oauthConfig: {
|
|
12
|
+
clientId: string;
|
|
13
|
+
clientSecret: string;
|
|
14
|
+
redirectUri: string;
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Get the authorization URL for the OAuth flow
|
|
18
|
+
* @param responseType - The response type (default: "code")
|
|
19
|
+
* @param state - Optional state parameter for security
|
|
20
|
+
* @returns The authorization URL
|
|
21
|
+
*/
|
|
22
|
+
getAuthorizationUrl(responseType?: string, state?: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Exchange authorization code for access token
|
|
25
|
+
* @param code - The authorization code
|
|
26
|
+
* @param grantType - The grant type (default: "authorization_code")
|
|
27
|
+
* @returns Promise resolving to token response
|
|
28
|
+
*/
|
|
29
|
+
exchangeCodeForToken(code: string, grantType?: string): Promise<PlaneOAuthTokenResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Get a new access token using a refresh token
|
|
32
|
+
* @param refreshToken - The refresh token
|
|
33
|
+
* @returns Promise resolving to token response
|
|
34
|
+
*/
|
|
35
|
+
getRefreshToken(refreshToken: string): Promise<PlaneOAuthTokenResponse>;
|
|
36
|
+
/**
|
|
37
|
+
* Get a new access token using client credentials for bot/app installations
|
|
38
|
+
* @param appInstallationId - The app installation ID
|
|
39
|
+
* @returns Promise resolving to token response
|
|
40
|
+
*/
|
|
41
|
+
getBotToken(appInstallationId: string): Promise<PlaneOAuthTokenResponse>;
|
|
42
|
+
/**
|
|
43
|
+
* Get an app installation by ID using the bot token
|
|
44
|
+
* @param token - The bot token from getBotToken method
|
|
45
|
+
* @param appInstallationId - The app installation ID
|
|
46
|
+
* @returns Promise resolving to app installation
|
|
47
|
+
*/
|
|
48
|
+
getAppInstallation(token: string, appInstallationId: string): Promise<PlaneOAuthAppInstallation>;
|
|
49
|
+
/**
|
|
50
|
+
* Generate basic auth token from client_id and client_secret
|
|
51
|
+
* @returns Base64 encoded basic auth token
|
|
52
|
+
*/
|
|
53
|
+
private getBasicAuthToken;
|
|
54
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
28
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
+
function step(op) {
|
|
31
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
33
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
+
switch (op[0]) {
|
|
36
|
+
case 0: case 1: t = op; break;
|
|
37
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
+
default:
|
|
41
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
+
if (t[2]) _.ops.pop();
|
|
46
|
+
_.trys.pop(); continue;
|
|
47
|
+
}
|
|
48
|
+
op = body.call(thisArg, _);
|
|
49
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.OAuthApi = void 0;
|
|
55
|
+
var runtime = require("../runtime");
|
|
56
|
+
/**
|
|
57
|
+
* OAuth API helper class
|
|
58
|
+
*/
|
|
59
|
+
var OAuthApi = /** @class */ (function (_super) {
|
|
60
|
+
__extends(OAuthApi, _super);
|
|
61
|
+
function OAuthApi(configuration, oauthConfig) {
|
|
62
|
+
var _this = _super.call(this, configuration) || this;
|
|
63
|
+
_this.clientId = oauthConfig.clientId;
|
|
64
|
+
_this.clientSecret = oauthConfig.clientSecret;
|
|
65
|
+
_this.redirectUri = oauthConfig.redirectUri;
|
|
66
|
+
_this.baseUrl = configuration.basePath || "https://api.plane.so";
|
|
67
|
+
return _this;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the authorization URL for the OAuth flow
|
|
71
|
+
* @param responseType - The response type (default: "code")
|
|
72
|
+
* @param state - Optional state parameter for security
|
|
73
|
+
* @returns The authorization URL
|
|
74
|
+
*/
|
|
75
|
+
OAuthApi.prototype.getAuthorizationUrl = function (responseType, state) {
|
|
76
|
+
if (responseType === void 0) { responseType = "code"; }
|
|
77
|
+
var params = new URLSearchParams({
|
|
78
|
+
client_id: this.clientId,
|
|
79
|
+
response_type: responseType,
|
|
80
|
+
redirect_uri: this.redirectUri,
|
|
81
|
+
});
|
|
82
|
+
if (state) {
|
|
83
|
+
params.append("state", state);
|
|
84
|
+
}
|
|
85
|
+
return "".concat(this.baseUrl, "/auth/o/authorize-app/?").concat(params.toString());
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Exchange authorization code for access token
|
|
89
|
+
* @param code - The authorization code
|
|
90
|
+
* @param grantType - The grant type (default: "authorization_code")
|
|
91
|
+
* @returns Promise resolving to token response
|
|
92
|
+
*/
|
|
93
|
+
OAuthApi.prototype.exchangeCodeForToken = function (code_1) {
|
|
94
|
+
return __awaiter(this, arguments, void 0, function (code, grantType) {
|
|
95
|
+
var data, headers, response;
|
|
96
|
+
if (grantType === void 0) { grantType = "authorization_code"; }
|
|
97
|
+
return __generator(this, function (_a) {
|
|
98
|
+
switch (_a.label) {
|
|
99
|
+
case 0:
|
|
100
|
+
data = new URLSearchParams({
|
|
101
|
+
grant_type: grantType,
|
|
102
|
+
code: code,
|
|
103
|
+
client_id: this.clientId,
|
|
104
|
+
client_secret: this.clientSecret,
|
|
105
|
+
redirect_uri: this.redirectUri,
|
|
106
|
+
});
|
|
107
|
+
headers = {
|
|
108
|
+
"Cache-Control": "no-cache",
|
|
109
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
110
|
+
};
|
|
111
|
+
return [4 /*yield*/, this.request({
|
|
112
|
+
path: "/auth/o/token/",
|
|
113
|
+
method: "POST",
|
|
114
|
+
headers: headers,
|
|
115
|
+
body: data,
|
|
116
|
+
})];
|
|
117
|
+
case 1:
|
|
118
|
+
response = _a.sent();
|
|
119
|
+
return [4 /*yield*/, response.json()];
|
|
120
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Get a new access token using a refresh token
|
|
127
|
+
* @param refreshToken - The refresh token
|
|
128
|
+
* @returns Promise resolving to token response
|
|
129
|
+
*/
|
|
130
|
+
OAuthApi.prototype.getRefreshToken = function (refreshToken) {
|
|
131
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
132
|
+
var data, headers, response;
|
|
133
|
+
return __generator(this, function (_a) {
|
|
134
|
+
switch (_a.label) {
|
|
135
|
+
case 0:
|
|
136
|
+
data = new URLSearchParams({
|
|
137
|
+
grant_type: "refresh_token",
|
|
138
|
+
refresh_token: refreshToken,
|
|
139
|
+
client_id: this.clientId,
|
|
140
|
+
client_secret: this.clientSecret,
|
|
141
|
+
});
|
|
142
|
+
headers = {
|
|
143
|
+
"Cache-Control": "no-cache",
|
|
144
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
145
|
+
};
|
|
146
|
+
return [4 /*yield*/, this.request({
|
|
147
|
+
path: "/auth/o/token/",
|
|
148
|
+
method: "POST",
|
|
149
|
+
headers: headers,
|
|
150
|
+
body: data,
|
|
151
|
+
})];
|
|
152
|
+
case 1:
|
|
153
|
+
response = _a.sent();
|
|
154
|
+
return [4 /*yield*/, response.json()];
|
|
155
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Get a new access token using client credentials for bot/app installations
|
|
162
|
+
* @param appInstallationId - The app installation ID
|
|
163
|
+
* @returns Promise resolving to token response
|
|
164
|
+
*/
|
|
165
|
+
OAuthApi.prototype.getBotToken = function (appInstallationId) {
|
|
166
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
167
|
+
var data, headers, response;
|
|
168
|
+
return __generator(this, function (_a) {
|
|
169
|
+
switch (_a.label) {
|
|
170
|
+
case 0:
|
|
171
|
+
data = new URLSearchParams({
|
|
172
|
+
grant_type: "client_credentials",
|
|
173
|
+
app_installation_id: appInstallationId,
|
|
174
|
+
});
|
|
175
|
+
headers = {
|
|
176
|
+
"Cache-Control": "no-cache",
|
|
177
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
178
|
+
Authorization: "Basic ".concat(this.getBasicAuthToken()),
|
|
179
|
+
};
|
|
180
|
+
return [4 /*yield*/, this.request({
|
|
181
|
+
path: "/auth/o/token/",
|
|
182
|
+
method: "POST",
|
|
183
|
+
headers: headers,
|
|
184
|
+
body: data,
|
|
185
|
+
})];
|
|
186
|
+
case 1:
|
|
187
|
+
response = _a.sent();
|
|
188
|
+
return [4 /*yield*/, response.json()];
|
|
189
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* Get an app installation by ID using the bot token
|
|
196
|
+
* @param token - The bot token from getBotToken method
|
|
197
|
+
* @param appInstallationId - The app installation ID
|
|
198
|
+
* @returns Promise resolving to app installation
|
|
199
|
+
*/
|
|
200
|
+
OAuthApi.prototype.getAppInstallation = function (token, appInstallationId) {
|
|
201
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
202
|
+
var headers, response, data;
|
|
203
|
+
return __generator(this, function (_a) {
|
|
204
|
+
switch (_a.label) {
|
|
205
|
+
case 0:
|
|
206
|
+
headers = {
|
|
207
|
+
Authorization: "Bearer ".concat(token),
|
|
208
|
+
};
|
|
209
|
+
return [4 /*yield*/, this.request({
|
|
210
|
+
path: "/auth/o/app-installation/?id=".concat(appInstallationId),
|
|
211
|
+
method: "GET",
|
|
212
|
+
headers: headers,
|
|
213
|
+
})];
|
|
214
|
+
case 1:
|
|
215
|
+
response = _a.sent();
|
|
216
|
+
return [4 /*yield*/, response.json()];
|
|
217
|
+
case 2:
|
|
218
|
+
data = _a.sent();
|
|
219
|
+
if (!data || data.length === 0) {
|
|
220
|
+
throw new runtime.ResponseError(response, "App installation not found");
|
|
221
|
+
}
|
|
222
|
+
return [2 /*return*/, data[0]];
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Generate basic auth token from client_id and client_secret
|
|
229
|
+
* @returns Base64 encoded basic auth token
|
|
230
|
+
*/
|
|
231
|
+
OAuthApi.prototype.getBasicAuthToken = function () {
|
|
232
|
+
var credentials = "".concat(this.clientId, ":").concat(this.clientSecret);
|
|
233
|
+
return btoa(credentials);
|
|
234
|
+
};
|
|
235
|
+
return OAuthApi;
|
|
236
|
+
}(runtime.BaseAPI));
|
|
237
|
+
exports.OAuthApi = OAuthApi;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface PlaneOAuthTokenResponse {
|
|
2
|
+
access_token: string;
|
|
3
|
+
expires_in?: number;
|
|
4
|
+
token_type: string;
|
|
5
|
+
scope?: string;
|
|
6
|
+
refresh_token?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface WorkspaceDetail {
|
|
9
|
+
name: string;
|
|
10
|
+
slug: string;
|
|
11
|
+
id: string;
|
|
12
|
+
logo_url?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PlaneOAuthAppInstallation {
|
|
15
|
+
id: string;
|
|
16
|
+
workspace_detail: WorkspaceDetail;
|
|
17
|
+
created_at: string;
|
|
18
|
+
updated_at: string;
|
|
19
|
+
deleted_at?: string;
|
|
20
|
+
status: string;
|
|
21
|
+
created_by?: string;
|
|
22
|
+
updated_by?: string;
|
|
23
|
+
workspace: string;
|
|
24
|
+
application: string;
|
|
25
|
+
installed_by: string;
|
|
26
|
+
app_bot: string;
|
|
27
|
+
webhook?: string;
|
|
28
|
+
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/src/oauth/api.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import * as runtime from "../runtime";
|
|
2
|
+
import { PlaneOAuthTokenResponse, PlaneOAuthAppInstallation } from "./models";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* OAuth API helper class
|
|
6
|
+
*/
|
|
7
|
+
export class OAuthApi extends runtime.BaseAPI {
|
|
8
|
+
private clientId: string;
|
|
9
|
+
private clientSecret: string;
|
|
10
|
+
private redirectUri: string;
|
|
11
|
+
private baseUrl: string;
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
configuration: runtime.Configuration,
|
|
15
|
+
oauthConfig: {
|
|
16
|
+
clientId: string;
|
|
17
|
+
clientSecret: string;
|
|
18
|
+
redirectUri: string;
|
|
19
|
+
}
|
|
20
|
+
) {
|
|
21
|
+
super(configuration);
|
|
22
|
+
this.clientId = oauthConfig.clientId;
|
|
23
|
+
this.clientSecret = oauthConfig.clientSecret;
|
|
24
|
+
this.redirectUri = oauthConfig.redirectUri;
|
|
25
|
+
this.baseUrl = configuration.basePath || "https://api.plane.so";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the authorization URL for the OAuth flow
|
|
30
|
+
* @param responseType - The response type (default: "code")
|
|
31
|
+
* @param state - Optional state parameter for security
|
|
32
|
+
* @returns The authorization URL
|
|
33
|
+
*/
|
|
34
|
+
getAuthorizationUrl(responseType: string = "code", state?: string): string {
|
|
35
|
+
const params = new URLSearchParams({
|
|
36
|
+
client_id: this.clientId,
|
|
37
|
+
response_type: responseType,
|
|
38
|
+
redirect_uri: this.redirectUri,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (state) {
|
|
42
|
+
params.append("state", state);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return `${this.baseUrl}/auth/o/authorize-app/?${params.toString()}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Exchange authorization code for access token
|
|
50
|
+
* @param code - The authorization code
|
|
51
|
+
* @param grantType - The grant type (default: "authorization_code")
|
|
52
|
+
* @returns Promise resolving to token response
|
|
53
|
+
*/
|
|
54
|
+
async exchangeCodeForToken(
|
|
55
|
+
code: string,
|
|
56
|
+
grantType: string = "authorization_code"
|
|
57
|
+
): Promise<PlaneOAuthTokenResponse> {
|
|
58
|
+
const data = new URLSearchParams({
|
|
59
|
+
grant_type: grantType,
|
|
60
|
+
code: code,
|
|
61
|
+
client_id: this.clientId,
|
|
62
|
+
client_secret: this.clientSecret,
|
|
63
|
+
redirect_uri: this.redirectUri,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const headers: runtime.HTTPHeaders = {
|
|
67
|
+
"Cache-Control": "no-cache",
|
|
68
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const response = await this.request({
|
|
72
|
+
path: `/auth/o/token/`,
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers: headers,
|
|
75
|
+
body: data,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return await response.json();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get a new access token using a refresh token
|
|
83
|
+
* @param refreshToken - The refresh token
|
|
84
|
+
* @returns Promise resolving to token response
|
|
85
|
+
*/
|
|
86
|
+
async getRefreshToken(
|
|
87
|
+
refreshToken: string
|
|
88
|
+
): Promise<PlaneOAuthTokenResponse> {
|
|
89
|
+
const data = new URLSearchParams({
|
|
90
|
+
grant_type: "refresh_token",
|
|
91
|
+
refresh_token: refreshToken,
|
|
92
|
+
client_id: this.clientId,
|
|
93
|
+
client_secret: this.clientSecret,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const headers: runtime.HTTPHeaders = {
|
|
97
|
+
"Cache-Control": "no-cache",
|
|
98
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const response = await this.request({
|
|
102
|
+
path: `/auth/o/token/`,
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: headers,
|
|
105
|
+
body: data,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return await response.json();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get a new access token using client credentials for bot/app installations
|
|
113
|
+
* @param appInstallationId - The app installation ID
|
|
114
|
+
* @returns Promise resolving to token response
|
|
115
|
+
*/
|
|
116
|
+
async getBotToken(
|
|
117
|
+
appInstallationId: string
|
|
118
|
+
): Promise<PlaneOAuthTokenResponse> {
|
|
119
|
+
const data = new URLSearchParams({
|
|
120
|
+
grant_type: "client_credentials",
|
|
121
|
+
app_installation_id: appInstallationId,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const headers: runtime.HTTPHeaders = {
|
|
125
|
+
"Cache-Control": "no-cache",
|
|
126
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
127
|
+
Authorization: `Basic ${this.getBasicAuthToken()}`,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const response = await this.request({
|
|
131
|
+
path: `/auth/o/token/`,
|
|
132
|
+
method: "POST",
|
|
133
|
+
headers: headers,
|
|
134
|
+
body: data,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return await response.json();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get an app installation by ID using the bot token
|
|
142
|
+
* @param token - The bot token from getBotToken method
|
|
143
|
+
* @param appInstallationId - The app installation ID
|
|
144
|
+
* @returns Promise resolving to app installation
|
|
145
|
+
*/
|
|
146
|
+
async getAppInstallation(
|
|
147
|
+
token: string,
|
|
148
|
+
appInstallationId: string
|
|
149
|
+
): Promise<PlaneOAuthAppInstallation> {
|
|
150
|
+
const headers: runtime.HTTPHeaders = {
|
|
151
|
+
Authorization: `Bearer ${token}`,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const response = await this.request({
|
|
155
|
+
path: `/auth/o/app-installation/?id=${appInstallationId}`,
|
|
156
|
+
method: "GET",
|
|
157
|
+
headers: headers,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const data = await response.json();
|
|
161
|
+
if (!data || data.length === 0) {
|
|
162
|
+
throw new runtime.ResponseError(response, "App installation not found");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return data[0];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Generate basic auth token from client_id and client_secret
|
|
170
|
+
* @returns Base64 encoded basic auth token
|
|
171
|
+
*/
|
|
172
|
+
private getBasicAuthToken(): string {
|
|
173
|
+
const credentials = `${this.clientId}:${this.clientSecret}`;
|
|
174
|
+
return btoa(credentials);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface PlaneOAuthTokenResponse {
|
|
2
|
+
access_token: string;
|
|
3
|
+
expires_in?: number;
|
|
4
|
+
token_type: string;
|
|
5
|
+
scope?: string;
|
|
6
|
+
refresh_token?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface WorkspaceDetail {
|
|
10
|
+
name: string;
|
|
11
|
+
slug: string;
|
|
12
|
+
id: string;
|
|
13
|
+
logo_url?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface PlaneOAuthAppInstallation {
|
|
17
|
+
id: string;
|
|
18
|
+
workspace_detail: WorkspaceDetail;
|
|
19
|
+
created_at: string;
|
|
20
|
+
updated_at: string;
|
|
21
|
+
deleted_at?: string;
|
|
22
|
+
status: string;
|
|
23
|
+
created_by?: string;
|
|
24
|
+
updated_by?: string;
|
|
25
|
+
workspace: string;
|
|
26
|
+
application: string;
|
|
27
|
+
installed_by: string;
|
|
28
|
+
app_bot: string;
|
|
29
|
+
webhook?: string;
|
|
30
|
+
}
|