Skip to content

Commit 0c3d972

Browse files
authored
refactor(auth): replace github-app-oauth with classic oauth app (#33)
This Pull request refactors the authentication system, replacing the usage of `github-app-oauth` with classic github `oauth` app. This decision was taken because of the limitations discovered using the Pull Request endpoint (implementation in #25); the `github-app-oauth` uses `permissions` which requires a user to have `write` access to the `upstream` (i.e. `write` access to atleast `pull-requests` on our/this project repo) before a pull request can created from their forked repo branch to the main project repo. This PR goes to implement classis `oauth` app, which uses `scopes` and allows user access to create the pull request to `upstream` repo on the `public_repo` scope. The changes made in this PR was done to mimic the normal `Octokit.App`'s methods/apis as close as possible to allow compatibility with the implementation in #8 and #28 (or for cases when we revert back to using the `github-app-oauth` in the future --- _maybe we end up finding a solution because honestly I really prefer the `github-app-oauth`_ 😉). It is also important to state that this `oauth` app option doesn't offer a short lived token (hence we only have an `accessToken` without expiry and No `refreshToken`), but I have configured the token to expire out of cookie in 8hours; even though we might be getting exactly thesame token back from github after this expires and we re-authorize the flow, I just kinda like that feeling of the cookies expiring after some hours and asking user to re-auth. ### Changes Made - Initialized a new `app` object that returns few methods and objects - `octokit` - the main octokit instance of the `oauth` app ```js /** * OAuth App's Octokit instance */ const octokit = new Octokit({ authStrategy: createOAuthAppAuth, auth: { clientId: import.meta.env.GITHUB_OAUTH_APP_CLIENT_ID, clientSecret: import.meta.env.GITHUB_OAUTH_APP_CLIENT_SECRET }, }); ``` - `oauth` - `getWebFlowAuthorizationUrl` - method that generates the oauth flow url ```js /** * Generate a Web Flow/OAuth authorization url to start an OAuth flow * @param {import("@octokit/oauth-authorization-url").OAuthAppOptions} options * @returns */ function getWebFlowAuthorizationUrl({state, scopes = ["public_repo"], ...options }) { return oauthAuthorizationUrl({ clientId: import.meta.env.GITHUB_OAUTH_APP_CLIENT_ID, state, scopes, ...options }); } ``` - `exchangeWebFlowCode` - method that exchanges oauth web flow returned `code` for `accessToken`; this functionality was extracted from the `github/oauth/authorize` endpoint to have all auth related function packed in one place ```js /** * Exchange Web Flow Authorization `code` for an `access_token` * @param {string} code * @returns {Promise<{access_token: string, scope: string, token_type: string}>} */ async function exchangeWebFlowCode(code) { const queryParams = new URLSearchParams(); queryParams.append("code", code); queryParams.append("client_id", import.meta.env.GITHUB_OAUTH_APP_CLIENT_ID); queryParams.append("client_secret", import.meta.env.GITHUB_OAUTH_APP_CLIENT_SECRET); const response = await fetch("https://github.com/login/oauth/access_token", { method: "POST", body: queryParams }); const responseText = await response.text(); const responseData = new URLSearchParams(responseText); return responseData; } ``` - `getUserOctokit` - method that gets an octokit instance of a user. ```js /** * Get a User's Octokit instance * @param {Omit<OctokitOptions, "auth"> & { token: string }} options * @returns {Octokit} */ function getUserOctokit({ token, ...options }) { return new Octokit({ auth: token, ...options }); }; ``` - Integrated the `app.oauth.exchangeWebFlowCode` method into the `github/oauth/authorize` endpoint handler - Removed the `refreshToken` and `refreshTokenExpiresIn` from `github/oauth/authorize` endpoint response object. - Modified `doAuth` actions - Removed `jargons.dev:refresh_token` value set to cookie; - Corrected computation of `userOctokit` to use `app.getUserOctokit` from `app.oauth.getUserOctokit` (even though I could just move the `getUserOctokit` method to the `app.oauth` object in the new implmentation, I just prefer it this way 😉). 📖 ### Screencast [screencast-bpconcjcammlapcogcnnelfmaeghhagj-2024.04.07-07_37_31.webm](https://github.com/babblebey/jargons.dev/assets/25631971/ef976b05-8ebd-4cca-a3b3-9943d9e5273d)
1 parent 7221ced commit 0c3d972

6 files changed

Lines changed: 410 additions & 68 deletions

File tree

.env.example

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# Create a GitHub App at https://github.com/settings/apps/new
2-
GITHUB_APP_ID=
3-
GITHUB_APP_CLIENT_ID=""
4-
GITHUB_APP_CLIENT_SECRET=""
5-
# IMPORTANT: private keys must be in PKCS#8 format, see https://github.com/gr2m/universal-github-app-jwt/#about-private-key-formats
6-
GITHUB_APP_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMII...und==\n-----END PRIVATE KEY-----\n"
2+
GITHUB_OAUTH_APP_CLIENT_ID=""
3+
GITHUB_OAUTH_APP_CLIENT_SECRET=""
74

85
CRYPTO_SECRET_KEY="secret"
96

0 commit comments

Comments
 (0)