From 5e5cbdeef9eb8d782ca6ccc4d1eebe38ad79e9b7 Mon Sep 17 00:00:00 2001 From: songtianlun Date: Sat, 24 Aug 2024 00:37:19 +0800 Subject: [PATCH] fix: supabase generate annon and service jwt by servicekey --- apps/dokploy/templates/supabase/index.ts | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/apps/dokploy/templates/supabase/index.ts b/apps/dokploy/templates/supabase/index.ts index f972fbd1..7ae96d70 100644 --- a/apps/dokploy/templates/supabase/index.ts +++ b/apps/dokploy/templates/supabase/index.ts @@ -1,3 +1,4 @@ +import { createHmac, randomBytes } from "node:crypto"; import { type Schema, type Template, @@ -7,6 +8,58 @@ import { generateRandomDomain, } from "../utils"; +interface JWTPayload { + role: "anon" | "service_role"; + iss: string; + iat: number; + exp: number; +} + +function base64UrlEncode(str: string): string { + return Buffer.from(str) + .toString("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=/g, ""); +} + +function generateJWT(payload: JWTPayload, secret: string): string { + const header = { alg: "HS256", typ: "JWT" }; + + const encodedHeader = base64UrlEncode(JSON.stringify(header)); + const encodedPayload = base64UrlEncode(JSON.stringify(payload)); + + const signature = createHmac("sha256", secret) + .update(`${encodedHeader}.${encodedPayload}`) + .digest("base64url"); + + return `${encodedHeader}.${encodedPayload}.${signature}`; +} + +export function generateSupabaseAnonJWT(secret: string): string { + const now = Math.floor(Date.now() / 1000); + const payload: JWTPayload = { + role: "anon", + iss: "supabase", + iat: now, + exp: now + 100 * 365 * 24 * 60 * 60, // 100 years + }; + + return generateJWT(payload, secret); +} + +export function generateSupabaseServiceJWT(secret: string): string { + const now = Math.floor(Date.now() / 1000); + const payload: JWTPayload = { + role: "service_role", + iss: "supabase", + iat: now, + exp: now + 100 * 365 * 24 * 60 * 60, // 100 years + }; + + return generateJWT(payload, secret); +} + export function generate(schema: Schema): Template { const mainServiceHash = generateHash(schema.projectName); const randomDomain = generateRandomDomain(schema); @@ -16,6 +69,9 @@ export function generate(schema: Schema): Template { const dashboardPassword = generatePassword(32); const logflareApiKey = generatePassword(32); + const annonKey = generateSupabaseAnonJWT(jwtSecret); + const serviceRoleKey = generateSupabaseServiceJWT(jwtSecret); + const envs = [ `SUPABASE_HOST=${randomDomain}`, `POSTGRES_PASSWORD=${postgresPassword}`,