Files
supabase/apps/docs/components/JwtGenerator/JwtGeneratorSimple.tsx
Ivan Vasilov ee8eae7309 chore: Clean the ui package from next imports (#44278)
This PR moves several components which rely on `next` out of the `ui`
package to the `ui-patterns` package.

`ui-patterns` package is intented to be imported with specific imports
so it's ok if there are components reliant on `next` in there.

The `SonnerToaster` component has removed its dependency by requiring a
prop for `theme`.
2026-03-30 10:58:37 +02:00

80 lines
2.3 KiB
TypeScript

import { KJUR } from 'jsrsasign'
import { useState } from 'react'
import { Button } from 'ui'
import { CodeBlock } from 'ui-patterns/CodeBlock'
const JWT_HEADER = { alg: 'HS256', typ: 'JWT' }
const generateRandomString = (length: number) => {
const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let result = ''
const MAX = Math.floor(256 / CHARS.length) * CHARS.length - 1
const randomUInt8Array = new Uint8Array(1)
for (let i = 0; i < length; i++) {
let randomNumber: number
do {
crypto.getRandomValues(randomUInt8Array)
randomNumber = randomUInt8Array[0]
} while (randomNumber > MAX)
result += CHARS[randomNumber % CHARS.length]
}
return result
}
const generateKeys = () => {
const now = new Date()
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
const fiveYears = new Date(now.getFullYear() + 5, now.getMonth(), now.getDate())
const iat = Math.floor(today.valueOf() / 1000)
const exp = Math.floor(fiveYears.valueOf() / 1000)
const anonToken = { role: 'anon', iss: 'supabase', iat, exp }
const serviceToken = { role: 'service_role', iss: 'supabase', iat, exp }
const secret = generateRandomString(40)
const anonKey = KJUR.jws.JWS.sign(null, JWT_HEADER, anonToken, secret)
const serviceRoleKey = KJUR.jws.JWS.sign(null, JWT_HEADER, serviceToken, secret)
return { secret, anonKey, serviceRoleKey }
}
export default function JwtGeneratorSimple() {
const [keys, setKeys] = useState(generateKeys)
const regenerate = () => {
setKeys(generateKeys())
}
return (
<div className="border rounded-lg p-4">
<div className="grid mb-8">
<label htmlFor="secret">JWT_SECRET</label>
<CodeBlock language="bash" className="relative font-mono">
{keys.secret}
</CodeBlock>
</div>
<div className="grid mb-8">
<label htmlFor="anon">ANON_KEY</label>
<CodeBlock language="bash" className="relative font-mono">
{keys.anonKey}
</CodeBlock>
</div>
<div className="grid mb-8">
<label htmlFor="service">SERVICE_ROLE_KEY</label>
<CodeBlock language="bash" className="relative font-mono">
{keys.serviceRoleKey}
</CodeBlock>
</div>
<Button type="primary" onClick={regenerate}>
Generate new
</Button>
</div>
)
}