Update JWT schema (#632)

## Description:

- Handle the new `sub` encoding
- Decode the new `rol` claim
- Related to https://github.com/openfrontio/infra/pull/25

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com>
This commit is contained in:
Scott Anderson
2025-05-01 15:22:20 -04:00
committed by GitHub
parent 2476f3e84b
commit b56764ce57
2 changed files with 58 additions and 1 deletions
+21 -1
View File
@@ -1,12 +1,32 @@
import { z } from "zod";
import { base64urlToUuid } from "./Base64";
export const TokenPayloadSchema = z.object({
jti: z.string(),
sub: z.string().uuid(),
sub: z
.string()
.refine(
(val) => {
const uuid = base64urlToUuid(val);
return uuid != null;
},
{
message: "Invalid base64-encoded UUID",
},
)
.transform((val) => {
const uuid = base64urlToUuid(val);
if (!uuid) throw new Error("Invalid base64 UUID");
return uuid;
}),
iat: z.number(),
iss: z.string(),
aud: z.string(),
exp: z.number(),
rol: z
.string()
.optional()
.transform((val) => val.split(",")),
});
export type TokenPayload = z.infer<typeof TokenPayloadSchema>;
+37
View File
@@ -0,0 +1,37 @@
import { base64url } from "jose";
/**
* Converts a UUID string to a base64url-encoded binary representation.
* @param uuid - The UUID string (e.g., '123e4567-e89b-12d3-a456-426614174000')
* @returns base64url string (e.g., 'Ej5FZ+i7EtOkVkJmFBdAAA')
*/
export function uuidToBase64url(uuid: string): string {
const hex = uuid.replace(/-/g, "");
const bytes = new Uint8Array(16);
for (let i = 0; i < 16; i++) {
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
}
return base64url.encode(bytes);
}
/**
* Converts a base64url-encoded binary UUID back to its canonical UUID string.
* @param encoded - base64url string (e.g., 'Ej5FZ+i7EtOkVkJmFBdAAA')
* @returns UUID string (e.g., '123e4567-e89b-12d3-a456-426614174000')
*/
export function base64urlToUuid(encoded: string): string {
const bytes = base64url.decode(encoded);
const hex = Array.from(bytes)
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
return [
hex.slice(0, 8),
hex.slice(8, 12),
hex.slice(12, 16),
hex.slice(16, 20),
hex.slice(20),
].join("-");
}