feat(template-helpers): Add more parameters to jwt helper

- jwt without parameter now generate a real jwt
- keep length parameter as is for backward compatibility
- add secret and payload parameters
- payload properties iss, iat, exp are automaticly set if not provided
This commit is contained in:
Jonathan Gotti
2025-04-21 16:00:16 +02:00
parent bc17991580
commit 11b9cee73d
2 changed files with 69 additions and 10 deletions
+42 -5
View File
@@ -1,4 +1,4 @@
import { randomBytes } from "node:crypto";
import { randomBytes, createHmac } from "node:crypto";
import { existsSync } from "node:fs";
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
@@ -9,7 +9,7 @@ import { fetchTemplateFiles } from "./github";
export interface Schema {
serverIp: string;
projectName: string;
}
};
export type DomainSchema = Pick<Domain, "host" | "port" | "serviceName"> & {
path?: string;
@@ -22,6 +22,12 @@ export interface Template {
content: string;
}>;
domains: DomainSchema[];
};
export interface GenerateJWTOptions {
length?: number;
secret?: string;
payload?: Record<string, unknown> | undefined;
}
export const generateRandomDomain = ({
@@ -59,10 +65,41 @@ export const generatePassword = (quantity = 16): string => {
*/
export function generateBase64(bytes = 32): string {
return randomBytes(bytes).toString("base64");
}
};
export function generateJwt(length = 256): string {
return randomBytes(length).toString("hex");
function safeBase64(str: string): string {
return str
.replace(/=/g, "")
.replace(/\+/g, "-")
.replace(/\//g, "_");
};
function objToJWTBase64(obj: any): string {
return safeBase64(Buffer.from(JSON.stringify(obj), "utf8").toString("base64"));
};
export function generateJwt(options: GenerateJWTOptions = {}): string {
let { length, secret, payload = {} } = options;
if (length) {
return randomBytes(length).toString("hex");
}
const encodedHeader = objToJWTBase64({
alg: "HS256",
typ: "JWT",
});
payload.iss || (payload.iss = "dokploy");
payload.iat || (payload.iat = Math.floor(Date.now() / 1000));
payload.exp || (payload.exp = Math.floor(new Date("2030-01-01T00:00:00Z").getTime() / 1000));
const encodedPayload = objToJWTBase64({
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(new Date("2030-01-01T00:00:00Z").getTime() / 1000),
...payload,
});
secret || (secret = randomBytes(32).toString("hex"));
const signature = safeBase64(createHmac("SHA256", secret)
.update(`${encodedHeader}.${encodedPayload}`)
.digest("base64"));
return `${encodedHeader}.${encodedPayload}.${signature}`;
}
/**