cyrus-github-event-transport 0.2.39 → 0.2.40

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.
@@ -0,0 +1,35 @@
1
+ export interface GitHubAppTokenProviderConfig {
2
+ appId: string;
3
+ installationId: string;
4
+ privateKeyPath: string;
5
+ /** GitHub API base URL (default: https://api.github.com) */
6
+ apiBaseUrl?: string;
7
+ }
8
+ /**
9
+ * Mints and caches GitHub App installation tokens for self-hosted users.
10
+ *
11
+ * Uses the App's private key to sign a JWT, then exchanges it for a
12
+ * short-lived installation access token via the GitHub API.
13
+ * Tokens are cached and refreshed 5 minutes before expiry.
14
+ */
15
+ export declare class GitHubAppTokenProvider {
16
+ private config;
17
+ private cachedToken;
18
+ private expiresAt;
19
+ private privateKeyPromise;
20
+ constructor(config: GitHubAppTokenProviderConfig);
21
+ /**
22
+ * Get a valid installation access token.
23
+ * Returns cached token if still valid, otherwise mints a new one.
24
+ */
25
+ getToken(): Promise<string>;
26
+ private loadPrivateKey;
27
+ }
28
+ /**
29
+ * Create a JWT for GitHub App authentication.
30
+ * Uses Node's native crypto — no external JWT library needed.
31
+ *
32
+ * @see https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app
33
+ */
34
+ export declare function createAppJwt(appId: string, privateKey: string): string;
35
+ //# sourceMappingURL=GitHubAppTokenProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubAppTokenProvider.d.ts","sourceRoot":"","sources":["../src/GitHubAppTokenProvider.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,4BAA4B;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,qBAAa,sBAAsB;IAClC,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,iBAAiB,CAAgC;gBAE7C,MAAM,EAAE,4BAA4B;IAIhD;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAwCjC,OAAO,CAAC,cAAc;CAMtB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAkBtE"}
@@ -0,0 +1,73 @@
1
+ import { createSign } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ /**
4
+ * Mints and caches GitHub App installation tokens for self-hosted users.
5
+ *
6
+ * Uses the App's private key to sign a JWT, then exchanges it for a
7
+ * short-lived installation access token via the GitHub API.
8
+ * Tokens are cached and refreshed 5 minutes before expiry.
9
+ */
10
+ export class GitHubAppTokenProvider {
11
+ config;
12
+ cachedToken = null;
13
+ expiresAt = 0;
14
+ privateKeyPromise = null;
15
+ constructor(config) {
16
+ this.config = config;
17
+ }
18
+ /**
19
+ * Get a valid installation access token.
20
+ * Returns cached token if still valid, otherwise mints a new one.
21
+ */
22
+ async getToken() {
23
+ // Refresh 5 minutes before expiry
24
+ if (this.cachedToken && Date.now() < this.expiresAt - 5 * 60 * 1000) {
25
+ return this.cachedToken;
26
+ }
27
+ const pem = await this.loadPrivateKey();
28
+ const jwt = createAppJwt(this.config.appId, pem);
29
+ const apiBase = this.config.apiBaseUrl ?? "https://api.github.com";
30
+ const response = await fetch(`${apiBase}/app/installations/${this.config.installationId}/access_tokens`, {
31
+ method: "POST",
32
+ headers: {
33
+ Authorization: `Bearer ${jwt}`,
34
+ Accept: "application/vnd.github+json",
35
+ "X-GitHub-Api-Version": "2022-11-28",
36
+ },
37
+ });
38
+ if (!response.ok) {
39
+ const body = await response.text();
40
+ throw new Error(`[GitHubAppTokenProvider] Failed to create installation token: ${response.status} ${response.statusText} - ${body}`);
41
+ }
42
+ const data = (await response.json());
43
+ this.cachedToken = data.token;
44
+ this.expiresAt = new Date(data.expires_at).getTime();
45
+ return this.cachedToken;
46
+ }
47
+ loadPrivateKey() {
48
+ if (!this.privateKeyPromise) {
49
+ this.privateKeyPromise = readFile(this.config.privateKeyPath, "utf-8");
50
+ }
51
+ return this.privateKeyPromise;
52
+ }
53
+ }
54
+ /**
55
+ * Create a JWT for GitHub App authentication.
56
+ * Uses Node's native crypto — no external JWT library needed.
57
+ *
58
+ * @see https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app
59
+ */
60
+ export function createAppJwt(appId, privateKey) {
61
+ const now = Math.floor(Date.now() / 1000);
62
+ const header = Buffer.from(JSON.stringify({ alg: "RS256", typ: "JWT" })).toString("base64url");
63
+ const payload = Buffer.from(JSON.stringify({
64
+ iat: now - 60,
65
+ exp: now + 10 * 60,
66
+ iss: appId,
67
+ })).toString("base64url");
68
+ const sign = createSign("RSA-SHA256");
69
+ sign.update(`${header}.${payload}`);
70
+ const signature = sign.sign(privateKey, "base64url");
71
+ return `${header}.${payload}.${signature}`;
72
+ }
73
+ //# sourceMappingURL=GitHubAppTokenProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubAppTokenProvider.js","sourceRoot":"","sources":["../src/GitHubAppTokenProvider.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export type { GitHubAppTokenProviderConfig } from "./GitHubAppTokenProvider.js";
2
+ export { createAppJwt, GitHubAppTokenProvider, } from "./GitHubAppTokenProvider.js";
1
3
  export type { AddReactionParams, GitHubCommentResponse, GitHubCommentServiceConfig, PostCommentParams, PostReviewCommentReplyParams, } from "./GitHubCommentService.js";
