n8n-nodes-github-copilot 3.31.30 → 3.32.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/credentials/GitHubCopilotApi.credentials.d.ts +2 -2
- package/dist/credentials/GitHubCopilotApi.credentials.js +112 -10
- package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.js +13 -6
- package/dist/package.json +1 -1
- package/dist/shared/utils/GitHubCopilotApiUtils.js +39 -4
- package/dist/shared/utils/OAuthTokenManager.d.ts +19 -0
- package/dist/shared/utils/OAuthTokenManager.js +121 -0
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ICredentialType, INodeProperties, ICredentialTestRequest,
|
|
1
|
+
import { ICredentialType, INodeProperties, ICredentialTestRequest, IHttpRequestOptions, ICredentialDataDecryptedObject } from "n8n-workflow";
|
|
2
2
|
export declare class GitHubCopilotApi implements ICredentialType {
|
|
3
3
|
name: string;
|
|
4
4
|
displayName: string;
|
|
5
5
|
documentationUrl: string;
|
|
6
6
|
properties: INodeProperties[];
|
|
7
|
-
authenticate:
|
|
7
|
+
authenticate(credentials: ICredentialDataDecryptedObject, requestOptions: IHttpRequestOptions): Promise<IHttpRequestOptions>;
|
|
8
8
|
test: ICredentialTestRequest;
|
|
9
9
|
}
|
|
@@ -2,41 +2,97 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GitHubCopilotApi = void 0;
|
|
4
4
|
const GitHubCopilotEndpoints_1 = require("../shared/utils/GitHubCopilotEndpoints");
|
|
5
|
+
const OAuthTokenManager_1 = require("../shared/utils/OAuthTokenManager");
|
|
5
6
|
class GitHubCopilotApi {
|
|
6
7
|
constructor() {
|
|
7
8
|
this.name = "githubCopilotApi";
|
|
8
9
|
this.displayName = "GitHub Copilot API (GitHub CLI Token)";
|
|
9
10
|
this.documentationUrl = "https://docs.github.com/en/copilot/github-copilot-chat/copilot-chat-in-ides/using-github-copilot-chat-in-your-ide";
|
|
10
11
|
this.properties = [
|
|
12
|
+
{
|
|
13
|
+
displayName: "Authentication Method",
|
|
14
|
+
name: "authMethod",
|
|
15
|
+
type: "options",
|
|
16
|
+
options: [
|
|
17
|
+
{
|
|
18
|
+
name: "GitHub CLI Token (Auto OAuth) - RECOMMENDED",
|
|
19
|
+
value: "githubToken",
|
|
20
|
+
description: "Automatically generates and refreshes OAuth tokens every 20 minutes",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "Manual OAuth Token (Advanced)",
|
|
24
|
+
value: "oauthToken",
|
|
25
|
+
description: "Manually provide OAuth token (expires in 20 minutes)",
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
default: "githubToken",
|
|
29
|
+
description: "Choose how to authenticate with GitHub Copilot API",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
displayName: "ℹ️ Auto OAuth Token Generation",
|
|
33
|
+
name: "autoOAuthNotice",
|
|
34
|
+
type: "notice",
|
|
35
|
+
default: "Your GitHub CLI token will be used to automatically generate OAuth tokens. Tokens are cached and refreshed automatically before expiration (every ~20 minutes). No manual intervention needed!",
|
|
36
|
+
displayOptions: {
|
|
37
|
+
show: {
|
|
38
|
+
authMethod: ["githubToken"],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
11
42
|
{
|
|
12
43
|
displayName: "⚠️ IMPORTANT: GitHub CLI Token Required",
|
|
13
44
|
name: "warningNotice",
|
|
14
45
|
type: "notice",
|
|
15
46
|
default: "",
|
|
47
|
+
displayOptions: {
|
|
48
|
+
show: {
|
|
49
|
+
authMethod: ["githubToken"],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
16
52
|
},
|
|
17
53
|
{
|
|
18
54
|
displayName: "🚀 Don't have GitHub CLI installed?",
|
|
19
55
|
name: "helperNotice1",
|
|
20
56
|
type: "notice",
|
|
21
57
|
default: "Use the visual 'GitHub Copilot Auth Helper' node to generate your token without touching the terminal!",
|
|
58
|
+
displayOptions: {
|
|
59
|
+
show: {
|
|
60
|
+
authMethod: ["githubToken"],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
22
63
|
},
|
|
23
64
|
{
|
|
24
65
|
displayName: "📝 Step 1: Create Helper Workflow",
|
|
25
66
|
name: "helperNotice2",
|
|
26
67
|
type: "notice",
|
|
27
68
|
default: "Add a new workflow and insert the 'GitHub Copilot Auth Helper' trigger node.",
|
|
69
|
+
displayOptions: {
|
|
70
|
+
show: {
|
|
71
|
+
authMethod: ["githubToken"],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
28
74
|
},
|
|
29
75
|
{
|
|
30
76
|
displayName: "▶️ Step 2: Activate & Access",
|
|
31
77
|
name: "helperNotice3",
|
|
32
78
|
type: "notice",
|
|
33
79
|
default: "Activate the workflow, then click 'Test workflow' to open the visual token generator in your browser.",
|
|
80
|
+
displayOptions: {
|
|
81
|
+
show: {
|
|
82
|
+
authMethod: ["githubToken"],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
34
85
|
},
|
|
35
86
|
{
|
|
36
87
|
displayName: "📋 Step 3: Copy Token",
|
|
37
88
|
name: "helperNotice4",
|
|
38
89
|
type: "notice",
|
|
39
90
|
default: "Follow the on-screen instructions to authenticate with GitHub and copy the generated 'gho_' token back here.",
|
|
91
|
+
displayOptions: {
|
|
92
|
+
show: {
|
|
93
|
+
authMethod: ["githubToken"],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
40
96
|
},
|
|
41
97
|
{
|
|
42
98
|
displayName: "GitHub CLI Token",
|
|
@@ -47,20 +103,43 @@ class GitHubCopilotApi {
|
|
|
47
103
|
},
|
|
48
104
|
default: "",
|
|
49
105
|
required: true,
|
|
50
|
-
description: "Token generated by GitHub CLI (starts with 'gho_').
|
|
106
|
+
description: "Token generated by GitHub CLI (starts with 'gho_'). OAuth tokens will be auto-generated and refreshed from this token.",
|
|
51
107
|
placeholder: "gho_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
108
|
+
displayOptions: {
|
|
109
|
+
show: {
|
|
110
|
+
authMethod: ["githubToken"],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
52
113
|
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
114
|
+
{
|
|
115
|
+
displayName: "⚠️ Manual OAuth Token (Advanced)",
|
|
116
|
+
name: "manualOAuthNotice",
|
|
117
|
+
type: "notice",
|
|
118
|
+
default: "OAuth tokens expire after ~20 minutes. You will need to manually regenerate and update this token frequently. Consider using GitHub CLI Token mode instead for automatic token management.",
|
|
119
|
+
displayOptions: {
|
|
120
|
+
show: {
|
|
121
|
+
authMethod: ["oauthToken"],
|
|
122
|
+
},
|
|
61
123
|
},
|
|
62
124
|
},
|
|
63
|
-
|
|
125
|
+
{
|
|
126
|
+
displayName: "OAuth Token",
|
|
127
|
+
name: "oauthToken",
|
|
128
|
+
type: "string",
|
|
129
|
+
typeOptions: {
|
|
130
|
+
password: true,
|
|
131
|
+
},
|
|
132
|
+
default: "",
|
|
133
|
+
required: true,
|
|
134
|
+
description: "Manual OAuth token (starts with 'tid='). Expires in ~20 minutes.",
|
|
135
|
+
placeholder: "tid=xxxxx;exp=xxxxx;sku=xxxxx;...",
|
|
136
|
+
displayOptions: {
|
|
137
|
+
show: {
|
|
138
|
+
authMethod: ["oauthToken"],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
];
|
|
64
143
|
this.test = {
|
|
65
144
|
request: {
|
|
66
145
|
baseURL: GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.BASE_URL,
|
|
@@ -69,5 +148,28 @@ class GitHubCopilotApi {
|
|
|
69
148
|
},
|
|
70
149
|
};
|
|
71
150
|
}
|
|
151
|
+
async authenticate(credentials, requestOptions) {
|
|
152
|
+
const authMethod = credentials.authMethod;
|
|
153
|
+
let authToken;
|
|
154
|
+
if (authMethod === "githubToken") {
|
|
155
|
+
const githubToken = credentials.token;
|
|
156
|
+
try {
|
|
157
|
+
authToken = await OAuthTokenManager_1.OAuthTokenManager.getValidOAuthToken(githubToken);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
throw new Error(`Failed to generate OAuth token: ${error instanceof Error ? error.message : String(error)}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
authToken = credentials.oauthToken;
|
|
165
|
+
}
|
|
166
|
+
if (!requestOptions.headers) {
|
|
167
|
+
requestOptions.headers = {};
|
|
168
|
+
}
|
|
169
|
+
requestOptions.headers.Authorization = `Bearer ${authToken}`;
|
|
170
|
+
requestOptions.headers.Accept = "application/json";
|
|
171
|
+
requestOptions.headers["Content-Type"] = "application/json";
|
|
172
|
+
return requestOptions;
|
|
173
|
+
}
|
|
72
174
|
}
|
|
73
175
|
exports.GitHubCopilotApi = GitHubCopilotApi;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GitHubCopilotOpenAI = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
4
5
|
const nodeProperties_1 = require("./nodeProperties");
|
|
5
6
|
const utils_1 = require("../GitHubCopilotChatAPI/utils");
|
|
6
7
|
const GitHubCopilotEndpoints_1 = require("../../shared/utils/GitHubCopilotEndpoints");
|
|
@@ -282,7 +283,18 @@ class GitHubCopilotOpenAI {
|
|
|
282
283
|
}
|
|
283
284
|
else {
|
|
284
285
|
const lowerMessage = cleanMessage.toLowerCase();
|
|
285
|
-
|
|
286
|
+
const is400Error = lowerMessage.includes("400") || lowerMessage.includes("bad request");
|
|
287
|
+
if (is400Error) {
|
|
288
|
+
errorType = "invalid_request_error";
|
|
289
|
+
errorCode = "invalid_request";
|
|
290
|
+
finalMessage = cleanMessage;
|
|
291
|
+
console.log('🚫 400 Bad Request detected - throwing non-retryable error');
|
|
292
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Bad Request (400): ${finalMessage}`, {
|
|
293
|
+
itemIndex: i,
|
|
294
|
+
description: 'The request was malformed or contains invalid parameters. Retrying will not help.',
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
else if (lowerMessage.includes("403") || lowerMessage.includes("forbidden")) {
|
|
286
298
|
errorType = "invalid_request_error";
|
|
287
299
|
errorCode = "insufficient_quota";
|
|
288
300
|
if (lowerMessage.includes("access") && lowerMessage.includes("forbidden")) {
|
|
@@ -303,11 +315,6 @@ class GitHubCopilotOpenAI {
|
|
|
303
315
|
errorCode = "invalid_api_key";
|
|
304
316
|
finalMessage = "Incorrect API key provided. You can find your API key at https://platform.openai.com/account/api-keys.";
|
|
305
317
|
}
|
|
306
|
-
else if (lowerMessage.includes("400") || lowerMessage.includes("bad request")) {
|
|
307
|
-
errorType = "invalid_request_error";
|
|
308
|
-
errorCode = "invalid_request";
|
|
309
|
-
finalMessage = cleanMessage;
|
|
310
|
-
}
|
|
311
318
|
else if (lowerMessage.includes("429") || lowerMessage.includes("rate limit")) {
|
|
312
319
|
errorType = "rate_limit_error";
|
|
313
320
|
errorCode = "rate_limit_exceeded";
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-github-copilot",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.32.0",
|
|
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",
|
|
@@ -10,6 +10,7 @@ exports.estimateTokens = estimateTokens;
|
|
|
10
10
|
exports.validateTokenLimit = validateTokenLimit;
|
|
11
11
|
exports.truncateToTokenLimit = truncateToTokenLimit;
|
|
12
12
|
const GitHubCopilotEndpoints_1 = require("./GitHubCopilotEndpoints");
|
|
13
|
+
const OAuthTokenManager_1 = require("./OAuthTokenManager");
|
|
13
14
|
async function makeGitHubCopilotRequest(context, endpoint, body, hasMedia = false, retryConfig) {
|
|
14
15
|
var _a, _b, _c, _d;
|
|
15
16
|
const MAX_RETRIES = (_a = retryConfig === null || retryConfig === void 0 ? void 0 : retryConfig.maxRetries) !== null && _a !== void 0 ? _a : 3;
|
|
@@ -24,10 +25,44 @@ async function makeGitHubCopilotRequest(context, endpoint, body, hasMedia = fals
|
|
|
24
25
|
}
|
|
25
26
|
const credentials = await context.getCredentials(credentialType);
|
|
26
27
|
console.log(`🔍 ${credentialType} Credentials Debug:`, Object.keys(credentials));
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
credentials.token
|
|
28
|
+
const authMethod = credentials.authMethod;
|
|
29
|
+
let token;
|
|
30
|
+
if (authMethod === "githubToken" || credentials.token) {
|
|
31
|
+
const githubToken = credentials.token;
|
|
32
|
+
if (!githubToken) {
|
|
33
|
+
throw new Error("GitHub token (gho_*) not found in credentials");
|
|
34
|
+
}
|
|
35
|
+
if (!githubToken.startsWith("gho_")) {
|
|
36
|
+
throw new Error("Invalid GitHub token format. Must start with gho_");
|
|
37
|
+
}
|
|
38
|
+
console.log(`🔄 Using GitHub token to generate OAuth token...`);
|
|
39
|
+
try {
|
|
40
|
+
token = await OAuthTokenManager_1.OAuthTokenManager.getValidOAuthToken(githubToken);
|
|
41
|
+
console.log(`✅ OAuth token ready (auto-generated from GitHub token)`);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new Error(`Failed to generate OAuth token: ${error instanceof Error ? error.message : String(error)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (authMethod === "oauthToken" || credentials.oauthToken) {
|
|
48
|
+
token = credentials.oauthToken;
|
|
49
|
+
if (!token) {
|
|
50
|
+
throw new Error("OAuth token not found in credentials");
|
|
51
|
+
}
|
|
52
|
+
console.log(`✅ Using manual OAuth token`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
token = (credentials.accessToken ||
|
|
56
|
+
credentials.access_token ||
|
|
57
|
+
((_d = credentials.oauthTokenData) === null || _d === void 0 ? void 0 : _d.access_token) ||
|
|
58
|
+
credentials.token);
|
|
59
|
+
if (!token) {
|
|
60
|
+
console.error(`❌ Available ${credentialType} credential properties:`, Object.keys(credentials));
|
|
61
|
+
throw new Error(`No access token found in ${credentialType} credentials. Available properties: ` +
|
|
62
|
+
Object.keys(credentials).join(", "));
|
|
63
|
+
}
|
|
64
|
+
console.log(`⚠️ Using legacy token format (consider updating credential configuration)`);
|
|
65
|
+
}
|
|
31
66
|
if (!token) {
|
|
32
67
|
console.error(`❌ Available ${credentialType} credential properties:`, Object.keys(credentials));
|
|
33
68
|
console.error(`❌ Full ${credentialType} credential object:`, JSON.stringify(credentials, null, 2));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface OAuthTokenCache {
|
|
2
|
+
token: string;
|
|
3
|
+
expiresAt: number;
|
|
4
|
+
generatedAt: number;
|
|
5
|
+
refreshIn: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class OAuthTokenManager {
|
|
8
|
+
private static tokenCache;
|
|
9
|
+
private static machineIdCache;
|
|
10
|
+
static getValidOAuthToken(githubToken: string): Promise<string>;
|
|
11
|
+
private static generateOAuthToken;
|
|
12
|
+
private static getMachineId;
|
|
13
|
+
private static generateSessionId;
|
|
14
|
+
private static getCacheKey;
|
|
15
|
+
static clearCache(githubToken: string): void;
|
|
16
|
+
static getCacheInfo(githubToken: string): OAuthTokenCache | null;
|
|
17
|
+
static needsRefresh(githubToken: string, bufferMinutes?: number): boolean;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OAuthTokenManager = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const https_1 = __importDefault(require("https"));
|
|
9
|
+
class OAuthTokenManager {
|
|
10
|
+
static async getValidOAuthToken(githubToken) {
|
|
11
|
+
if (!githubToken || !githubToken.startsWith('gho_')) {
|
|
12
|
+
throw new Error('Invalid GitHub token. Must start with gho_');
|
|
13
|
+
}
|
|
14
|
+
const cacheKey = this.getCacheKey(githubToken);
|
|
15
|
+
const cached = this.tokenCache.get(cacheKey);
|
|
16
|
+
if (cached && cached.expiresAt > Date.now() + 120000) {
|
|
17
|
+
const remainingMinutes = Math.round((cached.expiresAt - Date.now()) / 1000 / 60);
|
|
18
|
+
console.log(`✅ Using cached OAuth token (${remainingMinutes} minutes remaining)`);
|
|
19
|
+
return cached.token;
|
|
20
|
+
}
|
|
21
|
+
console.log('🔄 Generating new OAuth token...');
|
|
22
|
+
const newToken = await this.generateOAuthToken(githubToken);
|
|
23
|
+
return newToken;
|
|
24
|
+
}
|
|
25
|
+
static async generateOAuthToken(githubToken) {
|
|
26
|
+
const machineId = this.getMachineId(githubToken);
|
|
27
|
+
const sessionId = this.generateSessionId();
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
const options = {
|
|
30
|
+
hostname: 'api.github.com',
|
|
31
|
+
path: '/copilot_internal/v2/token',
|
|
32
|
+
method: 'GET',
|
|
33
|
+
headers: {
|
|
34
|
+
'Authorization': `token ${githubToken}`,
|
|
35
|
+
'Vscode-Machineid': machineId,
|
|
36
|
+
'Vscode-Sessionid': sessionId,
|
|
37
|
+
'Editor-Version': 'vscode/1.105.1',
|
|
38
|
+
'Editor-Plugin-Version': 'copilot-chat/0.32.3',
|
|
39
|
+
'X-GitHub-Api-Version': '2025-08-20',
|
|
40
|
+
'Accept': 'application/json',
|
|
41
|
+
'User-Agent': 'n8n-nodes-copilot/1.0.0',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
const req = https_1.default.request(options, (res) => {
|
|
45
|
+
let data = '';
|
|
46
|
+
res.on('data', (chunk) => (data += chunk));
|
|
47
|
+
res.on('end', () => {
|
|
48
|
+
if (res.statusCode === 200) {
|
|
49
|
+
try {
|
|
50
|
+
const response = JSON.parse(data);
|
|
51
|
+
const oauthToken = response.token;
|
|
52
|
+
const expiresAt = response.expires_at * 1000;
|
|
53
|
+
const refreshIn = response.refresh_in;
|
|
54
|
+
const cacheKey = this.getCacheKey(githubToken);
|
|
55
|
+
this.tokenCache.set(cacheKey, {
|
|
56
|
+
token: oauthToken,
|
|
57
|
+
expiresAt: expiresAt,
|
|
58
|
+
generatedAt: Date.now(),
|
|
59
|
+
refreshIn: refreshIn,
|
|
60
|
+
});
|
|
61
|
+
const expiresInMinutes = Math.round((expiresAt - Date.now()) / 1000 / 60);
|
|
62
|
+
console.log(`✅ OAuth token generated successfully (expires in ${expiresInMinutes} minutes)`);
|
|
63
|
+
resolve(oauthToken);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
reject(new Error(`Failed to parse OAuth token response: ${error}`));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
reject(new Error(`Failed to generate OAuth token: ${res.statusCode} ${res.statusMessage}`));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
req.on('error', (error) => {
|
|
75
|
+
reject(new Error(`Network error generating OAuth token: ${error.message}`));
|
|
76
|
+
});
|
|
77
|
+
req.setTimeout(10000, () => {
|
|
78
|
+
req.destroy();
|
|
79
|
+
reject(new Error('OAuth token generation timeout'));
|
|
80
|
+
});
|
|
81
|
+
req.end();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
static getMachineId(githubToken) {
|
|
85
|
+
const cacheKey = this.getCacheKey(githubToken);
|
|
86
|
+
if (!this.machineIdCache.has(cacheKey)) {
|
|
87
|
+
const uuid = crypto_1.default.randomUUID();
|
|
88
|
+
const machineId = crypto_1.default.createHash('sha256').update(uuid).digest('hex');
|
|
89
|
+
this.machineIdCache.set(cacheKey, machineId);
|
|
90
|
+
console.log('🆔 Generated new machine ID');
|
|
91
|
+
}
|
|
92
|
+
return this.machineIdCache.get(cacheKey);
|
|
93
|
+
}
|
|
94
|
+
static generateSessionId() {
|
|
95
|
+
return `${crypto_1.default.randomUUID()}${Date.now()}`;
|
|
96
|
+
}
|
|
97
|
+
static getCacheKey(githubToken) {
|
|
98
|
+
return githubToken.substring(0, 20);
|
|
99
|
+
}
|
|
100
|
+
static clearCache(githubToken) {
|
|
101
|
+
const cacheKey = this.getCacheKey(githubToken);
|
|
102
|
+
this.tokenCache.delete(cacheKey);
|
|
103
|
+
this.machineIdCache.delete(cacheKey);
|
|
104
|
+
console.log('🗑️ OAuth token cache cleared');
|
|
105
|
+
}
|
|
106
|
+
static getCacheInfo(githubToken) {
|
|
107
|
+
const cacheKey = this.getCacheKey(githubToken);
|
|
108
|
+
return this.tokenCache.get(cacheKey) || null;
|
|
109
|
+
}
|
|
110
|
+
static needsRefresh(githubToken, bufferMinutes = 2) {
|
|
111
|
+
const cacheKey = this.getCacheKey(githubToken);
|
|
112
|
+
const cached = this.tokenCache.get(cacheKey);
|
|
113
|
+
if (!cached)
|
|
114
|
+
return true;
|
|
115
|
+
const bufferMs = bufferMinutes * 60 * 1000;
|
|
116
|
+
return cached.expiresAt <= Date.now() + bufferMs;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.OAuthTokenManager = OAuthTokenManager;
|
|
120
|
+
OAuthTokenManager.tokenCache = new Map();
|
|
121
|
+
OAuthTokenManager.machineIdCache = new Map();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-github-copilot",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.32.0",
|
|
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",
|