Something went wrong. Try again.
mirror your GitHub repos to tangled.org automatically
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556import { installationAccountLogin, userAdministersInstallation, userOctokitFromCode } from '#server/utils/github-app'import { markInstallOwned } from '#server/utils/install-ownership'import { sessionConfig } from '#server/utils/server-session'
interface OAuthFlowData { state: string installationId: number}
/** * GitHub user-OAuth callback. Verifies the `state` against the sealed flow * cookie, exchanges the code for a user token, and confirms the user * administers the installation. On success, marks the install owned (a sealed * cookie the atproto callback checks before binding) and sends the user into * the tangled connect flow. */export default defineEventHandler(async event => { const query = getQuery(event) const code = typeof query.code === 'string' ? query.code : null const state = typeof query.state === 'string' ? query.state : null if (!code || !state) { throw createError({ statusCode: 400, statusMessage: 'missing code or state' }) }
const flow = await useSession<OAuthFlowData>(event, { ...sessionConfig(), name: 'synchub-gh-oauth', maxAge: 10 * 60, }) const expectedState = flow.data.state const installationId = flow.data.installationId await flow.clear()
if (!expectedState || expectedState !== state || typeof installationId !== 'number') { throw createError({ statusCode: 400, statusMessage: 'invalid or expired oauth state' }) }
const userOctokit = await userOctokitFromCode(code) const administers = await userAdministersInstallation(userOctokit, installationId) if (!administers) { throw createError({ statusCode: 403, statusMessage: 'your GitHub account does not administer this installation', }) }
await markInstallOwned(event, installationId)
// Ownership proven. Hand off to the connect page, which now lets the user // pick the tangled handle to bind. Carry the account login for display. const login = await installationAccountLogin(installationId) const params = new URLSearchParams({ installation_id: String(installationId), verified: '1' }) if (login) params.set('login', login) await sendRedirect(event, `/connect?${params.toString()}`, 302)})