Prevent login for people without write access github repo
Hey there,
I've been trying to setup Keystatic with a Github repo. It works great until I want new people to contribute. I understand that people need write access to use Keystatic but why allow people to login at all? Right now, people can login but get a cryptic error when they try to edit anything:
It seems like keystatic cloud handles this, if I try to login to https://keystatic.com/keystatic I get an expected error message:
Could we have something similar for the Github integration?
As a work around, I added some code before loading the keystatic admin using a different access token to verify that the current keystatic logged in user has access to my repo. If not, shows an error. For this, I stopped using the astro integration and just imported the UI and the API endpoints to install them manually, like we used to do before the integration.
---
import { Keystatic } from '@/components/keystatic'
import { Octokit } from '@octokit/core'
import { z } from 'astro:content'
import Layout from '@/layouts/default.astro'
import { ExclamationTriangleIcon } from '@radix-ui/react-icons'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import config from 'keystatic.config'
export const prerender = false
const accessToken = Astro.cookies.get('keystatic-gh-access-token')
let error: { title: string; message: string } | undefined = undefined
if (config.storage.kind === 'github' && accessToken) {
const souls = new Octokit({
auth: import.meta.env.SOULS_PERSONAL_ACCESS_TOKEN,
})
const keystatic = new Octokit({
auth: accessToken.value,
})
try {
const me = await keystatic.request('GET /user', {
headers: {
'X-GitHub-Api-Version': '2022-11-28',
},
})
await souls.request('GET /repos/{owner}/{repo}/collaborators/{username}', {
owner: 'soulsspeedruns',
repo: 'website',
username: me.data.login,
headers: {
'X-GitHub-Api-Version': '2022-11-28',
},
})
} catch (e) {
const result = z.object({ status: z.literal(404) }).safeParse(e)
if (result.success) {
error = {
title: 'Forbidden',
message: `The user is not a verified contributor.`,
}
Astro.response.status = 403
} else {
console.log(e)
throw e
}
}
}
---
{
error ? (
<Layout title="Unauthorized">
<main class="container mx-auto mt-20 grid grid-cols-10">
<div class="col-span-6 col-start-3">
<Alert
variant="destructive"
className="mb-6"
>
<ExclamationTriangleIcon className="h-4 w-4" />
<AlertTitle>{error.title}</AlertTitle>
<AlertDescription>{error.message}</AlertDescription>
</Alert>
<p class="prose max-w-none dark:prose-invert">
Please check <a href="/contribute">how to contribute</a>.
</p>
</div>
</main>
</Layout>
) : (
<Keystatic client:only="react" />
)
}
I had to use a different access token because for some reason I just couldn't get the correct api information using the keystatic token. Not really sure why, not that familiar with github scopes and stuff. Works for now though.
+1