refactor: replace `github-app.ts` with `@github/app`

This commit is contained in:
Gregor 2019-01-20 14:58:47 -08:00
parent 0821b969f3
commit 3f8a50a993
5 changed files with 52 additions and 51 deletions

15
src/@types/@octokit/app/index.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
declare module '@octokit/app' {
interface Options {
id: number,
privateKey: string
}
declare class App {
constructor (options: Options)
public getSignedJsonWebToken(): string
public getInstallationAccessToken({installationId: number}): Promise<string>
}
export = App
}

View File

@ -1,3 +1,4 @@
import OctokitApp from '@octokit/app'
import { WebhookEvent } from '@octokit/webhooks' import { WebhookEvent } from '@octokit/webhooks'
import express from 'express' import express from 'express'
import { EventEmitter } from 'promise-events' import { EventEmitter } from 'promise-events'
@ -9,7 +10,7 @@ import { logger } from './logger'
import { LoggerWithTarget, wrapLogger } from './wrap-logger' import { LoggerWithTarget, wrapLogger } from './wrap-logger'
export interface Options { export interface Options {
app: () => string app: OctokitApp
cache: Cache cache: Cache
router?: express.Router router?: express.Router
catchErrors?: boolean catchErrors?: boolean
@ -29,7 +30,7 @@ function isUnauthenticatedEvent (event: WebhookEvent) {
*/ */
export class Application { export class Application {
public events: EventEmitter public events: EventEmitter
public app: () => string public app: OctokitApp
public cache: Cache public cache: Cache
public router: express.Router public router: express.Router
public log: LoggerWithTarget public log: LoggerWithTarget
@ -198,18 +199,15 @@ export class Application {
const installationTokenTTL = parseInt(process.env.INSTALLATION_TOKEN_TTL || '3540', 10) const installationTokenTTL = parseInt(process.env.INSTALLATION_TOKEN_TTL || '3540', 10)
return this.cache.wrap(`app:${id}`, async () => { return this.cache.wrap(`app:${id}`, async () => {
const installation = GitHubAPI({ return GitHubAPI({
auth: async () => {
const accessToken = await this.app.getInstallationAccessToken({ installationId: id })
return `token ${accessToken}`
},
baseUrl: process.env.GHE_HOST && `https://${process.env.GHE_HOST}/api/v3`, baseUrl: process.env.GHE_HOST && `https://${process.env.GHE_HOST}/api/v3`,
debug: process.env.LOG_LEVEL === 'trace', debug: process.env.LOG_LEVEL === 'trace',
logger: log.child({ name: 'github', installation: String(id) }) logger: log.child({ name: 'github', installation: String(id) })
}) })
log.trace(`creating token for installation`)
installation.authenticate({ type: 'app', token: this.app() })
const response = await installation.apps.createInstallationToken({ installation_id: id })
installation.authenticate({ type: 'token', token: response.data.token })
return installation
}, { ttl: installationTokenTTL }) }, { ttl: installationTokenTTL })
} }
@ -220,7 +218,7 @@ export class Application {
}) })
github.authenticate({ github.authenticate({
token: this.githubToken ? this.githubToken : this.app(), token: this.githubToken ? this.githubToken : this.app.getSignedJsonWebToken(),
type: 'app' type: 'app'
}) })

View File

@ -1,19 +0,0 @@
import jwt from 'jsonwebtoken'
export const createApp = (options: AppOptions) => {
return () => {
const payload = {
exp: Math.floor(Date.now() / 1000) + 60, // JWT expiration time
iat: Math.floor(Date.now() / 1000), // Issued at time
iss: options.id // GitHub App ID
}
// Sign with RSA SHA256
return jwt.sign(payload, options.cert, { algorithm: 'RS256' })
}
}
export interface AppOptions {
id: number
cert: string
}

View File

@ -1,10 +1,11 @@
import OctokitApp from '@octokit/app'
import Webhooks, { WebhookEvent } from '@octokit/webhooks' import Webhooks, { WebhookEvent } from '@octokit/webhooks'
import Logger from 'bunyan' import Logger from 'bunyan'
import express from 'express' import express from 'express'
import { Application } from './application' import { Application } from './application'
import { createDefaultCache } from './cache' import { createDefaultCache } from './cache'
import { Context } from './context' import { Context } from './context'
import { createApp } from './github-app'
import { logger } from './logger' import { logger } from './logger'
import { resolve } from './resolver' import { resolve } from './resolver'
import { createServer } from './server' import { createServer } from './server'
@ -30,7 +31,7 @@ export class Probot {
private options: Options private options: Options
private apps: Application[] private apps: Application[]
private app: () => string private app?: OctokitApp
private githubToken?: string private githubToken?: string
constructor (options: Options) { constructor (options: Options) {
@ -40,11 +41,12 @@ export class Probot {
this.logger = logger this.logger = logger
this.apps = [] this.apps = []
this.webhook = new Webhooks({ path: options.webhookPath, secret: options.secret }) this.webhook = new Webhooks({ path: options.webhookPath, secret: options.secret })
if (options.githubToken) {
this.githubToken = options.githubToken this.githubToken = options.githubToken
this.app = () => '' if (this.options.id) {
} else { this.app = new OctokitApp({
this.app = createApp({ id: options.id!, cert: options.cert! }) id: options.id as number,
privateKey: options.cert as string
})
} }
this.server = createServer({ webhook: this.webhook.middleware, logger }) this.server = createServer({ webhook: this.webhook.middleware, logger })
@ -81,7 +83,11 @@ export class Probot {
if (typeof appFn === 'string') { if (typeof appFn === 'string') {
appFn = resolve(appFn) as ApplicationFunction appFn = resolve(appFn) as ApplicationFunction
} }
const app = new Application({ app: this.app, cache, githubToken: this.githubToken }) const app = new Application({
app: this.app as OctokitApp,
cache,
githubToken: this.githubToken
})
// Connect the router from the app to the server // Connect the router from the app to the server
this.server.use(app.router) this.server.use(app.router)
@ -131,6 +137,7 @@ export interface Options {
githubToken?: string, githubToken?: string,
webhookProxy?: string, webhookProxy?: string,
port?: number port?: number
} }
export { Logger, Context, Application } export { Logger, Context, Application }