n8n-nodes-github-copilot 3.31.1 → 3.31.3
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IWebhookFunctions, IWebhookResponseData, INodeType, INodeTypeDescription } from "n8n-workflow";
|
|
2
2
|
export declare class GitHubCopilotAuthHelper implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
|
-
|
|
4
|
+
webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
|
|
5
5
|
}
|
|
@@ -7,38 +7,59 @@ class GitHubCopilotAuthHelper {
|
|
|
7
7
|
displayName: "GitHub Copilot Auth Helper",
|
|
8
8
|
name: "githubCopilotAuthHelper",
|
|
9
9
|
icon: "file:../../shared/icons/copilot.svg",
|
|
10
|
-
group: ["
|
|
10
|
+
group: ["trigger"],
|
|
11
11
|
version: 1,
|
|
12
|
-
description: "Interactive OAuth Device Flow
|
|
12
|
+
description: "Interactive OAuth Device Flow - serves HTML page with proxy to avoid CORS",
|
|
13
13
|
defaults: {
|
|
14
|
-
name: "GitHub Copilot Auth
|
|
14
|
+
name: "GitHub Copilot Auth",
|
|
15
15
|
},
|
|
16
|
-
inputs: [
|
|
17
|
-
outputs: [
|
|
16
|
+
inputs: [],
|
|
17
|
+
outputs: [],
|
|
18
|
+
webhooks: [
|
|
19
|
+
{
|
|
20
|
+
name: "default",
|
|
21
|
+
httpMethod: "GET",
|
|
22
|
+
responseMode: "onReceived",
|
|
23
|
+
path: "github-auth",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "default",
|
|
27
|
+
httpMethod: "POST",
|
|
28
|
+
responseMode: "onReceived",
|
|
29
|
+
path: "github-auth",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
18
32
|
properties: [
|
|
19
33
|
{
|
|
20
|
-
displayName: "
|
|
34
|
+
displayName: "🎯 Como Usar",
|
|
21
35
|
name: "instructions",
|
|
22
36
|
type: "notice",
|
|
23
37
|
default: "",
|
|
24
38
|
description: `
|
|
25
|
-
<div style="background: #
|
|
26
|
-
<h3 style="margin-top: 0;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<p><strong>
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
<div style="background: #e8f5e8; padding: 20px; border-left: 4px solid #4CAF50; border-radius: 4px;">
|
|
40
|
+
<h3 style="margin-top: 0; color: #2E7D32;">✨ Autenticação Visual - Sem Terminal!</h3>
|
|
41
|
+
|
|
42
|
+
<p><strong>1. Ative este workflow</strong></p>
|
|
43
|
+
<p>Clique em "Active" no canto superior direito</p>
|
|
44
|
+
|
|
45
|
+
<p><strong>2. Copie a URL do Webhook</strong></p>
|
|
46
|
+
<p>Clique em "Copy URL" abaixo e envie para o usuário</p>
|
|
47
|
+
|
|
48
|
+
<p><strong>3. Usuário acessa a URL no navegador</strong></p>
|
|
49
|
+
<p>Uma página bonita vai abrir com instruções claras</p>
|
|
50
|
+
|
|
51
|
+
<p><strong>4. Processo automático!</strong></p>
|
|
52
|
+
<ul style="margin: 10px 0; padding-left: 20px;">
|
|
53
|
+
<li>✅ Página solicita código do GitHub</li>
|
|
54
|
+
<li>✅ Mostra código grande para copiar</li>
|
|
38
55
|
<li>✅ Abre GitHub automaticamente</li>
|
|
39
|
-
<li>✅
|
|
56
|
+
<li>✅ Aguarda autorização (polling automático)</li>
|
|
40
57
|
<li>✅ Exibe token pronto para copiar</li>
|
|
41
58
|
</ul>
|
|
59
|
+
|
|
60
|
+
<p style="background: #fff3e0; padding: 10px; border-radius: 4px; margin-top: 15px;">
|
|
61
|
+
<strong>💡 Sem CORS!</strong> O n8n faz as chamadas para o GitHub, não o navegador!
|
|
62
|
+
</p>
|
|
42
63
|
</div>
|
|
43
64
|
`,
|
|
44
65
|
},
|
|
@@ -58,90 +79,86 @@ class GitHubCopilotAuthHelper {
|
|
|
58
79
|
required: true,
|
|
59
80
|
description: "OAuth scopes required for GitHub Copilot",
|
|
60
81
|
},
|
|
61
|
-
{
|
|
62
|
-
displayName: "Output Format",
|
|
63
|
-
name: "outputFormat",
|
|
64
|
-
type: "options",
|
|
65
|
-
options: [
|
|
66
|
-
{
|
|
67
|
-
name: "📄 Binary File (Download Ready)",
|
|
68
|
-
value: "binary",
|
|
69
|
-
description: "HTML as binary data ready to download as .html file",
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
name: "📋 HTML Text + Instructions",
|
|
73
|
-
value: "htmlWithInstructions",
|
|
74
|
-
description: "HTML text with usage instructions (copy & paste)",
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
name: "📝 HTML Text Only",
|
|
78
|
-
value: "html",
|
|
79
|
-
description: "Just the HTML code as text",
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
default: "binary",
|
|
83
|
-
description: "How to output the authentication page",
|
|
84
|
-
},
|
|
85
82
|
],
|
|
86
83
|
};
|
|
87
84
|
}
|
|
88
|
-
async
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
message: "✅ Authentication page generated successfully!",
|
|
103
|
-
instructions: "Download the binary file below and open it in your browser",
|
|
104
|
-
fileName: "github-copilot-auth.html",
|
|
105
|
-
fileSize: `${(buffer.length / 1024).toFixed(2)} KB`,
|
|
106
|
-
},
|
|
107
|
-
binary: {
|
|
108
|
-
authPage: {
|
|
109
|
-
data: buffer.toString("base64"),
|
|
110
|
-
mimeType: "text/html",
|
|
111
|
-
fileName: "github-copilot-auth.html",
|
|
85
|
+
async webhook() {
|
|
86
|
+
const req = this.getRequestObject();
|
|
87
|
+
const clientId = this.getNodeParameter("clientId");
|
|
88
|
+
const scopes = this.getNodeParameter("scopes");
|
|
89
|
+
if (req.method === "POST") {
|
|
90
|
+
const body = this.getBodyData();
|
|
91
|
+
const action = body.action;
|
|
92
|
+
try {
|
|
93
|
+
if (action === "device_code") {
|
|
94
|
+
const response = await fetch("https://github.com/login/device/code", {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
"Accept": "application/json",
|
|
98
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
112
99
|
},
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
"2. Save as 'github-copilot-auth.html'",
|
|
127
|
-
"3. Open the file in your browser",
|
|
128
|
-
"4. Follow the on-screen instructions",
|
|
129
|
-
"5. Copy the token when it appears",
|
|
130
|
-
"6. Use the token in your GitHub Copilot API credential in n8n",
|
|
131
|
-
].join("\n");
|
|
100
|
+
body: new URLSearchParams({
|
|
101
|
+
client_id: clientId,
|
|
102
|
+
scope: scopes,
|
|
103
|
+
}),
|
|
104
|
+
});
|
|
105
|
+
const data = await response.json();
|
|
106
|
+
return {
|
|
107
|
+
webhookResponse: {
|
|
108
|
+
status: 200,
|
|
109
|
+
headers: { "Content-Type": "application/json" },
|
|
110
|
+
body: JSON.stringify(data),
|
|
111
|
+
},
|
|
112
|
+
};
|
|
132
113
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
114
|
+
if (action === "poll_token") {
|
|
115
|
+
const deviceCode = body.device_code;
|
|
116
|
+
const response = await fetch("https://github.com/login/oauth/access_token", {
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers: {
|
|
119
|
+
"Accept": "application/json",
|
|
120
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
121
|
+
},
|
|
122
|
+
body: new URLSearchParams({
|
|
123
|
+
client_id: clientId,
|
|
124
|
+
device_code: deviceCode,
|
|
125
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
const data = await response.json();
|
|
129
|
+
return {
|
|
130
|
+
webhookResponse: {
|
|
131
|
+
status: 200,
|
|
132
|
+
headers: { "Content-Type": "application/json" },
|
|
133
|
+
body: JSON.stringify(data),
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
throw new Error(`Unknown action: ${action}`);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
return {
|
|
141
|
+
webhookResponse: {
|
|
142
|
+
status: 500,
|
|
143
|
+
headers: { "Content-Type": "application/json" },
|
|
144
|
+
body: JSON.stringify({ error: error.message }),
|
|
145
|
+
},
|
|
136
146
|
};
|
|
137
147
|
}
|
|
138
|
-
returnData.push(output);
|
|
139
148
|
}
|
|
140
|
-
|
|
149
|
+
const webhookUrl = this.getNodeWebhookUrl("default");
|
|
150
|
+
const html = generateAuthPage(webhookUrl);
|
|
151
|
+
return {
|
|
152
|
+
webhookResponse: {
|
|
153
|
+
status: 200,
|
|
154
|
+
headers: { "Content-Type": "text/html; charset=utf-8" },
|
|
155
|
+
body: html,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
141
158
|
}
|
|
142
159
|
}
|
|
143
160
|
exports.GitHubCopilotAuthHelper = GitHubCopilotAuthHelper;
|
|
144
|
-
function generateAuthPage(
|
|
161
|
+
function generateAuthPage(proxyUrl) {
|
|
145
162
|
return `<!DOCTYPE html>
|
|
146
163
|
<html lang="pt-BR">
|
|
147
164
|
<head>
|
|
@@ -399,7 +416,7 @@ function generateAuthPage(clientId, scopes) {
|
|
|
399
416
|
<span>Copiar Token</span>
|
|
400
417
|
</button>
|
|
401
418
|
<p class="info-text" style="color: #155724; margin-top: 15px;">
|
|
402
|
-
✨ Cole este token na credencial "GitHub Copilot
|
|
419
|
+
✨ Cole este token na credencial "GitHub Copilot API" no n8n
|
|
403
420
|
</p>
|
|
404
421
|
</div>
|
|
405
422
|
|
|
@@ -410,10 +427,7 @@ function generateAuthPage(clientId, scopes) {
|
|
|
410
427
|
</div>
|
|
411
428
|
|
|
412
429
|
<script>
|
|
413
|
-
const
|
|
414
|
-
const SCOPES = "${scopes}";
|
|
415
|
-
const DEVICE_CODE_URL = "https://github.com/login/device/code";
|
|
416
|
-
const ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
|
|
430
|
+
const PROXY_URL = "${proxyUrl}";
|
|
417
431
|
|
|
418
432
|
let deviceCode = "";
|
|
419
433
|
let userCode = "";
|
|
@@ -425,16 +439,14 @@ function generateAuthPage(clientId, scopes) {
|
|
|
425
439
|
document.getElementById("step1").querySelector(".btn").disabled = true;
|
|
426
440
|
document.getElementById("step1").querySelector(".btn").innerHTML = '<span>⏳</span><span>Solicitando...</span>';
|
|
427
441
|
|
|
428
|
-
// Request device code
|
|
429
|
-
const response = await fetch(
|
|
442
|
+
// Request device code via n8n proxy
|
|
443
|
+
const response = await fetch(PROXY_URL, {
|
|
430
444
|
method: "POST",
|
|
431
445
|
headers: {
|
|
432
|
-
"
|
|
433
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
446
|
+
"Content-Type": "application/json",
|
|
434
447
|
},
|
|
435
|
-
body:
|
|
436
|
-
|
|
437
|
-
scope: SCOPES
|
|
448
|
+
body: JSON.stringify({
|
|
449
|
+
action: "device_code"
|
|
438
450
|
})
|
|
439
451
|
});
|
|
440
452
|
|
|
@@ -490,16 +502,14 @@ function generateAuthPage(clientId, scopes) {
|
|
|
490
502
|
document.getElementById("statusText").textContent = \`Verificando... (tentativa \${attempt}/\${maxAttempts})\`;
|
|
491
503
|
|
|
492
504
|
try {
|
|
493
|
-
const response = await fetch(
|
|
505
|
+
const response = await fetch(PROXY_URL, {
|
|
494
506
|
method: "POST",
|
|
495
507
|
headers: {
|
|
496
|
-
"
|
|
497
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
508
|
+
"Content-Type": "application/json",
|
|
498
509
|
},
|
|
499
|
-
body:
|
|
500
|
-
|
|
501
|
-
device_code: deviceCode
|
|
502
|
-
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
510
|
+
body: JSON.stringify({
|
|
511
|
+
action: "poll_token",
|
|
512
|
+
device_code: deviceCode
|
|
503
513
|
})
|
|
504
514
|
});
|
|
505
515
|
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-github-copilot",
|
|
3
|
-
"version": "3.31.
|
|
3
|
+
"version": "3.31.3",
|
|
4
4
|
"description": "n8n community node for GitHub Copilot with CLI integration, Chat API access, and AI Chat Model for workflows - access GPT-5, Claude, Gemini and more using your Copilot subscription",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/sufficit/n8n-nodes-github-copilot",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-github-copilot",
|
|
3
|
-
"version": "3.31.
|
|
3
|
+
"version": "3.31.3",
|
|
4
4
|
"description": "n8n community node for GitHub Copilot with CLI integration, Chat API access, and AI Chat Model for workflows - access GPT-5, Claude, Gemini and more using your Copilot subscription",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/sufficit/n8n-nodes-github-copilot",
|