n8n-nodes-github-copilot 3.31.0 → 3.31.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.
@@ -1,5 +1,5 @@
1
- import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from "n8n-workflow";
1
+ import { IWebhookFunctions, IWebhookResponseData, INodeType, INodeTypeDescription } from "n8n-workflow";
2
2
  export declare class GitHubCopilotAuthHelper implements INodeType {
3
3
  description: INodeTypeDescription;
4
- execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
4
+ webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
5
5
  }
@@ -7,38 +7,53 @@ class GitHubCopilotAuthHelper {
7
7
  displayName: "GitHub Copilot Auth Helper",
8
8
  name: "githubCopilotAuthHelper",
9
9
  icon: "file:../../shared/icons/copilot.svg",
10
- group: ["transform"],
10
+ group: ["trigger"],
11
11
  version: 1,
12
- description: "Interactive OAuth Device Flow authentication helper - generates HTML page for easy token generation",
12
+ description: "Interactive OAuth Device Flow - serves HTML page with proxy to avoid CORS",
13
13
  defaults: {
14
- name: "GitHub Copilot Auth Helper",
14
+ name: "GitHub Copilot Auth",
15
15
  },
16
- inputs: ["main"],
17
- outputs: ["main"],
16
+ inputs: [],
17
+ outputs: [],
18
+ webhooks: [
19
+ {
20
+ name: "default",
21
+ httpMethod: "=",
22
+ responseMode: "onReceived",
23
+ path: "github-auth",
24
+ },
25
+ ],
18
26
  properties: [
19
27
  {
20
- displayName: "📋 Como Usar",
28
+ displayName: "🎯 Como Usar",
21
29
  name: "instructions",
22
30
  type: "notice",
23
31
  default: "",
24
32
  description: `
25
- <div style="background: #e3f2fd; padding: 15px; border-left: 4px solid #2196F3; border-radius: 4px;">
26
- <h3 style="margin-top: 0;">🎯 Este node gera uma página HTML interativa!</h3>
27
- <ol>
28
- <li>Execute este node</li>
29
- <li>Copie o HTML do output</li>
30
- <li>Salve como arquivo .html e abra no navegador</li>
31
- <li>OU use um node "Send Email" para enviar para você</li>
32
- <li>Siga as instruções na página para obter seu token</li>
33
- </ol>
34
- <p><strong>A página faz tudo automaticamente:</strong></p>
35
- <ul>
36
- <li>✅ Solicita device code do GitHub</li>
37
- <li>✅ Mostra código para copiar</li>
33
+ <div style="background: #e8f5e8; padding: 20px; border-left: 4px solid #4CAF50; border-radius: 4px;">
34
+ <h3 style="margin-top: 0; color: #2E7D32;">✨ Autenticação Visual - Sem Terminal!</h3>
35
+
36
+ <p><strong>1. Ative este workflow</strong></p>
37
+ <p>Clique em "Active" no canto superior direito</p>
38
+
39
+ <p><strong>2. Copie a URL do Webhook</strong></p>
40
+ <p>Clique em "Copy URL" abaixo e envie para o usuário</p>
41
+
42
+ <p><strong>3. Usuário acessa a URL no navegador</strong></p>
43
+ <p>Uma página bonita vai abrir com instruções claras</p>
44
+
45
+ <p><strong>4. Processo automático!</strong></p>
46
+ <ul style="margin: 10px 0; padding-left: 20px;">
47
+ <li>✅ Página solicita código do GitHub</li>
48
+ <li>✅ Mostra código grande para copiar</li>
38
49
  <li>✅ Abre GitHub automaticamente</li>
39
- <li>✅ Faz polling até você autorizar</li>
50
+ <li>✅ Aguarda autorização (polling automático)</li>
40
51
  <li>✅ Exibe token pronto para copiar</li>
41
52
  </ul>
53
+
54
+ <p style="background: #fff3e0; padding: 10px; border-radius: 4px; margin-top: 15px;">
55
+ <strong>💡 Sem CORS!</strong> O n8n faz as chamadas para o GitHub, não o navegador!
56
+ </p>
42
57
  </div>
43
58
  `,
44
59
  },
@@ -58,60 +73,86 @@ class GitHubCopilotAuthHelper {
58
73
  required: true,
59
74
  description: "OAuth scopes required for GitHub Copilot",
60
75
  },
61
- {
62
- displayName: "Output Format",
63
- name: "outputFormat",
64
- type: "options",
65
- options: [
66
- {
67
- name: "Complete HTML File",
68
- value: "html",
69
- description: "Full HTML page ready to save and open",
70
- },
71
- {
72
- name: "HTML + Instructions",
73
- value: "htmlWithInstructions",
74
- description: "HTML with usage instructions",
75
- },
76
- ],
77
- default: "htmlWithInstructions",
78
- },
79
76
  ],
80
77
  };
