@generacy-ai/generacy-plugin-github-issues 0.0.0-preview-20260304013206
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/LICENSE +191 -0
- package/dist/auth/auth-factory.d.ts +44 -0
- package/dist/auth/auth-factory.d.ts.map +1 -0
- package/dist/auth/auth-factory.js +85 -0
- package/dist/auth/auth-factory.js.map +1 -0
- package/dist/auth/env.d.ts +32 -0
- package/dist/auth/env.d.ts.map +1 -0
- package/dist/auth/env.js +88 -0
- package/dist/auth/env.js.map +1 -0
- package/dist/auth/github-app.d.ts +69 -0
- package/dist/auth/github-app.d.ts.map +1 -0
- package/dist/auth/github-app.js +191 -0
- package/dist/auth/github-app.js.map +1 -0
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +10 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/token-cache.d.ts +70 -0
- package/dist/auth/token-cache.d.ts.map +1 -0
- package/dist/auth/token-cache.js +112 -0
- package/dist/auth/token-cache.js.map +1 -0
- package/dist/auth/types.d.ts +119 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +27 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/client.d.ts +101 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +197 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/operations/comments.d.ts +46 -0
- package/dist/operations/comments.d.ts.map +1 -0
- package/dist/operations/comments.js +127 -0
- package/dist/operations/comments.js.map +1 -0
- package/dist/operations/issues.d.ts +46 -0
- package/dist/operations/issues.d.ts.map +1 -0
- package/dist/operations/issues.js +188 -0
- package/dist/operations/issues.js.map +1 -0
- package/dist/operations/labels.d.ts +46 -0
- package/dist/operations/labels.d.ts.map +1 -0
- package/dist/operations/labels.js +132 -0
- package/dist/operations/labels.js.map +1 -0
- package/dist/operations/pull-requests.d.ts +41 -0
- package/dist/operations/pull-requests.d.ts.map +1 -0
- package/dist/operations/pull-requests.js +162 -0
- package/dist/operations/pull-requests.js.map +1 -0
- package/dist/plugin.d.ts +181 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +324 -0
- package/dist/plugin.js.map +1 -0
- package/dist/types/config.d.ts +126 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +22 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/events.d.ts +72 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/issues.d.ts +178 -0
- package/dist/types/issues.d.ts.map +1 -0
- package/dist/types/issues.js +29 -0
- package/dist/types/issues.js.map +1 -0
- package/dist/types/responses.d.ts +61 -0
- package/dist/types/responses.d.ts.map +1 -0
- package/dist/types/responses.js +5 -0
- package/dist/types/responses.js.map +1 -0
- package/dist/utils/errors.d.ts +69 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +123 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/validation.d.ts +33 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +69 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/webhooks/handler.d.ts +66 -0
- package/dist/webhooks/handler.d.ts.map +1 -0
- package/dist/webhooks/handler.js +176 -0
- package/dist/webhooks/handler.js.map +1 -0
- package/dist/webhooks/parser.d.ts +36 -0
- package/dist/webhooks/parser.d.ts.map +1 -0
- package/dist/webhooks/parser.js +220 -0
- package/dist/webhooks/parser.js.map +1 -0
- package/dist/webhooks/triggers.d.ts +25 -0
- package/dist/webhooks/triggers.d.ts.map +1 -0
- package/dist/webhooks/triggers.js +119 -0
- package/dist/webhooks/triggers.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { createAppAuth } from '@octokit/auth-app';
|
|
2
|
+
import { Octokit } from '@octokit/rest';
|
|
3
|
+
import { GitHubAppAuthError, GitHubAppErrorCode } from '../utils/errors.js';
|
|
4
|
+
import { TokenCache } from './token-cache.js';
|
|
5
|
+
import * as fs from 'node:fs';
|
|
6
|
+
/**
|
|
7
|
+
* GitHub App authentication strategy
|
|
8
|
+
*
|
|
9
|
+
* Implements the AuthStrategy interface for GitHub App authentication.
|
|
10
|
+
* Handles JWT generation, installation discovery, and token caching.
|
|
11
|
+
*/
|
|
12
|
+
export class GitHubAppAuthStrategy {
|
|
13
|
+
type = 'github-app';
|
|
14
|
+
config;
|
|
15
|
+
context;
|
|
16
|
+
tokenCache;
|
|
17
|
+
installationId = null;
|
|
18
|
+
octokit = null;
|
|
19
|
+
authFn = null;
|
|
20
|
+
constructor(config, context) {
|
|
21
|
+
this.config = config;
|
|
22
|
+
this.context = context;
|
|
23
|
+
this.tokenCache = new TokenCache();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Initialize the GitHub App authentication
|
|
27
|
+
* - Resolves private key (from file or inline)
|
|
28
|
+
* - Creates the auth function
|
|
29
|
+
* - Discovers installation ID if not provided
|
|
30
|
+
*/
|
|
31
|
+
async initialize() {
|
|
32
|
+
const privateKey = await this.resolvePrivateKey();
|
|
33
|
+
const appId = typeof this.config.appId === 'string'
|
|
34
|
+
? parseInt(this.config.appId, 10)
|
|
35
|
+
: this.config.appId;
|
|
36
|
+
this.authFn = createAppAuth({
|
|
37
|
+
appId,
|
|
38
|
+
privateKey,
|
|
39
|
+
});
|
|
40
|
+
// If installation ID is provided, use it; otherwise discover it
|
|
41
|
+
if (this.config.installationId) {
|
|
42
|
+
this.installationId = this.config.installationId;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.installationId = await this.discoverInstallationId();
|
|
46
|
+
}
|
|
47
|
+
// Create Octokit instance with app auth
|
|
48
|
+
this.octokit = new Octokit({
|
|
49
|
+
authStrategy: createAppAuth,
|
|
50
|
+
auth: {
|
|
51
|
+
appId,
|
|
52
|
+
privateKey,
|
|
53
|
+
installationId: this.installationId,
|
|
54
|
+
},
|
|
55
|
+
baseUrl: this.context.baseUrl,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the private key from file path or inline content
|
|
60
|
+
*/
|
|
61
|
+
async resolvePrivateKey() {
|
|
62
|
+
if (this.config.privateKey) {
|
|
63
|
+
return this.config.privateKey;
|
|
64
|
+
}
|
|
65
|
+
if (this.config.privateKeyPath) {
|
|
66
|
+
try {
|
|
67
|
+
return fs.readFileSync(this.config.privateKeyPath, 'utf-8');
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
throw new GitHubAppAuthError(`Failed to read private key from path: ${this.config.privateKeyPath}`, GitHubAppErrorCode.PRIVATE_KEY_NOT_FOUND, error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
throw new GitHubAppAuthError('No private key provided. Either privateKey or privateKeyPath is required.', GitHubAppErrorCode.INVALID_PRIVATE_KEY);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Discover the installation ID for the configured owner
|
|
77
|
+
* Uses the GitHub App JWT to list installations and find the matching one
|
|
78
|
+
*/
|
|
79
|
+
async discoverInstallationId() {
|
|
80
|
+
if (!this.authFn) {
|
|
81
|
+
throw new GitHubAppAuthError('Auth function not initialized', GitHubAppErrorCode.JWT_GENERATION_FAILED);
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
// Get app-level auth (JWT) for listing installations
|
|
85
|
+
const appAuth = await this.authFn({ type: 'app' });
|
|
86
|
+
// Create a temporary Octokit for installation discovery
|
|
87
|
+
const tempOctokit = new Octokit({
|
|
88
|
+
auth: appAuth.token,
|
|
89
|
+
baseUrl: this.context.baseUrl,
|
|
90
|
+
});
|
|
91
|
+
// List all installations
|
|
92
|
+
const { data: installations } = await tempOctokit.request('GET /app/installations');
|
|
93
|
+
// Find installation for the configured owner (case-insensitive)
|
|
94
|
+
const installation = installations.find((inst) => inst.account?.login.toLowerCase() === this.context.owner.toLowerCase());
|
|
95
|
+
if (!installation) {
|
|
96
|
+
throw new GitHubAppAuthError(`No installation found for owner: ${this.context.owner}`, GitHubAppErrorCode.INSTALLATION_NOT_FOUND);
|
|
97
|
+
}
|
|
98
|
+
return installation.id;
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (error instanceof GitHubAppAuthError) {
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
throw new GitHubAppAuthError('Failed to discover installation ID', GitHubAppErrorCode.INSTALLATION_NOT_FOUND, error);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get a valid authentication token
|
|
109
|
+
* Returns cached token if still valid, otherwise generates a new one
|
|
110
|
+
*/
|
|
111
|
+
async getToken() {
|
|
112
|
+
if (this.installationId === null) {
|
|
113
|
+
await this.initialize();
|
|
114
|
+
}
|
|
115
|
+
// Check cache first
|
|
116
|
+
const cached = this.tokenCache.get(this.installationId);
|
|
117
|
+
if (cached && !this.tokenCache.needsRefresh(this.installationId)) {
|
|
118
|
+
return cached.token;
|
|
119
|
+
}
|
|
120
|
+
// Generate new token
|
|
121
|
+
return this.generateInstallationToken();
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Generate a new installation access token
|
|
125
|
+
*/
|
|
126
|
+
async generateInstallationToken() {
|
|
127
|
+
if (!this.authFn || this.installationId === null) {
|
|
128
|
+
throw new GitHubAppAuthError('GitHub App not initialized', GitHubAppErrorCode.TOKEN_GENERATION_FAILED);
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const auth = await this.authFn({
|
|
132
|
+
type: 'installation',
|
|
133
|
+
installationId: this.installationId,
|
|
134
|
+
});
|
|
135
|
+
// Cache the token
|
|
136
|
+
const cachedToken = {
|
|
137
|
+
token: auth.token,
|
|
138
|
+
expiresAt: new Date(auth.expiresAt),
|
|
139
|
+
installationId: this.installationId,
|
|
140
|
+
permissions: auth.permissions ?? {},
|
|
141
|
+
repositorySelection: auth.repositorySelection ?? 'all',
|
|
142
|
+
};
|
|
143
|
+
this.tokenCache.set(cachedToken);
|
|
144
|
+
return auth.token;
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
throw new GitHubAppAuthError('Failed to generate installation access token', GitHubAppErrorCode.TOKEN_GENERATION_FAILED, error);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Verify that authentication is working
|
|
152
|
+
* Returns the authenticated user/bot information
|
|
153
|
+
*/
|
|
154
|
+
async verify() {
|
|
155
|
+
const token = await this.getToken();
|
|
156
|
+
const octokit = new Octokit({
|
|
157
|
+
auth: token,
|
|
158
|
+
baseUrl: this.context.baseUrl,
|
|
159
|
+
});
|
|
160
|
+
const { data } = await octokit.request('GET /user');
|
|
161
|
+
return {
|
|
162
|
+
login: data.login,
|
|
163
|
+
id: data.id,
|
|
164
|
+
type: data.type,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get the Octokit instance for making API calls
|
|
169
|
+
*/
|
|
170
|
+
getOctokit() {
|
|
171
|
+
if (!this.octokit) {
|
|
172
|
+
throw new GitHubAppAuthError('GitHub App not initialized. Call initialize() first.', GitHubAppErrorCode.JWT_GENERATION_FAILED);
|
|
173
|
+
}
|
|
174
|
+
return this.octokit;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Clear the token cache
|
|
178
|
+
*/
|
|
179
|
+
clearCache() {
|
|
180
|
+
this.tokenCache.clearAll();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Create a new GitHubAppAuthStrategy instance
|
|
185
|
+
*/
|
|
186
|
+
export async function createGitHubAppAuth(config, context) {
|
|
187
|
+
const strategy = new GitHubAppAuthStrategy(config, context);
|
|
188
|
+
await strategy.initialize();
|
|
189
|
+
return strategy;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=github-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-app.js","sourceRoot":"","sources":["../../src/auth/github-app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { GitHubAppConfig, AuthStrategy, AuthVerification, CachedToken, ValidatedGitHubAppConfig, } from './types.js';
|
|
2
|
+
export { GitHubAppConfigSchema } from './types.js';
|
|
3
|
+
export { GitHubAppAuthStrategy, createGitHubAppAuth } from './github-app.js';
|
|
4
|
+
export type { AuthContext } from './github-app.js';
|
|
5
|
+
export { PATAuthStrategy, createAuthStrategy } from './auth-factory.js';
|
|
6
|
+
export type { AuthFactoryConfig } from './auth-factory.js';
|
|
7
|
+
export { TokenCache } from './token-cache.js';
|
|
8
|
+
export type { TokenCacheOptions } from './token-cache.js';
|
|
9
|
+
export { readGitHubAppConfigFromEnv, hasGitHubAppEnvConfig, loadPrivateKeyFromPath, ENV_VARS, } from './env.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,EACtB,QAAQ,GACT,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { GitHubAppConfigSchema } from './types.js';
|
|
2
|
+
// GitHub App authentication
|
|
3
|
+
export { GitHubAppAuthStrategy, createGitHubAppAuth } from './github-app.js';
|
|
4
|
+
// PAT authentication and factory
|
|
5
|
+
export { PATAuthStrategy, createAuthStrategy } from './auth-factory.js';
|
|
6
|
+
// Token cache
|
|
7
|
+
export { TokenCache } from './token-cache.js';
|
|
8
|
+
// Environment variable helpers
|
|
9
|
+
export { readGitHubAppConfigFromEnv, hasGitHubAppEnvConfig, loadPrivateKeyFromPath, ENV_VARS, } from './env.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,4BAA4B;AAC5B,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG7E,iCAAiC;AACjC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGxE,cAAc;AACd,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,+BAA+B;AAC/B,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,EACtB,QAAQ,GACT,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { CachedToken } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for the TokenCache
|
|
4
|
+
*/
|
|
5
|
+
export interface TokenCacheOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Callback when a token needs to be refreshed
|
|
8
|
+
* Called when getWithRefresh() is invoked and token is within refresh window
|
|
9
|
+
*/
|
|
10
|
+
onRefreshNeeded?: (installationId: number) => Promise<CachedToken>;
|
|
11
|
+
/**
|
|
12
|
+
* Refresh threshold in milliseconds (default: 10 minutes = 600000ms)
|
|
13
|
+
* Tokens will be proactively refreshed when this much time remains
|
|
14
|
+
*/
|
|
15
|
+
refreshThresholdMs?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* In-memory token cache with expiry tracking and proactive refresh
|
|
19
|
+
*
|
|
20
|
+
* Caches installation access tokens with their expiration times.
|
|
21
|
+
* Supports proactive refresh when tokens are approaching expiry.
|
|
22
|
+
*/
|
|
23
|
+
export declare class TokenCache {
|
|
24
|
+
private readonly cache;
|
|
25
|
+
private readonly options;
|
|
26
|
+
/** Default refresh threshold: 10 minutes before expiry */
|
|
27
|
+
private static readonly DEFAULT_REFRESH_THRESHOLD_MS;
|
|
28
|
+
constructor(options?: TokenCacheOptions);
|
|
29
|
+
/**
|
|
30
|
+
* Get a cached token by installation ID
|
|
31
|
+
* Returns undefined if token doesn't exist or is expired
|
|
32
|
+
*/
|
|
33
|
+
get(installationId: number): CachedToken | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Get a token with automatic refresh if needed
|
|
36
|
+
* If the token is within the refresh threshold, calls the refresh callback
|
|
37
|
+
*/
|
|
38
|
+
getWithRefresh(installationId: number): Promise<CachedToken | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* Store a token in the cache
|
|
41
|
+
*/
|
|
42
|
+
set(token: CachedToken): void;
|
|
43
|
+
/**
|
|
44
|
+
* Check if a token is expired
|
|
45
|
+
* Returns true if token doesn't exist or is past expiration
|
|
46
|
+
*/
|
|
47
|
+
isExpired(installationId: number): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a token needs to be refreshed
|
|
50
|
+
* Returns true if token doesn't exist, is expired, or is within the refresh threshold
|
|
51
|
+
*/
|
|
52
|
+
needsRefresh(installationId: number): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Remove a token from the cache
|
|
55
|
+
*/
|
|
56
|
+
clear(installationId: number): void;
|
|
57
|
+
/**
|
|
58
|
+
* Remove all tokens from the cache
|
|
59
|
+
*/
|
|
60
|
+
clearAll(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get the number of cached tokens
|
|
63
|
+
*/
|
|
64
|
+
get size(): number;
|
|
65
|
+
/**
|
|
66
|
+
* Check if a token exists for the given installation (regardless of expiry)
|
|
67
|
+
*/
|
|
68
|
+
has(installationId: number): boolean;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=token-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-cache.d.ts","sourceRoot":"","sources":["../../src/auth/token-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAEnE;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8E;IAEtG,0DAA0D;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAkB;gBAE1D,OAAO,GAAE,iBAAsB;IAO3C;;;OAGG;IACH,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAepD;;;OAGG;IACG,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAuB9E;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAI7B;;;OAGG;IACH,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAQ1C;;;OAGG;IACH,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAU7C;;OAEG;IACH,KAAK,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;CAGrC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory token cache with expiry tracking and proactive refresh
|
|
3
|
+
*
|
|
4
|
+
* Caches installation access tokens with their expiration times.
|
|
5
|
+
* Supports proactive refresh when tokens are approaching expiry.
|
|
6
|
+
*/
|
|
7
|
+
export class TokenCache {
|
|
8
|
+
cache = new Map();
|
|
9
|
+
options;
|
|
10
|
+
/** Default refresh threshold: 10 minutes before expiry */
|
|
11
|
+
static DEFAULT_REFRESH_THRESHOLD_MS = 10 * 60 * 1000;
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
this.options = {
|
|
14
|
+
refreshThresholdMs: options.refreshThresholdMs ?? TokenCache.DEFAULT_REFRESH_THRESHOLD_MS,
|
|
15
|
+
onRefreshNeeded: options.onRefreshNeeded,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get a cached token by installation ID
|
|
20
|
+
* Returns undefined if token doesn't exist or is expired
|
|
21
|
+
*/
|
|
22
|
+
get(installationId) {
|
|
23
|
+
const token = this.cache.get(installationId);
|
|
24
|
+
if (!token) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
// Return undefined if expired
|
|
28
|
+
if (this.isExpired(installationId)) {
|
|
29
|
+
this.cache.delete(installationId);
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return token;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get a token with automatic refresh if needed
|
|
36
|
+
* If the token is within the refresh threshold, calls the refresh callback
|
|
37
|
+
*/
|
|
38
|
+
async getWithRefresh(installationId) {
|
|
39
|
+
const token = this.get(installationId);
|
|
40
|
+
// If no token or no callback, just return what we have
|
|
41
|
+
if (!token || !this.options.onRefreshNeeded) {
|
|
42
|
+
return token;
|
|
43
|
+
}
|
|
44
|
+
// Check if we need to refresh
|
|
45
|
+
if (this.needsRefresh(installationId)) {
|
|
46
|
+
try {
|
|
47
|
+
const newToken = await this.options.onRefreshNeeded(installationId);
|
|
48
|
+
this.set(newToken);
|
|
49
|
+
return newToken;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// If refresh fails, return existing token if still valid
|
|
53
|
+
return token;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return token;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Store a token in the cache
|
|
60
|
+
*/
|
|
61
|
+
set(token) {
|
|
62
|
+
this.cache.set(token.installationId, token);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if a token is expired
|
|
66
|
+
* Returns true if token doesn't exist or is past expiration
|
|
67
|
+
*/
|
|
68
|
+
isExpired(installationId) {
|
|
69
|
+
const token = this.cache.get(installationId);
|
|
70
|
+
if (!token) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return token.expiresAt.getTime() <= Date.now();
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if a token needs to be refreshed
|
|
77
|
+
* Returns true if token doesn't exist, is expired, or is within the refresh threshold
|
|
78
|
+
*/
|
|
79
|
+
needsRefresh(installationId) {
|
|
80
|
+
const token = this.cache.get(installationId);
|
|
81
|
+
if (!token) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
const timeUntilExpiry = token.expiresAt.getTime() - Date.now();
|
|
85
|
+
return timeUntilExpiry <= this.options.refreshThresholdMs;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Remove a token from the cache
|
|
89
|
+
*/
|
|
90
|
+
clear(installationId) {
|
|
91
|
+
this.cache.delete(installationId);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Remove all tokens from the cache
|
|
95
|
+
*/
|
|
96
|
+
clearAll() {
|
|
97
|
+
this.cache.clear();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get the number of cached tokens
|
|
101
|
+
*/
|
|
102
|
+
get size() {
|
|
103
|
+
return this.cache.size;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if a token exists for the given installation (regardless of expiry)
|
|
107
|
+
*/
|
|
108
|
+
has(installationId) {
|
|
109
|
+
return this.cache.has(installationId);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=token-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-cache.js","sourceRoot":"","sources":["../../src/auth/token-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for GitHub App configuration validation
|
|
4
|
+
*/
|
|
5
|
+
export declare const GitHubAppConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
6
|
+
/** GitHub App ID */
|
|
7
|
+
appId: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
8
|
+
/** Private key in PEM format */
|
|
9
|
+
privateKey: z.ZodOptional<z.ZodString>;
|
|
10
|
+
/** Path to private key PEM file */
|
|
11
|
+
privateKeyPath: z.ZodOptional<z.ZodString>;
|
|
12
|
+
/** Optional installation ID (auto-discovered if not provided) */
|
|
13
|
+
installationId: z.ZodOptional<z.ZodNumber>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
appId: string | number;
|
|
16
|
+
privateKey?: string | undefined;
|
|
17
|
+
privateKeyPath?: string | undefined;
|
|
18
|
+
installationId?: number | undefined;
|
|
19
|
+
}, {
|
|
20
|
+
appId: string | number;
|
|
21
|
+
privateKey?: string | undefined;
|
|
22
|
+
privateKeyPath?: string | undefined;
|
|
23
|
+
installationId?: number | undefined;
|
|
24
|
+
}>, {
|
|
25
|
+
appId: string | number;
|
|
26
|
+
privateKey?: string | undefined;
|
|
27
|
+
privateKeyPath?: string | undefined;
|
|
28
|
+
installationId?: number | undefined;
|
|
29
|
+
}, {
|
|
30
|
+
appId: string | number;
|
|
31
|
+
privateKey?: string | undefined;
|
|
32
|
+
privateKeyPath?: string | undefined;
|
|
33
|
+
installationId?: number | undefined;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* GitHub App configuration for authentication
|
|
37
|
+
*/
|
|
38
|
+
export interface GitHubAppConfig {
|
|
39
|
+
/** GitHub App ID */
|
|
40
|
+
appId: number | string;
|
|
41
|
+
/** Private key in PEM format */
|
|
42
|
+
privateKey?: string;
|
|
43
|
+
/** Path to private key PEM file */
|
|
44
|
+
privateKeyPath?: string;
|
|
45
|
+
/** Optional installation ID (auto-discovered if not provided) */
|
|
46
|
+
installationId?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Result of authentication verification
|
|
50
|
+
*/
|
|
51
|
+
export interface AuthVerification {
|
|
52
|
+
/** GitHub login/username */
|
|
53
|
+
login: string;
|
|
54
|
+
/** GitHub user/bot ID */
|
|
55
|
+
id: number;
|
|
56
|
+
/** Account type */
|
|
57
|
+
type: 'User' | 'Bot';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Authentication strategy interface
|
|
61
|
+
*/
|
|
62
|
+
export interface AuthStrategy {
|
|
63
|
+
/** Get a valid authentication token */
|
|
64
|
+
getToken(): Promise<string>;
|
|
65
|
+
/** Verify that authentication is working */
|
|
66
|
+
verify(): Promise<AuthVerification>;
|
|
67
|
+
/** Authentication type for logging purposes */
|
|
68
|
+
readonly type: 'pat' | 'github-app';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Cached installation access token
|
|
72
|
+
*/
|
|
73
|
+
export interface CachedToken {
|
|
74
|
+
/** The access token */
|
|
75
|
+
token: string;
|
|
76
|
+
/** Token expiration time */
|
|
77
|
+
expiresAt: Date;
|
|
78
|
+
/** Installation ID the token is for */
|
|
79
|
+
installationId: number;
|
|
80
|
+
/** Permissions granted to this token */
|
|
81
|
+
permissions: Record<string, string>;
|
|
82
|
+
/** Repository selection mode */
|
|
83
|
+
repositorySelection: 'all' | 'selected';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Inferred type from GitHubAppConfigSchema
|
|
87
|
+
*/
|
|
88
|
+
export declare const ValidatedGitHubAppConfig: z.ZodEffects<z.ZodObject<{
|
|
89
|
+
/** GitHub App ID */
|
|
90
|
+
appId: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
91
|
+
/** Private key in PEM format */
|
|
92
|
+
privateKey: z.ZodOptional<z.ZodString>;
|
|
93
|
+
/** Path to private key PEM file */
|
|
94
|
+
privateKeyPath: z.ZodOptional<z.ZodString>;
|
|
95
|
+
/** Optional installation ID (auto-discovered if not provided) */
|
|
96
|
+
installationId: z.ZodOptional<z.ZodNumber>;
|
|
97
|
+
}, "strip", z.ZodTypeAny, {
|
|
98
|
+
appId: string | number;
|
|
99
|
+
privateKey?: string | undefined;
|
|
100
|
+
privateKeyPath?: string | undefined;
|
|
101
|
+
installationId?: number | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
appId: string | number;
|
|
104
|
+
privateKey?: string | undefined;
|
|
105
|
+
privateKeyPath?: string | undefined;
|
|
106
|
+
installationId?: number | undefined;
|
|
107
|
+
}>, {
|
|
108
|
+
appId: string | number;
|
|
109
|
+
privateKey?: string | undefined;
|
|
110
|
+
privateKeyPath?: string | undefined;
|
|
111
|
+
installationId?: number | undefined;
|
|
112
|
+
}, {
|
|
113
|
+
appId: string | number;
|
|
114
|
+
privateKey?: string | undefined;
|
|
115
|
+
privateKeyPath?: string | undefined;
|
|
116
|
+
installationId?: number | undefined;
|
|
117
|
+
}>;
|
|
118
|
+
export type ValidatedGitHubAppConfig = z.infer<typeof GitHubAppConfigSchema>;
|
|
119
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,qBAAqB;IAE9B,oBAAoB;;IAKpB,gCAAgC;;IAEhC,mCAAmC;;IAEnC,iEAAiE;;;;;;;;;;;;;;;;;;;;;;EAMjE,CAAC;AAEL;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oBAAoB;IACpB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,4CAA4C;IAC5C,MAAM,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACpC,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,YAAY,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,uCAAuC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,gCAAgC;IAChC,mBAAmB,EAAE,KAAK,GAAG,UAAU,CAAC;CACzC;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB;IA1EjC,oBAAoB;;IAKpB,gCAAgC;;IAEhC,mCAAmC;;IAEnC,iEAAiE;;;;;;;;;;;;;;;;;;;;;;EAiER,CAAC;AAC9D,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for GitHub App configuration validation
|
|
4
|
+
*/
|
|
5
|
+
export const GitHubAppConfigSchema = z
|
|
6
|
+
.object({
|
|
7
|
+
/** GitHub App ID */
|
|
8
|
+
appId: z.union([
|
|
9
|
+
z.number().positive('App ID must be a positive number'),
|
|
10
|
+
z.string().regex(/^\d+$/, 'App ID must be a numeric string'),
|
|
11
|
+
]),
|
|
12
|
+
/** Private key in PEM format */
|
|
13
|
+
privateKey: z.string().optional(),
|
|
14
|
+
/** Path to private key PEM file */
|
|
15
|
+
privateKeyPath: z.string().optional(),
|
|
16
|
+
/** Optional installation ID (auto-discovered if not provided) */
|
|
17
|
+
installationId: z.number().positive('Installation ID must be positive').optional(),
|
|
18
|
+
})
|
|
19
|
+
.refine((data) => data.privateKey !== undefined || data.privateKeyPath !== undefined, {
|
|
20
|
+
message: 'Either privateKey or privateKeyPath must be provided',
|
|
21
|
+
path: ['privateKey'],
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Inferred type from GitHubAppConfigSchema
|
|
25
|
+
*/
|
|
26
|
+
export const ValidatedGitHubAppConfig = GitHubAppConfigSchema;
|
|
27
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC;KACnC,MAAM,CAAC;IACN,oBAAoB;IACpB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;QACb,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;QACvD,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,iCAAiC,CAAC;KAC7D,CAAC;IACF,gCAAgC;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,mCAAmC;IACnC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,iEAAiE;IACjE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAAC,QAAQ,EAAE;CACnF,CAAC;KACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE;IACpF,OAAO,EAAE,sDAAsD;IAC/D,IAAI,EAAE,CAAC,YAAY,CAAC;CACrB,CAAC,CAAC;AAwDL;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC"}
|