import { KJUR } from 'jsrsasign' import { ChangeEvent, useState } from 'react' import { Button, CodeBlock, Input, Select } from 'ui' const JWT_HEADER = { alg: 'HS256', typ: 'JWT' } 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 anonToken = { role: 'anon', iss: 'supabase', iat: Math.floor(today.valueOf() / 1000), exp: Math.floor(fiveYears.valueOf() / 1000), } const serviceToken = { role: 'service_role', iss: 'supabase', iat: Math.floor(today.valueOf() / 1000), exp: Math.floor(fiveYears.valueOf() / 1000), } const generateRandomString = (length: number) => { const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' let result = '' /** * The number of possible Uint8 integers is 256. Since the length of `CHARS` * doesn't fit exactly into 256, simply taking the modulus would create an * uneven distribution that favors the earlier characters. To make a truly * uniform distribution, we have to discard everything above the last full * cycle, and pick again. * * The minus 1 is to account for 0-indexing. */ 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] /** * Keep picking until we get a number in the valid range. */ } while (randomNumber > MAX) result += CHARS[randomNumber % CHARS.length] } return result } export default function JwtGenerator() { const secret = generateRandomString(40) const [jwtSecret, setJwtSecret] = useState(secret) const [token, setToken] = useState(anonToken) const [signedToken, setSignedToken] = useState('') const [err, setErr] = useState('') const handleKeySelection = (e: ChangeEvent) => { const val = e.target.value if (val == 'service') setToken(serviceToken) else setToken(anonToken) } const handleClaimsChange = (e: ChangeEvent) => { try { const newTok = JSON.parse(e.target.value) setToken(newTok) setErr('') } catch (err) { const errMessage = !!err && typeof err === 'object' && 'message' in err && typeof err.message === 'string' ? err.message : '' setErr('Not a valid JSON body' + (errMessage ? `: ${errMessage}` : '')) } } const generate = () => { const signedJWT = KJUR.jws.JWS.sign(null, JWT_HEADER, token, jwtSecret) setSignedToken(signedJWT) } return (
setJwtSecret(e.target.value)} />
{err && ( Input must be valid JSON. {err} )}
{signedToken && (

Generated Token:

{signedToken}
)}
) }