81
78
  }
82
- async execute() {
83
- const items = this.getInputData();
84
- const returnData = [];
85
- for (let i = 0; i < items.length; i++) {
86
- const clientId = this.getNodeParameter("clientId", i);
87
- const scopes = this.getNodeParameter("scopes", i);
88
- const outputFormat = this.getNodeParameter("outputFormat", i);
89
- const html = generateAuthPage(clientId, scopes);
90
- const output = {
91
- html,
92
- clientId,
93
- scopes,
94
- };
95
- if (outputFormat === "htmlWithInstructions") {
96
- output.instructions = [
97
- "1. Copy the HTML content below",
98
- "2. Save as 'github-copilot-auth.html'",
99
- "3. Open the file in your browser",
100
- "4. Follow the on-screen instructions",
101
- "5. Copy the token when it appears",
102
- "6. Use the token in your GitHub Copilot OAuth2 credential in n8n",
103
- ].join("\n");
79
+ async webhook() {
80
+ const req = this.getRequestObject();
81
+ const clientId = this.getNodeParameter("clientId");
82
+ const scopes = this.getNodeParameter("scopes");
83
+ if (req.method === "POST") {
84
+ const body = this.getBodyData();
85
+ const action = body.action;
86
+ try {
87
+ if (action === "device_code") {
88
+ const response = await fetch("https://github.com/login/device/code", {
89
+ method: "POST",
90
+ headers: {
91
+ "Accept": "application/json",
92
+ "Content-Type": "application/x-www-form-urlencoded",
93
+ },
94
+ body: new URLSearchParams({
95
+ client_id: clientId,
96
+ scope: scopes,
97
+ }),
98
+ });
99
+ const data = await response.json();
100
+ return {
101
+ webhookResponse: {
102
+ status: 200,
103
+ headers: { "Content-Type": "application/json" },
104
+ body: JSON.stringify(data),
105
+ },
106
+ };
107
+ }
108
+ if (action === "poll_token") {
109
+ const deviceCode = body.device_code;
110
+ const response = await fetch("https://github.com/login/oauth/access_token", {
111
+ method: "POST",
112
+ headers: {
113
+ "Accept": "application/json",
114
+ "Content-Type": "application/x-www-form-urlencoded",
115
+ },
116
+ body: new URLSearchParams({
117
+ client_id: clientId,
118
+ device_code: deviceCode,
119
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
120
+ }),
121
+ });
122
+ const data = await response.json();
123
+ return {
124
+ webhookResponse: {
125
+ status: 200,
126
+ headers: { "Content-Type": "application/json" },
127
+ body: JSON.stringify(data),
128
+ },
129
+ };
130
+ }
131
+ throw new Error(`Unknown action: ${action}`);
132
+ }
133
+ catch (error) {
134
+ return {
135
+ webhookResponse: {
136
+ status: 500,
137
+ headers: { "Content-Type": "application/json" },
138
+ body: JSON.stringify({ error: error.message }),
139
+ },
140
+ };
104
141
  }
105
- returnData.push({
106
- json: output,
107
- pairedItem: i,
108
- });
109
142
  }
110
- return [returnData];
143
+ const webhookUrl = this.getNodeWebhookUrl("default");
144
+ const html = generateAuthPage(webhookUrl);
145
+ return {
146
+ webhookResponse: {
147
+ status: 200,
148
+ headers: { "Content-Type": "text/html; charset=utf-8" },
149
+ body: html,
150
+ },
151
+ };
111
152
  }
112
153
  }
113
154
  exports.GitHubCopilotAuthHelper = GitHubCopilotAuthHelper;
114
- function generateAuthPage(clientId, scopes) {
155
+ function generateAuthPage(proxyUrl) {
115
156
  return `<!DOCTYPE html>
116
157
  <html lang="pt-BR">
117
158
  <head>
@@ -369,7 +410,7 @@ function generateAuthPage(clientId, scopes) {
369
410
  <span>Copiar Token</span>
370
411
  </button>
371
412
  <p class="info-text" style="color: #155724; margin-top: 15px;">
372
- ✨ Cole este token na credencial "GitHub Copilot OAuth2 (with Helper)" no n8n
413
+ ✨ Cole este token na credencial "GitHub Copilot API" no n8n
373
414
  </p>
374
415
  </div>
375
416
 
@@ -380,10 +421,7 @@ function generateAuthPage(clientId, scopes) {
380
421
  </div>
381
422
 
382
423
  <script>
383
- const CLIENT_ID = "${clientId}";
384
- const SCOPES = "${scopes}";
385
- const DEVICE_CODE_URL = "https://github.com/login/device/code";
386
- const ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
424
+ const PROXY_URL = "${proxyUrl}";
387
425
 
388
426
  let deviceCode = "";
389
427
  let userCode = "";
@@ -395,16 +433,14 @@ function generateAuthPage(clientId, scopes) {
395
433
  document.getElementById("step1").querySelector(".btn").disabled = true;
396
434
  document.getElementById("step1").querySelector(".btn").innerHTML = '<span>⏳</span><span>Solicitando...</span>';
397
435
 
398
- // Request device code
399
- const response = await fetch(DEVICE_CODE_URL, {
436
+ // Request device code via n8n proxy
437
+ const response = await fetch(PROXY_URL, {
400
438
  method: "POST",
401
439
  headers: {
402
- "Accept": "application/json",
403
- "Content-Type": "application/x-www-form-urlencoded",
440
+ "Content-Type": "application/json",
404
441
  },
405
- body: new URLSearchParams({
406
- client_id: CLIENT_ID,
407
- scope: SCOPES
442
+ body: JSON.stringify({
443
+ action: "device_code"
408
444
  })
409
445
  });
410
446
 
@@ -460,16 +496,14 @@ function generateAuthPage(clientId, scopes) {
460
496
  document.getElementById("statusText").textContent = \`Verificando... (tentativa \${attempt}/\${maxAttempts})\`;
461
497
 
462
498
  try {
463
- const response = await fetch(ACCESS_TOKEN_URL, {
499
+ const response = await fetch(PROXY_URL, {
464
500
  method: "POST",
465
501
  headers: {
466
- "Accept": "application/json",
467
- "Content-Type": "application/x-www-form-urlencoded",
502
+ "Content-Type": "application/json",
468
503
  },
469
- body: new URLSearchParams({
470
- client_id: CLIENT_ID,
471
- device_code: deviceCode,
472
- grant_type: "urn:ietf:params:oauth:grant-type:device_code"
504
+ body: JSON.stringify({
505
+ action: "poll_token",
506
+ device_code: deviceCode
473
507
  })
474
508
  });
475
509
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-github-copilot",
3
- "version": "3.31.0",
3
+ "version": "3.31.2",
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.0",
3
+ "version": "3.31.2",
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",