mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
[autofix.ci] apply automated fixes
This commit is contained in:
parent
e6d0b7b4ee
commit
c3986d7a08
@ -58,10 +58,10 @@ describe("processTemplate", () => {
|
||||
variables: {
|
||||
jwt_secret: "cQsdycq1hDLopQonF6jUTqgQc5WEZTwWLL02J6XJ",
|
||||
anon_payload: JSON.stringify({
|
||||
"role": "tester",
|
||||
"iss": "dockploy",
|
||||
"iat": "${timestamps:2025-01-01T00:00:00Z}",
|
||||
"exp": "${timestamps:2030-01-01T00:00:00Z}",
|
||||
role: "tester",
|
||||
iss: "dockploy",
|
||||
iat: "${timestamps:2025-01-01T00:00:00Z}",
|
||||
exp: "${timestamps:2030-01-01T00:00:00Z}",
|
||||
}),
|
||||
anon_key: "${jwt:jwt_secret:anon_payload}",
|
||||
},
|
||||
@ -74,7 +74,9 @@ describe("processTemplate", () => {
|
||||
};
|
||||
const result = processTemplate(template, mockSchema);
|
||||
expect(result.envs).toHaveLength(1);
|
||||
expect(result.envs).toContain("ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNzM1Njg5NjAwIiwiZXhwIjoiMTg5MzQ1NjAwMCIsInJvbGUiOiJ0ZXN0ZXIiLCJpc3MiOiJkb2NrcGxveSJ9.BG5JoxL2_NaTFbPgyZdm3kRWenf_O3su_HIRKGCJ_kY");
|
||||
expect(result.envs).toContain(
|
||||
"ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNzM1Njg5NjAwIiwiZXhwIjoiMTg5MzQ1NjAwMCIsInJvbGUiOiJ0ZXN0ZXIiLCJpc3MiOiJkb2NrcGxveSJ9.BG5JoxL2_NaTFbPgyZdm3kRWenf_O3su_HIRKGCJ_kY",
|
||||
);
|
||||
expect(result.mounts).toHaveLength(0);
|
||||
expect(result.domains).toHaveLength(0);
|
||||
});
|
||||
|
@ -2,7 +2,6 @@ import type { Schema } from "@dokploy/server/templates";
|
||||
import { processValue } from "@dokploy/server/templates/processors";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
|
||||
describe("helpers functions", () => {
|
||||
// Mock schema for testing
|
||||
const mockSchema: Schema = {
|
||||
@ -30,7 +29,11 @@ describe("helpers functions", () => {
|
||||
it("should generate a random domain", () => {
|
||||
const domain = processValue("${domain}", {}, mockSchema);
|
||||
expect(domain.startsWith(`${mockSchema.projectName}-`)).toBeTruthy();
|
||||
expect(domain.endsWith(`${mockSchema.serverIp.replaceAll(".","-")}.traefik.me`)).toBeTruthy();
|
||||
expect(
|
||||
domain.endsWith(
|
||||
`${mockSchema.serverIp.replaceAll(".", "-")}.traefik.me`,
|
||||
),
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@ -46,11 +49,14 @@ describe("helpers functions", () => {
|
||||
[32, 44],
|
||||
[64, 88],
|
||||
[128, 172],
|
||||
])("should generate a base64 string from parameter %d bytes length", (length, finalLength) => {
|
||||
])(
|
||||
"should generate a base64 string from parameter %d bytes length",
|
||||
(length, finalLength) => {
|
||||
const base64 = processValue(`\${base64:${length}}`, {}, mockSchema);
|
||||
expect(base64).toMatch(/^[A-Za-z0-9+=/]+={0,2}$/);
|
||||
expect(base64.length).toBe(finalLength);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("${password}", () => {
|
||||
@ -58,11 +64,14 @@ describe("helpers functions", () => {
|
||||
const password = processValue("${password}", {}, mockSchema);
|
||||
expect(password).toMatch(/^[A-Za-z0-9]+$/);
|
||||
});
|
||||
it.each([6,8,12,16,32])("should generate a password string respecting parameter %d length", (length) => {
|
||||
it.each([6, 8, 12, 16, 32])(
|
||||
"should generate a password string respecting parameter %d length",
|
||||
(length) => {
|
||||
const password = processValue(`\${password:${length}}`, {}, mockSchema);
|
||||
expect(password).toMatch(/^[A-Za-z0-9]+$/);
|
||||
expect(password.length).toBe(length);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("${hash}", () => {
|
||||
@ -70,17 +79,22 @@ describe("helpers functions", () => {
|
||||
const hash = processValue("${hash}", {}, mockSchema);
|
||||
expect(hash).toMatch(/^[A-Za-z0-9]+$/);
|
||||
});
|
||||
it.each([6,8,12,16,32])("should generate a hash string respecting parameter %d length", (length) => {
|
||||
it.each([6, 8, 12, 16, 32])(
|
||||
"should generate a hash string respecting parameter %d length",
|
||||
(length) => {
|
||||
const hash = processValue(`\${hash:${length}}`, {}, mockSchema);
|
||||
expect(hash).toMatch(/^[A-Za-z0-9]+$/);
|
||||
expect(hash.length).toBe(length);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("${uuid}", () => {
|
||||
it("should generate a UUID string", () => {
|
||||
const uuid = processValue("${uuid}", {}, mockSchema);
|
||||
expect(uuid).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
|
||||
expect(uuid).toMatch(
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -100,8 +114,12 @@ describe("helpers functions", () => {
|
||||
expect(timestamp.length).toBe(nowLength);
|
||||
});
|
||||
it("should generate a timestamp string in milliseconds from parameter", () => {
|
||||
const timestamp = processValue("${timestampms:2025-01-01}", {}, mockSchema);
|
||||
expect(timestamp).toEqual('1735689600000');
|
||||
const timestamp = processValue(
|
||||
"${timestampms:2025-01-01}",
|
||||
{},
|
||||
mockSchema,
|
||||
);
|
||||
expect(timestamp).toEqual("1735689600000");
|
||||
});
|
||||
});
|
||||
describe("${timestamps}", () => {
|
||||
@ -112,8 +130,12 @@ describe("helpers functions", () => {
|
||||
expect(timestamps.length).toBe(nowLength);
|
||||
});
|
||||
it("should generate a timestamp string in seconds from parameter", () => {
|
||||
const timestamps = processValue("${timestamps:2025-01-01}", {}, mockSchema);
|
||||
expect(timestamps).toEqual('1735689600');
|
||||
const timestamps = processValue(
|
||||
"${timestamps:2025-01-01}",
|
||||
{},
|
||||
mockSchema,
|
||||
);
|
||||
expect(timestamps).toEqual("1735689600");
|
||||
});
|
||||
});
|
||||
|
||||
@ -151,16 +173,23 @@ describe("helpers functions", () => {
|
||||
expect(decodedPayload).toHaveProperty("exp");
|
||||
expect(decodedPayload.iss).toEqual("dokploy");
|
||||
});
|
||||
it.each([6,8,12,16,32])("should generate a random hex string from parameter %d byte length", (length) => {
|
||||
it.each([6, 8, 12, 16, 32])(
|
||||
"should generate a random hex string from parameter %d byte length",
|
||||
(length) => {
|
||||
const jwt = processValue(`\${jwt:${length}}`, {}, mockSchema);
|
||||
expect(jwt).toMatch(/^[A-Za-z0-9-_.]+$/);
|
||||
expect(jwt.length).toBeGreaterThanOrEqual(length); // bytes translated to hex can take up to 2x the length
|
||||
expect(jwt.length).toBeLessThanOrEqual(length * 2);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
describe("${jwt:secret}", () => {
|
||||
it("should generate a JWT string respecting parameter secret from variable", () => {
|
||||
const jwt = processValue("${jwt:secret}", {secret: "mysecret"}, mockSchema);
|
||||
const jwt = processValue(
|
||||
"${jwt:secret}",
|
||||
{ secret: "mysecret" },
|
||||
mockSchema,
|
||||
);
|
||||
expect(jwt).toMatch(jwtMatchExp);
|
||||
const parts = jwt.split(".") as JWTParts;
|
||||
const decodedPayload = jwtBase64Decode(parts[1]);
|
||||
@ -175,10 +204,14 @@ describe("helpers functions", () => {
|
||||
it("should generate a JWT string respecting parameters secret and payload from variables", () => {
|
||||
const iat = Math.floor(new Date("2025-01-01T00:00:00Z").getTime() / 1000);
|
||||
const expiry = iat + 3600;
|
||||
const jwt = processValue("${jwt:secret:payload}", {
|
||||
const jwt = processValue(
|
||||
"${jwt:secret:payload}",
|
||||
{
|
||||
secret: "mysecret",
|
||||
payload: `{"iss": "test-issuer", "iat": ${iat}, "exp": ${expiry}, "customprop": "customvalue"}`,
|
||||
}, mockSchema);
|
||||
},
|
||||
mockSchema,
|
||||
);
|
||||
expect(jwt).toMatch(jwtMatchExp);
|
||||
const parts = jwt.split(".") as JWTParts;
|
||||
jwtCheckHeader(parts[0]);
|
||||
@ -191,7 +224,9 @@ describe("helpers functions", () => {
|
||||
expect(decodedPayload.exp).toEqual(expiry);
|
||||
expect(decodedPayload).toHaveProperty("customprop");
|
||||
expect(decodedPayload.customprop).toEqual("customvalue");
|
||||
expect(jwt).toEqual("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MzU2ODk2MDAsImV4cCI6MTczNTY5MzIwMCwiaXNzIjoidGVzdC1pc3N1ZXIiLCJjdXN0b21wcm9wIjoiY3VzdG9tdmFsdWUifQ.m42U7PZSUSCf7gBOJrxJir0rQmyPq4rA59Dydr_QahI")
|
||||
expect(jwt).toEqual(
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MzU2ODk2MDAsImV4cCI6MTczNTY5MzIwMCwiaXNzIjoidGVzdC1pc3N1ZXIiLCJjdXN0b21wcm9wIjoiY3VzdG9tdmFsdWUifQ.m42U7PZSUSCf7gBOJrxJir0rQmyPq4rA59Dydr_QahI",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
@ -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,7 +22,7 @@ export interface Template {
|
||||
content: string;
|
||||
}>;
|
||||
domains: DomainSchema[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface GenerateJWTOptions {
|
||||
length?: number;
|
||||
@ -65,17 +65,16 @@ export const generatePassword = (quantity = 16): string => {
|
||||
*/
|
||||
export function generateBase64(bytes = 32): string {
|
||||
return randomBytes(bytes).toString("base64");
|
||||
};
|
||||
}
|
||||
|
||||
function safeBase64(str: string): string {
|
||||
return str
|
||||
.replace(/=/g, "")
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_");
|
||||
};
|
||||
return str.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
||||
}
|
||||
function objToJWTBase64(obj: any): string {
|
||||
return safeBase64(Buffer.from(JSON.stringify(obj), "utf8").toString("base64"));
|
||||
};
|
||||
return safeBase64(
|
||||
Buffer.from(JSON.stringify(obj), "utf8").toString("base64"),
|
||||
);
|
||||
}
|
||||
|
||||
export function generateJwt(options: GenerateJWTOptions = {}): string {
|
||||
let { length, secret, payload = {} } = options;
|
||||
@ -88,16 +87,21 @@ export function generateJwt(options: GenerateJWTOptions = {}): string {
|
||||
});
|
||||
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));
|
||||
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)
|
||||
const signature = safeBase64(
|
||||
createHmac("SHA256", secret)
|
||||
.update(`${encodedHeader}.${encodedPayload}`)
|
||||
.digest("base64"));
|
||||
.digest("base64"),
|
||||
);
|
||||
|
||||
return `${encodedHeader}.${encodedPayload}.${signature}`;
|
||||
}
|
||||
|
@ -117,7 +117,9 @@ export function processValue(
|
||||
return new Date(varName.slice(12)).getTime().toString();
|
||||
}
|
||||
if (varName.startsWith("timestamps:")) {
|
||||
return Math.round(new Date(varName.slice(11)).getTime() / 1000).toString();
|
||||
return Math.round(
|
||||
new Date(varName.slice(11)).getTime() / 1000,
|
||||
).toString();
|
||||
}
|
||||
|
||||
if (varName === "randomPort") {
|
||||
@ -137,7 +139,11 @@ export function processValue(
|
||||
if (typeof payload === "string" && variables[payload]) {
|
||||
payload = variables[payload];
|
||||
}
|
||||
if (typeof payload === "string" && payload.startsWith("{") && payload.endsWith("}")) {
|
||||
if (
|
||||
typeof payload === "string" &&
|
||||
payload.startsWith("{") &&
|
||||
payload.endsWith("}")
|
||||
) {
|
||||
try {
|
||||
payload = JSON.parse(payload);
|
||||
} catch (e) {
|
||||
@ -146,12 +152,12 @@ export function processValue(
|
||||
console.error("Invalid JWT payload", e);
|
||||
}
|
||||
}
|
||||
if (typeof payload !== 'object') {
|
||||
if (typeof payload !== "object") {
|
||||
payload = undefined;
|
||||
}
|
||||
return generateJwt({
|
||||
secret: secret ? (variables[secret] || secret) : undefined,
|
||||
payload: payload as any
|
||||
secret: secret ? variables[secret] || secret : undefined,
|
||||
payload: payload as any,
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user