2
4
  export { GitHubCommentService } from "./GitHubCommentService.js";
3
5
  export { GitHubEventTransport } from "./GitHubEventTransport.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,iBAAiB,EACjB,qBAAqB,EACrB,0BAA0B,EAC1B,iBAAiB,EACjB,4BAA4B,GAC5B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,iCAAiC,EACjC,0BAA0B,EAC1B,YAAY,GACZ,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACX,aAAa,EACb,0BAA0B,EAC1B,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,yBAAyB,EACzB,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACpB,qCAAqC,EACrC,8BAA8B,EAC9B,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,EACN,YAAY,EACZ,sBAAsB,GACtB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACX,iBAAiB,EACjB,qBAAqB,EACrB,0BAA0B,EAC1B,iBAAiB,EACjB,4BAA4B,GAC5B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,iCAAiC,EACjC,0BAA0B,EAC1B,YAAY,GACZ,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACX,aAAa,EACb,0BAA0B,EAC1B,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,yBAAyB,EACzB,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACpB,qCAAqC,EACrC,8BAA8B,EAC9B,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { createAppJwt, GitHubAppTokenProvider, } from "./GitHubAppTokenProvider.js";
1
2
  export { GitHubCommentService } from "./GitHubCommentService.js";
2
3
  export { GitHubEventTransport } from "./GitHubEventTransport.js";
3
4
  export { GitHubMessageTranslator } from "./GitHubMessageTranslator.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,iCAAiC,EACjC,0BAA0B,EAC1B,YAAY,GACZ,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,YAAY,EACZ,sBAAsB,GACtB,MAAM,6BAA6B,CAAC;AAQrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,iCAAiC,EACjC,0BAA0B,EAC1B,YAAY,GACZ,MAAM,2BAA2B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyrus-github-event-transport",
3
- "version": "0.2.39",
3
+ "version": "0.2.40",
4
4
  "description": "GitHub event transport for receiving and verifying forwarded GitHub webhooks",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,7 +10,7 @@
10
10
  ],
11
11
  "dependencies": {
12
12
  "fastify": "^5.8.3",
13
- "cyrus-core": "0.2.39"
13
+ "cyrus-core": "0.2.40"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/node": "^20.0.0",