From e0a8d8258c517e46ef143b68bcc64178403712f8 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:55:27 -0600 Subject: [PATCH 1/3] fix(git): remove old references to ssh files to use the tmp file --- packages/server/src/utils/providers/git.ts | 80 +++++++++++++++++++--- 1 file changed, 69 insertions(+), 11 deletions(-) diff --git a/packages/server/src/utils/providers/git.ts b/packages/server/src/utils/providers/git.ts index 43173c7d..4553ffe6 100644 --- a/packages/server/src/utils/providers/git.ts +++ b/packages/server/src/utils/providers/git.ts @@ -2,7 +2,7 @@ import { createWriteStream } from "node:fs"; import path, { join } from "node:path"; import { paths } from "@/server/constants"; import type { Compose } from "@/server/services/compose"; -import { updateSSHKeyById } from "@/server/services/ssh-key"; +import { findSSHKeyById, updateSSHKeyById } from "@/server/services/ssh-key"; import { TRPCError } from "@trpc/server"; import { recreateDirectory } from "../filesystem/directory"; import { execAsync, execAsyncRemote } from "../process/execAsync"; @@ -29,13 +29,29 @@ export const cloneGitRepository = async ( } const writeStream = createWriteStream(logPath, { flags: "a" }); - const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`); + const temporalKeyPath = path.join("/tmp", "id_rsa"); + + if (customGitSSHKeyId) { + const sshKey = await findSSHKeyById(customGitSSHKeyId); + + await execAsync(` + echo "${sshKey.privateKey}" > ${temporalKeyPath} + chmod 600 ${temporalKeyPath} + `); + } const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH; const outputPath = join(basePath, appName, "code"); const knownHostsPath = path.join(SSH_PATH, "known_hosts"); try { if (!isHttpOrHttps(customGitUrl)) { + if (!customGitSSHKeyId) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: + "Error: you are trying to clone a ssh repository without a ssh key, please set a ssh key", + }); + } await addHostToKnownHosts(customGitUrl); } await recreateDirectory(outputPath); @@ -74,7 +90,7 @@ export const cloneGitRepository = async ( env: { ...process.env, ...(customGitSSHKeyId && { - GIT_SSH_COMMAND: `ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}`, + GIT_SSH_COMMAND: `ssh -i ${temporalKeyPath} -o UserKnownHostsFile=${knownHostsPath}`, }), }, }, @@ -122,7 +138,6 @@ export const getCustomGitCloneCommand = async ( }); } - const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`); const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH; const outputPath = join(basePath, appName, "code"); const knownHostsPath = path.join(SSH_PATH, "known_hosts"); @@ -136,6 +151,13 @@ export const getCustomGitCloneCommand = async ( try { const command = []; if (!isHttpOrHttps(customGitUrl)) { + if (!customGitSSHKeyId) { + command.push( + `echo "Error: you are trying to clone a ssh repository without a ssh key, please set a ssh key ❌" >> ${logPath}; + exit 1; + `, + ); + } command.push(addHostToKnownHostsCommand(customGitUrl)); } command.push(`rm -rf ${outputPath};`); @@ -144,8 +166,14 @@ export const getCustomGitCloneCommand = async ( `echo "Cloning Custom Git ${customGitUrl}" to ${outputPath}: ✅ >> ${logPath};`, ); if (customGitSSHKeyId) { + const sshKey = await findSSHKeyById(customGitSSHKeyId); + const gitSshCommand = `ssh -i /tmp/id_rsa -o UserKnownHostsFile=${knownHostsPath}`; command.push( - `GIT_SSH_COMMAND="ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}"`, + ` + echo "${sshKey.privateKey}" > /tmp/id_rsa + chmod 600 /tmp/id_rsa + export GIT_SSH_COMMAND="${gitSshCommand}" + `, ); } @@ -184,7 +212,7 @@ const addHostToKnownHosts = async (repositoryURL: string) => { }; const addHostToKnownHostsCommand = (repositoryURL: string) => { - const { SSH_PATH } = paths(); + const { SSH_PATH } = paths(true); const { domain, port } = sanitizeRepoPathSSH(repositoryURL); const knownHostsPath = path.join(SSH_PATH, "known_hosts"); @@ -242,13 +270,31 @@ export const cloneGitRawRepository = async (entity: { } const { SSH_PATH, COMPOSE_PATH } = paths(); - const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`); + const temporalKeyPath = path.join("/tmp", "id_rsa"); const basePath = COMPOSE_PATH; const outputPath = join(basePath, appName, "code"); const knownHostsPath = path.join(SSH_PATH, "known_hosts"); + if (customGitSSHKeyId) { + const sshKey = await findSSHKeyById(customGitSSHKeyId); + + await execAsync(` + echo "${sshKey.privateKey}" > ${temporalKeyPath} + chmod 600 ${temporalKeyPath} + `); + } + try { - await addHostToKnownHosts(customGitUrl); + if (!isHttpOrHttps(customGitUrl)) { + if (!customGitSSHKeyId) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: + "Error: you are trying to clone a ssh repository without a ssh key, please set a ssh key", + }); + } + await addHostToKnownHosts(customGitUrl); + } await recreateDirectory(outputPath); if (customGitSSHKeyId) { @@ -275,7 +321,7 @@ export const cloneGitRawRepository = async (entity: { env: { ...process.env, ...(customGitSSHKeyId && { - GIT_SSH_COMMAND: `ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}`, + GIT_SSH_COMMAND: `ssh -i ${temporalKeyPath} -o UserKnownHostsFile=${knownHostsPath}`, }), }, }, @@ -308,7 +354,6 @@ export const cloneRawGitRepositoryRemote = async (compose: Compose) => { } const { SSH_PATH, COMPOSE_PATH } = paths(true); - const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`); const basePath = COMPOSE_PATH; const outputPath = join(basePath, appName, "code"); const knownHostsPath = path.join(SSH_PATH, "known_hosts"); @@ -322,13 +367,26 @@ export const cloneRawGitRepositoryRemote = async (compose: Compose) => { try { const command = []; if (!isHttpOrHttps(customGitUrl)) { + if (!customGitSSHKeyId) { + command.push( + `echo "Error: you are trying to clone a ssh repository without a ssh key, please set a ssh key ❌" ; + exit 1; + `, + ); + } command.push(addHostToKnownHostsCommand(customGitUrl)); } command.push(`rm -rf ${outputPath};`); command.push(`mkdir -p ${outputPath};`); if (customGitSSHKeyId) { + const sshKey = await findSSHKeyById(customGitSSHKeyId); + const gitSshCommand = `ssh -i /tmp/id_rsa -o UserKnownHostsFile=${knownHostsPath}`; command.push( - `GIT_SSH_COMMAND="ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}"`, + ` + echo "${sshKey.privateKey}" > /tmp/id_rsa + chmod 600 /tmp/id_rsa + export GIT_SSH_COMMAND="${gitSshCommand}" + `, ); } From 8536945a606178ca715635fb176c6393bf09e26c Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:58:51 -0600 Subject: [PATCH 2/3] styles: lint --- apps/dokploy/setup.ts | 8 ++-- apps/website/app/[locale]/layout.tsx | 4 +- apps/website/components/pricing.tsx | 12 ++--- apps/website/components/ui/switch.tsx | 46 +++++++++---------- .../server/src/utils/access-log/handler.ts | 2 +- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/apps/dokploy/setup.ts b/apps/dokploy/setup.ts index cb3f5eec..d22eba4c 100644 --- a/apps/dokploy/setup.ts +++ b/apps/dokploy/setup.ts @@ -1,17 +1,17 @@ import { createDefaultMiddlewares, - createDefaultTraefikConfig, createDefaultServerTraefikConfig, + createDefaultTraefikConfig, initializeTraefik, } from "@dokploy/server/dist/setup/traefik-setup"; +import { setupDirectories } from "@dokploy/server/dist/setup/config-paths"; +import { initializePostgres } from "@dokploy/server/dist/setup/postgres-setup"; +import { initializeRedis } from "@dokploy/server/dist/setup/redis-setup"; import { initializeNetwork, initializeSwarm, } from "@dokploy/server/dist/setup/setup"; -import { setupDirectories } from "@dokploy/server/dist/setup/config-paths"; -import { initializePostgres } from "@dokploy/server/dist/setup/postgres-setup"; -import { initializeRedis } from "@dokploy/server/dist/setup/redis-setup"; (async () => { try { setupDirectories(); diff --git a/apps/website/app/[locale]/layout.tsx b/apps/website/app/[locale]/layout.tsx index 65e4ba49..04f359e5 100644 --- a/apps/website/app/[locale]/layout.tsx +++ b/apps/website/app/[locale]/layout.tsx @@ -6,9 +6,9 @@ import GoogleAnalytics from "@/components/analitycs/google"; import { NextIntlClientProvider } from "next-intl"; import { getMessages } from "next-intl/server"; -import type { Metadata } from "next"; -import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; +import { Header } from "@/components/Header"; +import type { Metadata } from "next"; export const metadata: Metadata = { title: { diff --git a/apps/website/components/pricing.tsx b/apps/website/components/pricing.tsx index 7526e5be..f1cf5660 100644 --- a/apps/website/components/pricing.tsx +++ b/apps/website/components/pricing.tsx @@ -1,13 +1,13 @@ "use client"; import clsx from "clsx"; -import { Container } from "./Container"; -import { Button } from "./ui/button"; -import { trackGAEvent } from "./analitycs"; -import { Switch } from "./ui/switch"; -import { useState } from "react"; -import { useRouter } from "next/navigation"; import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { Container } from "./Container"; +import { trackGAEvent } from "./analitycs"; +import { Button } from "./ui/button"; +import { Switch } from "./ui/switch"; function SwirlyDoodle(props: React.ComponentPropsWithoutRef<"svg">) { return ( diff --git a/apps/website/components/ui/switch.tsx b/apps/website/components/ui/switch.tsx index bc69cf2d..dc376c6a 100644 --- a/apps/website/components/ui/switch.tsx +++ b/apps/website/components/ui/switch.tsx @@ -1,29 +1,29 @@ -"use client" +"use client"; -import * as React from "react" -import * as SwitchPrimitives from "@radix-ui/react-switch" +import * as SwitchPrimitives from "@radix-ui/react-switch"; +import * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const Switch = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - -)) -Switch.displayName = SwitchPrimitives.Root.displayName + + + +)); +Switch.displayName = SwitchPrimitives.Root.displayName; -export { Switch } +export { Switch }; diff --git a/packages/server/src/utils/access-log/handler.ts b/packages/server/src/utils/access-log/handler.ts index abc6ee3d..db5c7f20 100644 --- a/packages/server/src/utils/access-log/handler.ts +++ b/packages/server/src/utils/access-log/handler.ts @@ -1,8 +1,8 @@ import { IS_CLOUD, paths } from "@/server/constants"; import { updateAdmin } from "@/server/services/admin"; import { type RotatingFileStream, createStream } from "rotating-file-stream"; -import { execAsync } from "../process/execAsync"; import { db } from "../../db"; +import { execAsync } from "../process/execAsync"; class LogRotationManager { private static instance: LogRotationManager; From 60497fe59d77e525515c4441d94090626b3cff72 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Fri, 18 Oct 2024 00:10:01 -0600 Subject: [PATCH 3/3] refactor: add husky --- .husky/commit-msg | 1 + .husky/install.mjs | 6 ++++++ .husky/pre-commit | 2 ++ package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 5 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 .husky/commit-msg create mode 100644 .husky/install.mjs create mode 100644 .husky/pre-commit diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100644 index 00000000..c3c62bfc --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +npx commitlint --edit "$1" \ No newline at end of file diff --git a/.husky/install.mjs b/.husky/install.mjs new file mode 100644 index 00000000..9b13ce1f --- /dev/null +++ b/.husky/install.mjs @@ -0,0 +1,6 @@ +// Skip Husky install in production and CI +if (process.env.NODE_ENV === "production" || process.env.CI === "true") { + process.exit(0); +} +const husky = (await import("husky")).default; +console.log(husky()); diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..fef815e9 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +pnpm run check +git add . \ No newline at end of file diff --git a/package.json b/package.json index 4afa2447..192da5b7 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "format-and-lint": "biome check .", "check": "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true", "format-and-lint:fix": "biome check . --write", - "prepare": "node ./.config/.husky/install.mjs" + "prepare": "node .husky/install.mjs" }, "devDependencies": { "dotenv": "16.4.5", @@ -31,7 +31,7 @@ "tsx": "4.16.2", "lint-staged": "^15.2.7", "@biomejs/biome": "1.8.3", - "husky": "^9.0.11", + "husky": "^9.1.6", "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", "@types/node": "^18.17.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3aa026c5..11189f2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,8 +31,8 @@ importers: specifier: 0.20.2 version: 0.20.2 husky: - specifier: ^9.0.11 - version: 9.1.3 + specifier: ^9.1.6 + version: 9.1.6 lint-staged: specifier: ^15.2.7 version: 15.2.7 @@ -5504,8 +5504,8 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - husky@9.1.3: - resolution: {integrity: sha512-ET3TQmQgdIu0pt+jKkpo5oGyg/4MQZpG6xcam5J5JyNJV+CBT23OBpCF15bKHKycRyMH9k6ONy8g2HdGIsSkMQ==} + husky@9.1.6: + resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==} engines: {node: '>=18'} hasBin: true @@ -13020,7 +13020,7 @@ snapshots: eslint: 8.45.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.45.0) eslint-plugin-react: 7.35.0(eslint@8.45.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.45.0) @@ -13044,7 +13044,7 @@ snapshots: enhanced-resolve: 5.17.1 eslint: 8.45.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.15.0 @@ -13066,7 +13066,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -13816,7 +13816,7 @@ snapshots: human-signals@5.0.0: {} - husky@9.1.3: {} + husky@9.1.6: {} hyperdyperid@1.2.0: {}