diff --git a/.env.example b/.env.example index 6f2df3d..761cb66 100644 --- a/.env.example +++ b/.env.example @@ -31,4 +31,7 @@ SMTP_USER=smtpUser SMTP_PASSWORD=smtpPassword # GitHub Webhook Secret -GITHUB_WEBHOOK_SECRET= \ No newline at end of file +GITHUB_WEBHOOK_SECRET= + +# GitHub App Private Key [.pem] (enclose in double quotes to preserve newlines) +GITHUB_APP_PRIVATE_KEY= diff --git a/README.md b/README.md index c463ee5..abf86de 100644 --- a/README.md +++ b/README.md @@ -1 +1,47 @@ -oss.gg 🕹️ +# oss.gg 🕹️ + +## Run Locally + +1. Clone the project + +```bash + git clone https://github.com/formbricks/oss.gg.git + cd oss.gg +``` + +2. Install dependencies + +```bash + pnpm install +``` + +3. Copy `.env.example` to `.env` and fill in the required environment variables + +```bash + cp .env.example .env +``` + +> The Github Env Vars (incl the webhook secret) can be accessed from your GitHub App Settings + +4. Start the server + +```bash + pnpm dev +``` + +5. Run the Webhook Proxy + +```bash + smee --url https://smee.io/ --path /api/github-webhook --port 3000 +``` + +## GitHub App Configuration + +- Callback URL: `http://localhost:3000/api/auth/callback` +- Setup URL: `http://localhost:3000/select-repo` (Check the **Redirect on Update** option) +- Webhook set to Active and get a URL from `https://smee.io/` by clicking on **Start a new channel** and then paste the URL in the Webhook URL field. +- Disable SSL verification for now +- Generate a Client Secret and keep it in the `.env` file +- Generate a Private Key and keep it in the `.env` file +- Copy the Client ID and keep it in the `.env` file +- Now Hit the **Save Changes** button \ No newline at end of file diff --git a/lib/constants.ts b/lib/constants.ts index 6c9765b..91e8159 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -20,3 +20,5 @@ export enum EVENT_TRIGGERS { export const ON_NEW_ISSUE = "Thanks for opening an issue! It's live on oss.gg!"; export const ON_REPO_NOT_REGISTERED = `This repository is not registered with oss.gg. Please register it at https://oss.gg.`; export const GITHUB_APP_APP_ID = env.GITHUB_APP_APP_ID as string; +export const GITHUB_APP_PRIVATE_KEY = env.GITHUB_APP_PRIVATE_KEY as string; +export const GITHUB_WEBHOOK_SECRET = env.GITHUB_WEBHOOK_SECRET as string; \ No newline at end of file diff --git a/lib/github/index.ts b/lib/github/index.ts index 4986314..3e2a5f5 100644 --- a/lib/github/index.ts +++ b/lib/github/index.ts @@ -1,11 +1,11 @@ -import { env } from "@/env.mjs"; import { Webhooks, createNodeMiddleware } from "@octokit/webhooks"; import { onInstallationCreated } from "./hooks/installation"; import { onAssignCommented, onIssueOpened, onUnassignCommented } from "./hooks/issue"; +import { GITHUB_WEBHOOK_SECRET } from "../constants"; const webhooks = new Webhooks({ - secret: env.GITHUB_WEBHOOK_SECRET as string, + secret: GITHUB_WEBHOOK_SECRET, }); export const webhookMiddleware = createNodeMiddleware(webhooks, { diff --git a/lib/github/services/user.ts b/lib/github/services/user.ts index 67521ad..4bf80ce 100644 --- a/lib/github/services/user.ts +++ b/lib/github/services/user.ts @@ -1,12 +1,6 @@ -import { env } from "@/env.mjs"; +import { GITHUB_APP_PRIVATE_KEY, GITHUB_WEBHOOK_SECRET } from "@/lib/constants"; import { db } from "@/lib/db"; -import { readFileSync } from "fs"; import { App } from "octokit"; -import path from "path"; - -const privateKeyPath = "@/key.pem"; -const resolvedPath = path.resolve(__dirname, privateKeyPath); -const privateKey = readFileSync(resolvedPath, "utf8"); export const sendInstallationDetails = async ( installationId: number, @@ -25,9 +19,9 @@ export const sendInstallationDetails = async ( try { const app = new App({ appId, - privateKey, + privateKey: GITHUB_APP_PRIVATE_KEY, webhooks: { - secret: env.GITHUB_WEBHOOK_SECRET!, + secret: GITHUB_WEBHOOK_SECRET!, }, }); const octokit = await app.getInstallationOctokit(installationId); diff --git a/lib/github/utils.ts b/lib/github/utils.ts index 80baf06..014dd2c 100644 --- a/lib/github/utils.ts +++ b/lib/github/utils.ts @@ -1,13 +1,8 @@ import { createAppAuth } from "@octokit/auth-app"; import { Octokit } from "@octokit/rest"; -import { readFileSync } from "fs"; -import path from "path"; -import { GITHUB_APP_APP_ID } from "../constants"; +import { GITHUB_APP_APP_ID, GITHUB_APP_PRIVATE_KEY } from "../constants"; -const privateKeyPath = "@/key.pem"; -const resolvedPath = path.resolve(__dirname, privateKeyPath); -const privateKey = readFileSync(resolvedPath, "utf8"); export const getOctokitInstance = (installationId: number) => { if (!installationId) { @@ -18,7 +13,7 @@ export const getOctokitInstance = (installationId: number) => { authStrategy: createAppAuth, auth: { appId: GITHUB_APP_APP_ID!, - privateKey, + privateKey:GITHUB_APP_PRIVATE_KEY!, installationId, }, });