decap-cms-backend-github 3.1.0-beta.0 → 3.1.0-beta.2
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/CHANGELOG.md +88 -449
- package/README.md +1 -1
- package/dist/decap-cms-backend-github.js +8 -8
- package/dist/decap-cms-backend-github.js.map +1 -1
- package/dist/esm/API.js +11 -6
- package/dist/esm/GraphQLAPI.js +1 -1
- package/dist/esm/implementation.js +49 -22
- package/package.json +3 -3
- package/src/API.ts +12 -8
- package/src/GraphQLAPI.ts +1 -1
- package/src/implementation.tsx +41 -18
package/dist/esm/API.js
CHANGED
|
@@ -77,6 +77,7 @@ class API {
|
|
|
77
77
|
constructor(config) {
|
|
78
78
|
_defineProperty(this, "apiRoot", void 0);
|
|
79
79
|
_defineProperty(this, "token", void 0);
|
|
80
|
+
_defineProperty(this, "tokenKeyword", void 0);
|
|
80
81
|
_defineProperty(this, "branch", void 0);
|
|
81
82
|
_defineProperty(this, "useOpenAuthoring", void 0);
|
|
82
83
|
_defineProperty(this, "repo", void 0);
|
|
@@ -90,6 +91,8 @@ class API {
|
|
|
90
91
|
_defineProperty(this, "mergeMethod", void 0);
|
|
91
92
|
_defineProperty(this, "initialWorkflowStatus", void 0);
|
|
92
93
|
_defineProperty(this, "cmsLabelPrefix", void 0);
|
|
94
|
+
_defineProperty(this, "baseUrl", void 0);
|
|
95
|
+
_defineProperty(this, "getUser", void 0);
|
|
93
96
|
_defineProperty(this, "_userPromise", void 0);
|
|
94
97
|
_defineProperty(this, "_metadataSemaphore", void 0);
|
|
95
98
|
_defineProperty(this, "commitAuthor", void 0);
|
|
@@ -122,6 +125,7 @@ class API {
|
|
|
122
125
|
});
|
|
123
126
|
this.apiRoot = config.apiRoot || 'https://api.github.com';
|
|
124
127
|
this.token = config.token || '';
|
|
128
|
+
this.tokenKeyword = config.tokenKeyword || 'token';
|
|
125
129
|
this.branch = config.branch || 'master';
|
|
126
130
|
this.useOpenAuthoring = config.useOpenAuthoring;
|
|
127
131
|
this.repo = config.repo || '';
|
|
@@ -137,16 +141,17 @@ class API {
|
|
|
137
141
|
this.mergeMethod = config.squashMerges ? 'squash' : 'merge';
|
|
138
142
|
this.cmsLabelPrefix = config.cmsLabelPrefix;
|
|
139
143
|
this.initialWorkflowStatus = config.initialWorkflowStatus;
|
|
144
|
+
this.baseUrl = config.baseUrl;
|
|
145
|
+
this.getUser = config.getUser;
|
|
140
146
|
}
|
|
141
147
|
user() {
|
|
142
148
|
if (!this._userPromise) {
|
|
143
|
-
this._userPromise = this.getUser(
|
|
149
|
+
this._userPromise = this.getUser({
|
|
150
|
+
token: this.token
|
|
151
|
+
});
|
|
144
152
|
}
|
|
145
153
|
return this._userPromise;
|
|
146
154
|
}
|
|
147
|
-
getUser() {
|
|
148
|
-
return this.request('/user');
|
|
149
|
-
}
|
|
150
155
|
async hasWriteAccess() {
|
|
151
156
|
try {
|
|
152
157
|
const result = await this.request(this.repoURL);
|
|
@@ -166,7 +171,7 @@ class API {
|
|
|
166
171
|
'Content-Type': 'application/json; charset=utf-8'
|
|
167
172
|
}, headers);
|
|
168
173
|
if (this.token) {
|
|
169
|
-
baseHeader.Authorization =
|
|
174
|
+
baseHeader.Authorization = `${this.tokenKeyword} ${this.token}`;
|
|
170
175
|
return Promise.resolve(baseHeader);
|
|
171
176
|
}
|
|
172
177
|
return Promise.resolve(baseHeader);
|
|
@@ -444,7 +449,7 @@ class API {
|
|
|
444
449
|
return;
|
|
445
450
|
}
|
|
446
451
|
try {
|
|
447
|
-
const user = await this.
|
|
452
|
+
const user = await this.user();
|
|
448
453
|
return user.name || user.login;
|
|
449
454
|
} catch {
|
|
450
455
|
return;
|
package/dist/esm/GraphQLAPI.js
CHANGED
|
@@ -58,7 +58,7 @@ class GraphQLAPI extends _API.default {
|
|
|
58
58
|
headers: _objectSpread(_objectSpread({
|
|
59
59
|
'Content-Type': 'application/json; charset=utf-8'
|
|
60
60
|
}, headers), {}, {
|
|
61
|
-
authorization: this.token ?
|
|
61
|
+
authorization: this.token ? `${this.tokenKeyword} ${this.token}` : ''
|
|
62
62
|
})
|
|
63
63
|
};
|
|
64
64
|
});
|
|
@@ -45,9 +45,12 @@ class GitHub {
|
|
|
45
45
|
_defineProperty(this, "mediaFolder", void 0);
|
|
46
46
|
_defineProperty(this, "previewContext", void 0);
|
|
47
47
|
_defineProperty(this, "token", void 0);
|
|
48
|
+
_defineProperty(this, "tokenKeyword", void 0);
|
|
48
49
|
_defineProperty(this, "squashMerges", void 0);
|
|
49
50
|
_defineProperty(this, "cmsLabelPrefix", void 0);
|
|
50
51
|
_defineProperty(this, "useGraphql", void 0);
|
|
52
|
+
_defineProperty(this, "baseUrl", void 0);
|
|
53
|
+
_defineProperty(this, "bypassWriteAccessCheckForAppTokens", false);
|
|
51
54
|
_defineProperty(this, "_currentUserPromise", void 0);
|
|
52
55
|
_defineProperty(this, "_userIsOriginMaintainerPromises", void 0);
|
|
53
56
|
_defineProperty(this, "_mediaDisplayURLSem", void 0);
|
|
@@ -104,6 +107,8 @@ class GitHub {
|
|
|
104
107
|
this.branch = ((_config$backend$branc = config.backend.branch) === null || _config$backend$branc === void 0 ? void 0 : _config$backend$branc.trim()) || 'master';
|
|
105
108
|
this.apiRoot = config.backend.api_root || 'https://api.github.com';
|
|
106
109
|
this.token = '';
|
|
110
|
+
this.tokenKeyword = 'token';
|
|
111
|
+
this.baseUrl = config.backend.base_url;
|
|
107
112
|
this.squashMerges = config.backend.squash_merges || false;
|
|
108
113
|
this.cmsLabelPrefix = config.backend.cms_label_prefix || '';
|
|
109
114
|
this.useGraphql = config.backend.use_graphql || false;
|
|
@@ -124,8 +129,10 @@ class GitHub {
|
|
|
124
129
|
let auth = false;
|
|
125
130
|
// no need to check auth if api is down
|
|
126
131
|
if (api) {
|
|
127
|
-
var _this$api;
|
|
128
|
-
auth = (await ((_this$api = this.api) === null || _this$api === void 0 ? void 0 : _this$api.getUser(
|
|
132
|
+
var _this$api, _this$token;
|
|
133
|
+
auth = (await ((_this$api = this.api) === null || _this$api === void 0 ? void 0 : _this$api.getUser({
|
|
134
|
+
token: (_this$token = this.token) !== null && _this$token !== void 0 ? _this$token : ''
|
|
135
|
+
}).then(user => !!user).catch(e => {
|
|
129
136
|
console.warn('Failed getting GitHub user', e);
|
|
130
137
|
return false;
|
|
131
138
|
}))) || false;
|
|
@@ -162,7 +169,7 @@ class GitHub {
|
|
|
162
169
|
while (!repoExists) {
|
|
163
170
|
repoExists = await fetch(`${this.apiRoot}/repos/${repo}`, {
|
|
164
171
|
headers: {
|
|
165
|
-
Authorization:
|
|
172
|
+
Authorization: `${this.tokenKeyword} ${token}`
|
|
166
173
|
}
|
|
167
174
|
}).then(() => true).catch(err => {
|
|
168
175
|
if (err && err.status === 404) {
|
|
@@ -185,7 +192,7 @@ class GitHub {
|
|
|
185
192
|
if (!this._currentUserPromise) {
|
|
186
193
|
this._currentUserPromise = fetch(`${this.apiRoot}/user`, {
|
|
187
194
|
headers: {
|
|
188
|
-
Authorization:
|
|
195
|
+
Authorization: `${this.tokenKeyword} ${token}`
|
|
189
196
|
}
|
|
190
197
|
}).then(res => res.json());
|
|
191
198
|
}
|
|
@@ -202,7 +209,7 @@ class GitHub {
|
|
|
202
209
|
if (!this._userIsOriginMaintainerPromises[username]) {
|
|
203
210
|
this._userIsOriginMaintainerPromises[username] = fetch(`${this.apiRoot}/repos/${this.originRepo}/collaborators/${username}/permission`, {
|
|
204
211
|
headers: {
|
|
205
|
-
Authorization:
|
|
212
|
+
Authorization: `${this.tokenKeyword} ${token}`
|
|
206
213
|
}
|
|
207
214
|
}).then(res => res.json()).then(({
|
|
208
215
|
permission
|
|
@@ -221,7 +228,7 @@ class GitHub {
|
|
|
221
228
|
const repo = await fetch(`${this.apiRoot}/repos/${currentUser.login}/${repoName}`, {
|
|
222
229
|
method: 'GET',
|
|
223
230
|
headers: {
|
|
224
|
-
Authorization:
|
|
231
|
+
Authorization: `${this.tokenKeyword} ${token}`
|
|
225
232
|
}
|
|
226
233
|
}).then(res => res.json());
|
|
227
234
|
|
|
@@ -252,29 +259,47 @@ class GitHub {
|
|
|
252
259
|
this.useOpenAuthoring = false;
|
|
253
260
|
return Promise.resolve();
|
|
254
261
|
}
|
|
255
|
-
|
|
262
|
+
|
|
263
|
+
// If a fork exists merge it with upstream
|
|
264
|
+
// otherwise create a new fork.
|
|
265
|
+
const currentUser = await this.currentUser({
|
|
256
266
|
token
|
|
257
|
-
})
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
const fork = await fetch(`${this.apiRoot}/repos/${this.originRepo}/forks`, {
|
|
261
|
-
method: 'POST',
|
|
262
|
-
headers: {
|
|
263
|
-
Authorization: `token ${token}`
|
|
264
|
-
}
|
|
265
|
-
}).then(res => res.json());
|
|
267
|
+
});
|
|
268
|
+
const repoName = this.originRepo.split('/')[1];
|
|
269
|
+
this.repo = `${currentUser.login}/${repoName}`;
|
|
266
270
|
this.useOpenAuthoring = true;
|
|
267
|
-
|
|
268
|
-
return this.pollUntilForkExists({
|
|
269
|
-
repo: fork.full_name,
|
|
271
|
+
if (await this.forkExists({
|
|
270
272
|
token
|
|
271
|
-
})
|
|
273
|
+
})) {
|
|
274
|
+
return fetch(`${this.apiRoot}/repos/${this.repo}/merge-upstream`, {
|
|
275
|
+
method: 'POST',
|
|
276
|
+
headers: {
|
|
277
|
+
Authorization: `${this.tokenKeyword} ${token}`
|
|
278
|
+
},
|
|
279
|
+
body: JSON.stringify({
|
|
280
|
+
branch: this.branch
|
|
281
|
+
})
|
|
282
|
+
});
|
|
283
|
+
} else {
|
|
284
|
+
await getPermissionToFork();
|
|
285
|
+
const fork = await fetch(`${this.apiRoot}/repos/${this.originRepo}/forks`, {
|
|
286
|
+
method: 'POST',
|
|
287
|
+
headers: {
|
|
288
|
+
Authorization: `${this.tokenKeyword} ${token}`
|
|
289
|
+
}
|
|
290
|
+
}).then(res => res.json());
|
|
291
|
+
return this.pollUntilForkExists({
|
|
292
|
+
repo: fork.full_name,
|
|
293
|
+
token
|
|
294
|
+
});
|
|
295
|
+
}
|
|
272
296
|
}
|
|
273
297
|
async authenticate(state) {
|
|
274
298
|
this.token = state.token;
|
|
275
299
|
const apiCtor = this.useGraphql ? _GraphQLAPI.default : _API.default;
|
|
276
300
|
this.api = new apiCtor({
|
|
277
301
|
token: this.token,
|
|
302
|
+
tokenKeyword: this.tokenKeyword,
|
|
278
303
|
branch: this.branch,
|
|
279
304
|
repo: this.repo,
|
|
280
305
|
originRepo: this.originRepo,
|
|
@@ -282,7 +307,9 @@ class GitHub {
|
|
|
282
307
|
squashMerges: this.squashMerges,
|
|
283
308
|
cmsLabelPrefix: this.cmsLabelPrefix,
|
|
284
309
|
useOpenAuthoring: this.useOpenAuthoring,
|
|
285
|
-
initialWorkflowStatus: this.options.initialWorkflowStatus
|
|
310
|
+
initialWorkflowStatus: this.options.initialWorkflowStatus,
|
|
311
|
+
baseUrl: this.baseUrl,
|
|
312
|
+
getUser: this.currentUser
|
|
286
313
|
});
|
|
287
314
|
const user = await this.api.user();
|
|
288
315
|
const isCollab = await this.api.hasWriteAccess().catch(error => {
|
|
@@ -299,7 +326,7 @@ class GitHub {
|
|
|
299
326
|
});
|
|
300
327
|
|
|
301
328
|
// Unauthorized user
|
|
302
|
-
if (!isCollab) {
|
|
329
|
+
if (!isCollab && !this.bypassWriteAccessCheckForAppTokens) {
|
|
303
330
|
throw new Error('Your GitHub user account does not have access to this repo.');
|
|
304
331
|
}
|
|
305
332
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "decap-cms-backend-github",
|
|
3
3
|
"description": "GitHub backend for Decap CMS",
|
|
4
|
-
"version": "3.1.0-beta.
|
|
4
|
+
"version": "3.1.0-beta.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/decaporg/decap-cms/tree/master/packages/decap-cms-backend-github",
|
|
7
7
|
"bugs": "https://github.com/decaporg/decap-cms/issues",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"sideEffects": false,
|
|
16
16
|
"scripts": {
|
|
17
|
-
"develop": "
|
|
17
|
+
"develop": "npm run build:esm -- --watch",
|
|
18
18
|
"build": "cross-env NODE_ENV=production webpack",
|
|
19
19
|
"build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"",
|
|
20
20
|
"createFragmentTypes": "node scripts/createFragmentTypes.js"
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"prop-types": "^15.7.2",
|
|
41
41
|
"react": "^18.2.0"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "d7a43e3bb45259ab0789362ea804df31fec77e21"
|
|
44
44
|
}
|
package/src/API.ts
CHANGED
|
@@ -50,6 +50,7 @@ export const MOCK_PULL_REQUEST = -1;
|
|
|
50
50
|
export interface Config {
|
|
51
51
|
apiRoot?: string;
|
|
52
52
|
token?: string;
|
|
53
|
+
tokenKeyword?: string;
|
|
53
54
|
branch?: string;
|
|
54
55
|
useOpenAuthoring?: boolean;
|
|
55
56
|
repo?: string;
|
|
@@ -57,6 +58,8 @@ export interface Config {
|
|
|
57
58
|
squashMerges: boolean;
|
|
58
59
|
initialWorkflowStatus: string;
|
|
59
60
|
cmsLabelPrefix: string;
|
|
61
|
+
baseUrl?: string;
|
|
62
|
+
getUser: ({ token }: { token: string }) => Promise<GitHubUser>;
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
interface TreeFile {
|
|
@@ -173,6 +176,7 @@ let migrationNotified = false;
|
|
|
173
176
|
export default class API {
|
|
174
177
|
apiRoot: string;
|
|
175
178
|
token: string;
|
|
179
|
+
tokenKeyword: string;
|
|
176
180
|
branch: string;
|
|
177
181
|
useOpenAuthoring?: boolean;
|
|
178
182
|
repo: string;
|
|
@@ -186,7 +190,8 @@ export default class API {
|
|
|
186
190
|
mergeMethod: string;
|
|
187
191
|
initialWorkflowStatus: string;
|
|
188
192
|
cmsLabelPrefix: string;
|
|
189
|
-
|
|
193
|
+
baseUrl?: string;
|
|
194
|
+
getUser: ({ token }: { token: string }) => Promise<GitHubUser>;
|
|
190
195
|
_userPromise?: Promise<GitHubUser>;
|
|
191
196
|
_metadataSemaphore?: Semaphore;
|
|
192
197
|
|
|
@@ -195,6 +200,7 @@ export default class API {
|
|
|
195
200
|
constructor(config: Config) {
|
|
196
201
|
this.apiRoot = config.apiRoot || 'https://api.github.com';
|
|
197
202
|
this.token = config.token || '';
|
|
203
|
+
this.tokenKeyword = config.tokenKeyword || 'token';
|
|
198
204
|
this.branch = config.branch || 'master';
|
|
199
205
|
this.useOpenAuthoring = config.useOpenAuthoring;
|
|
200
206
|
this.repo = config.repo || '';
|
|
@@ -213,21 +219,19 @@ export default class API {
|
|
|
213
219
|
this.mergeMethod = config.squashMerges ? 'squash' : 'merge';
|
|
214
220
|
this.cmsLabelPrefix = config.cmsLabelPrefix;
|
|
215
221
|
this.initialWorkflowStatus = config.initialWorkflowStatus;
|
|
222
|
+
this.baseUrl = config.baseUrl;
|
|
223
|
+
this.getUser = config.getUser;
|
|
216
224
|
}
|
|
217
225
|
|
|
218
226
|
static DEFAULT_COMMIT_MESSAGE = 'Automatically generated by Decap CMS';
|
|
219
227
|
|
|
220
228
|
user(): Promise<{ name: string; login: string }> {
|
|
221
229
|
if (!this._userPromise) {
|
|
222
|
-
this._userPromise = this.getUser();
|
|
230
|
+
this._userPromise = this.getUser({ token: this.token });
|
|
223
231
|
}
|
|
224
232
|
return this._userPromise;
|
|
225
233
|
}
|
|
226
234
|
|
|
227
|
-
getUser() {
|
|
228
|
-
return this.request('/user') as Promise<GitHubUser>;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
235
|
async hasWriteAccess() {
|
|
232
236
|
try {
|
|
233
237
|
const result: Octokit.ReposGetResponse = await this.request(this.repoURL);
|
|
@@ -251,7 +255,7 @@ export default class API {
|
|
|
251
255
|
};
|
|
252
256
|
|
|
253
257
|
if (this.token) {
|
|
254
|
-
baseHeader.Authorization =
|
|
258
|
+
baseHeader.Authorization = `${this.tokenKeyword} ${this.token}`;
|
|
255
259
|
return Promise.resolve(baseHeader);
|
|
256
260
|
}
|
|
257
261
|
|
|
@@ -576,7 +580,7 @@ export default class API {
|
|
|
576
580
|
}
|
|
577
581
|
|
|
578
582
|
try {
|
|
579
|
-
const user
|
|
583
|
+
const user = await this.user();
|
|
580
584
|
return user.name || user.login;
|
|
581
585
|
} catch {
|
|
582
586
|
return;
|
package/src/GraphQLAPI.ts
CHANGED
|
@@ -108,7 +108,7 @@ export default class GraphQLAPI extends API {
|
|
|
108
108
|
headers: {
|
|
109
109
|
'Content-Type': 'application/json; charset=utf-8',
|
|
110
110
|
...headers,
|
|
111
|
-
authorization: this.token ?
|
|
111
|
+
authorization: this.token ? `${this.tokenKeyword} ${this.token}` : '',
|
|
112
112
|
},
|
|
113
113
|
};
|
|
114
114
|
});
|
package/src/implementation.tsx
CHANGED
|
@@ -42,7 +42,7 @@ import type {
|
|
|
42
42
|
} from 'decap-cms-lib-util';
|
|
43
43
|
import type { Semaphore } from 'semaphore';
|
|
44
44
|
|
|
45
|
-
type GitHubUser = Octokit.UsersGetAuthenticatedResponse;
|
|
45
|
+
export type GitHubUser = Octokit.UsersGetAuthenticatedResponse;
|
|
46
46
|
|
|
47
47
|
const MAX_CONCURRENT_DOWNLOADS = 10;
|
|
48
48
|
|
|
@@ -78,9 +78,12 @@ export default class GitHub implements Implementation {
|
|
|
78
78
|
mediaFolder: string;
|
|
79
79
|
previewContext: string;
|
|
80
80
|
token: string | null;
|
|
81
|
+
tokenKeyword: string;
|
|
81
82
|
squashMerges: boolean;
|
|
82
83
|
cmsLabelPrefix: string;
|
|
83
84
|
useGraphql: boolean;
|
|
85
|
+
baseUrl?: string;
|
|
86
|
+
bypassWriteAccessCheckForAppTokens = false;
|
|
84
87
|
_currentUserPromise?: Promise<GitHubUser>;
|
|
85
88
|
_userIsOriginMaintainerPromises?: {
|
|
86
89
|
[key: string]: Promise<boolean>;
|
|
@@ -119,6 +122,8 @@ export default class GitHub implements Implementation {
|
|
|
119
122
|
this.branch = config.backend.branch?.trim() || 'master';
|
|
120
123
|
this.apiRoot = config.backend.api_root || 'https://api.github.com';
|
|
121
124
|
this.token = '';
|
|
125
|
+
this.tokenKeyword = 'token';
|
|
126
|
+
this.baseUrl = config.backend.base_url;
|
|
122
127
|
this.squashMerges = config.backend.squash_merges || false;
|
|
123
128
|
this.cmsLabelPrefix = config.backend.cms_label_prefix || '';
|
|
124
129
|
this.useGraphql = config.backend.use_graphql || false;
|
|
@@ -153,7 +158,7 @@ export default class GitHub implements Implementation {
|
|
|
153
158
|
if (api) {
|
|
154
159
|
auth =
|
|
155
160
|
(await this.api
|
|
156
|
-
?.getUser()
|
|
161
|
+
?.getUser({ token: this.token ?? '' })
|
|
157
162
|
.then(user => !!user)
|
|
158
163
|
.catch(e => {
|
|
159
164
|
console.warn('Failed getting GitHub user', e);
|
|
@@ -185,7 +190,7 @@ export default class GitHub implements Implementation {
|
|
|
185
190
|
let repoExists = false;
|
|
186
191
|
while (!repoExists) {
|
|
187
192
|
repoExists = await fetch(`${this.apiRoot}/repos/${repo}`, {
|
|
188
|
-
headers: { Authorization:
|
|
193
|
+
headers: { Authorization: `${this.tokenKeyword} ${token}` },
|
|
189
194
|
})
|
|
190
195
|
.then(() => true)
|
|
191
196
|
.catch(err => {
|
|
@@ -208,7 +213,7 @@ export default class GitHub implements Implementation {
|
|
|
208
213
|
if (!this._currentUserPromise) {
|
|
209
214
|
this._currentUserPromise = fetch(`${this.apiRoot}/user`, {
|
|
210
215
|
headers: {
|
|
211
|
-
Authorization:
|
|
216
|
+
Authorization: `${this.tokenKeyword} ${token}`,
|
|
212
217
|
},
|
|
213
218
|
}).then(res => res.json());
|
|
214
219
|
}
|
|
@@ -229,7 +234,7 @@ export default class GitHub implements Implementation {
|
|
|
229
234
|
`${this.apiRoot}/repos/${this.originRepo}/collaborators/${username}/permission`,
|
|
230
235
|
{
|
|
231
236
|
headers: {
|
|
232
|
-
Authorization:
|
|
237
|
+
Authorization: `${this.tokenKeyword} ${token}`,
|
|
233
238
|
},
|
|
234
239
|
},
|
|
235
240
|
)
|
|
@@ -246,7 +251,7 @@ export default class GitHub implements Implementation {
|
|
|
246
251
|
const repo = await fetch(`${this.apiRoot}/repos/${currentUser.login}/${repoName}`, {
|
|
247
252
|
method: 'GET',
|
|
248
253
|
headers: {
|
|
249
|
-
Authorization:
|
|
254
|
+
Authorization: `${this.tokenKeyword} ${token}`,
|
|
250
255
|
},
|
|
251
256
|
}).then(res => res.json());
|
|
252
257
|
|
|
@@ -283,19 +288,34 @@ export default class GitHub implements Implementation {
|
|
|
283
288
|
return Promise.resolve();
|
|
284
289
|
}
|
|
285
290
|
|
|
286
|
-
|
|
291
|
+
// If a fork exists merge it with upstream
|
|
292
|
+
// otherwise create a new fork.
|
|
293
|
+
const currentUser = await this.currentUser({ token });
|
|
294
|
+
const repoName = this.originRepo.split('/')[1];
|
|
295
|
+
this.repo = `${currentUser.login}/${repoName}`;
|
|
296
|
+
this.useOpenAuthoring = true;
|
|
297
|
+
|
|
298
|
+
if (await this.forkExists({ token })) {
|
|
299
|
+
return fetch(`${this.apiRoot}/repos/${this.repo}/merge-upstream`, {
|
|
300
|
+
method: 'POST',
|
|
301
|
+
headers: {
|
|
302
|
+
Authorization: `${this.tokenKeyword} ${token}`,
|
|
303
|
+
},
|
|
304
|
+
body: JSON.stringify({
|
|
305
|
+
branch: this.branch,
|
|
306
|
+
}),
|
|
307
|
+
});
|
|
308
|
+
} else {
|
|
287
309
|
await getPermissionToFork();
|
|
288
|
-
}
|
|
289
310
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
return this.pollUntilForkExists({ repo: fork.full_name, token });
|
|
311
|
+
const fork = await fetch(`${this.apiRoot}/repos/${this.originRepo}/forks`, {
|
|
312
|
+
method: 'POST',
|
|
313
|
+
headers: {
|
|
314
|
+
Authorization: `${this.tokenKeyword} ${token}`,
|
|
315
|
+
},
|
|
316
|
+
}).then(res => res.json());
|
|
317
|
+
return this.pollUntilForkExists({ repo: fork.full_name, token });
|
|
318
|
+
}
|
|
299
319
|
}
|
|
300
320
|
|
|
301
321
|
async authenticate(state: Credentials) {
|
|
@@ -303,6 +323,7 @@ export default class GitHub implements Implementation {
|
|
|
303
323
|
const apiCtor = this.useGraphql ? GraphQLAPI : API;
|
|
304
324
|
this.api = new apiCtor({
|
|
305
325
|
token: this.token,
|
|
326
|
+
tokenKeyword: this.tokenKeyword,
|
|
306
327
|
branch: this.branch,
|
|
307
328
|
repo: this.repo,
|
|
308
329
|
originRepo: this.originRepo,
|
|
@@ -311,6 +332,8 @@ export default class GitHub implements Implementation {
|
|
|
311
332
|
cmsLabelPrefix: this.cmsLabelPrefix,
|
|
312
333
|
useOpenAuthoring: this.useOpenAuthoring,
|
|
313
334
|
initialWorkflowStatus: this.options.initialWorkflowStatus,
|
|
335
|
+
baseUrl: this.baseUrl,
|
|
336
|
+
getUser: this.currentUser,
|
|
314
337
|
});
|
|
315
338
|
const user = await this.api!.user();
|
|
316
339
|
const isCollab = await this.api!.hasWriteAccess().catch(error => {
|
|
@@ -327,7 +350,7 @@ export default class GitHub implements Implementation {
|
|
|
327
350
|
});
|
|
328
351
|
|
|
329
352
|
// Unauthorized user
|
|
330
|
-
if (!isCollab) {
|
|
353
|
+
if (!isCollab && !this.bypassWriteAccessCheckForAppTokens) {
|
|
331
354
|
throw new Error('Your GitHub user account does not have access to this repo.');
|
|
332
355
|
}
|
|
333
356
|
|