diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c22bde6..445c0da 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -31,4 +31,7 @@ jobs: # Make sure to replace with your own namespace and repository tags: | killercf/sgc:latest - platforms: linux/amd64 \ No newline at end of file + platforms: linux/amd64 + build-args: | + PUBLIC_CONVEX_URL=${{ secrets.PUBLIC_CONVEX_URL }} + PUBLIC_CONVEX_SITE_URL=${{ secrets.PUBLIC_CONVEX_SITE_URL }} \ No newline at end of file diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 32dc0ba..ad0bbb8 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -6,13 +6,9 @@ WORKDIR /app # --- FROM base AS prepare -# Replace with the major version installed in your repository. For example: -# RUN yarn global add turbo@^2 + RUN bun add -g turbo@^2 COPY . . -# Add lockfile and package.json's of isolated subworkspace -# Generate a partial monorepo with a pruned lockfile for a target workspace. -# Assuming "web" is the name entered in the project's package.json: { name: "web" } RUN turbo prune web --docker @@ -28,6 +24,12 @@ COPY --from=prepare /app/out/full/ . # Copy the rest of the source code COPY --from=prepare /app/out/full/ . +ARG PUBLIC_CONVEX_URL +ENV PUBLIC_CONVEX_URL=$PUBLIC_CONVEX_URL + +ARG PUBLIC_CONVEX_SITE_URL +ENV PUBLIC_CONVEX_SITE_URL=$PUBLIC_CONVEX_SITE_URL + RUN bunx turbo build # Production stage diff --git a/apps/web/package.json b/apps/web/package.json index 55c201c..7314345 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -4,9 +4,9 @@ "version": "0.0.1", "type": "module", "scripts": { - "dev": "vite dev", - "build": "vite build", - "preview": "vite preview", + "dev": "bunx --bun vite dev", + "build": "bunx --bun vite build", + "preview": "bunx --bun vite preview", "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" @@ -22,6 +22,7 @@ "esbuild": "^0.25.11", "postcss": "^8.5.6", "svelte": "^5.38.1", + "svelte-adapter-bun": "^1.0.1", "svelte-check": "^4.3.1", "svelte-dnd-action": "^0.9.67", "tailwindcss": "^4.1.12", diff --git a/apps/web/svelte.config.js b/apps/web/svelte.config.js index 6f88dbb..008b306 100644 --- a/apps/web/svelte.config.js +++ b/apps/web/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from "@sveltejs/adapter-auto"; +import adapter from "svelte-adapter-bun"; import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; /** @type {import('@sveltejs/kit').Config} */ diff --git a/bun.lock b/bun.lock index 1f58467..cb8737c 100644 --- a/bun.lock +++ b/bun.lock @@ -67,6 +67,7 @@ "esbuild": "^0.25.11", "postcss": "^8.5.6", "svelte": "^5.38.1", + "svelte-adapter-bun": "^1.0.1", "svelte-check": "^4.3.1", "svelte-dnd-action": "^0.9.67", "tailwindcss": "^4.1.12", @@ -85,7 +86,6 @@ "better-auth": "catalog:", "convex": "catalog:", "nodemailer": "^7.0.10", - "ssh2": "^1.17.0", }, "devDependencies": { "@sgse-app/eslint-config": "*", @@ -271,6 +271,12 @@ "@dicebear/thumbs": ["@dicebear/thumbs@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-EL4sMqv9p2+1Xy3d8e8UxyeKZV2+cgt3X2x2RTRzEOIIhobtkL8u6lJxmJbiGbpVtVALmrt5e7gjmwqpryYDpg=="], + "@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.11", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.25.11", "", { "os": "android", "cpu": "arm" }, "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg=="], @@ -379,6 +385,8 @@ "@mmailaender/convex-better-auth-svelte": ["@mmailaender/convex-better-auth-svelte@0.2.0", "", { "dependencies": { "is-network-error": "^1.1.0" }, "peerDependencies": { "@convex-dev/better-auth": "^0.9.0", "better-auth": "^1.3.27", "convex": "^1.27.0", "convex-svelte": "^0.0.11", "svelte": "^5.0.0" } }, "sha512-qzahOJg30xErb4ZW+aeszQw4ydhCmKFXn8CeRSA77YxR/dDMgZl+vdWLE4EKsDN0Jd748ecWMnk1fDNNUdgDcg=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], + "@next/eslint-plugin-next": ["@next/eslint-plugin-next@15.5.6", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-YxDvsT2fwy1j5gMqk3ppXlsgDopHnkM4BoxSVASbvvgh5zgsK8lvWerDzPip8k3WVzsTZ1O7A7si1KNfN4OZfQ=="], "@noble/ciphers": ["@noble/ciphers@2.0.1", "", {}, "sha512-xHK3XHPUW8DTAobU+G0XT+/w+JLM7/8k1UFdB5xg/zTFPnFCobhftzw8wl4Lw2aq/Rvir5pxfZV5fEazmeCJ2g=="], @@ -391,6 +399,10 @@ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@oxc-project/runtime": ["@oxc-project/runtime@0.71.0", "", {}, "sha512-QwoF5WUXIGFQ+hSxWEib4U/aeLoiDN9JlP18MnBgx9LLPRDfn1iICtcow7Jgey6HLH4XFceWXQD5WBJ39dyJcw=="], + + "@oxc-project/types": ["@oxc-project/types@0.71.0", "", {}, "sha512-5CwQ4MI+P4MQbjLWXgNurA+igGwu/opNetIE13LBs9+V93R64MLvDKOOLZIXSzEfovU3Zef3q3GjPnMTgJTn2w=="], + "@peculiar/asn1-android": ["@peculiar/asn1-android@2.5.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.5.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-t8A83hgghWQkcneRsgGs2ebAlRe54ns88p7ouv8PW2tzF1nAW4yHcL4uZKrFpIU+uszIRzTkcCuie37gpkId0A=="], "@peculiar/asn1-cms": ["@peculiar/asn1-cms@2.5.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.5.0", "@peculiar/asn1-x509": "^2.5.0", "@peculiar/asn1-x509-attr": "^2.5.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-p0SjJ3TuuleIvjPM4aYfvYw8Fk1Hn/zAVyPJZTtZ2eE9/MIer6/18ROxX6N/e6edVSfvuZBqhxAj3YgsmSjQ/A=="], @@ -417,6 +429,32 @@ "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-beta.9-commit.d91dfb5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Mp0/gqiPdepHjjVm7e0yL1acWvI0rJVVFQEADSezvAjon9sjQ7CEg9JnXICD4B1YrPmN9qV/e7cQZCp87tTV4w=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-beta.9-commit.d91dfb5", "", { "os": "darwin", "cpu": "x64" }, "sha512-40re4rMNrsi57oavRzIOpRGmg3QRlW6Ea8Q3znaqgOuJuKVrrm2bIQInTfkZJG7a4/5YMX7T951d0+toGLTdCA=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-beta.9-commit.d91dfb5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-8BDM939bbMariZupiHp3OmP5N+LXPT4mULA0hZjDaq970PCxv4krZOSMG+HkWUUwmuQROtV+/00xw39EO0P+8g=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.9-commit.d91dfb5", "", { "os": "linux", "cpu": "arm" }, "sha512-sntsPaPgrECpBB/+2xrQzVUt0r493TMPI+4kWRMhvMsmrxOqH1Ep5lM0Wua/ZdbfZNwm1aVa5pcESQfNfM4Fhw=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-beta.9-commit.d91dfb5", "", { "os": "linux", "cpu": "arm64" }, "sha512-5clBW/I+er9F2uM1OFjJFWX86y7Lcy0M+NqsN4s3o07W+8467Zk8oQa4B45vdaXoNUF/yqIAgKkA/OEdQDxZqA=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-beta.9-commit.d91dfb5", "", { "os": "linux", "cpu": "arm64" }, "sha512-wv+rnAfQDk9p/CheX8/Kmqk2o1WaFa4xhWI9gOyDMk/ljvOX0u0ubeM8nI1Qfox7Tnh71eV5AjzSePXUhFOyOg=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-beta.9-commit.d91dfb5", "", { "os": "linux", "cpu": "x64" }, "sha512-gxD0/xhU4Py47IH3bKZbWtvB99tMkUPGPJFRfSc5UB9Osoje0l0j1PPbxpUtXIELurYCqwLBKXIMTQGifox1BQ=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-beta.9-commit.d91dfb5", "", { "os": "linux", "cpu": "x64" }, "sha512-HotuVe3XUjDwqqEMbm3o3IRkP9gdm8raY/btd/6KE3JGLF/cv4+3ff1l6nOhAZI8wulWDPEXPtE7v+HQEaTXnA=="], + + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-beta.9-commit.d91dfb5", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.4" }, "cpu": "none" }, "sha512-8Cx+ucbd8n2dIr21FqBh6rUvTVL0uTgEtKR7l+MUZ5BgY4dFh1e4mPVX8oqmoYwOxBiXrsD2JIOCz4AyKLKxWA=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-beta.9-commit.d91dfb5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Vhq5vikrVDxAa75fxsyqj0c0Y/uti/TwshXI71Xb8IeUQJOBnmLUsn5dgYf5ljpYYkNa0z9BPAvUDIDMmyDi+w=="], + + "@rolldown/binding-win32-ia32-msvc": ["@rolldown/binding-win32-ia32-msvc@1.0.0-beta.9-commit.d91dfb5", "", { "os": "win32", "cpu": "ia32" }, "sha512-lN7RIg9Iugn08zP2aZN9y/MIdG8iOOCE93M1UrFlrxMTqPf8X+fDzmR/OKhTSd1A2pYNipZHjyTcb5H8kyQSow=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-beta.9-commit.d91dfb5", "", { "os": "win32", "cpu": "x64" }, "sha512-7/7cLIn48Y+EpQ4CePvf8reFl63F15yPUlg4ZAhl+RXJIfydkdak1WD8Ir3AwAO+bJBXzrfNL+XQbxm0mcQZmw=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.9-commit.d91dfb5", "", {}, "sha512-8sExkWRK+zVybw3+2/kBkYBFeLnEUWz1fT7BLHplpzmtqkOfTbAQ9gkt4pzwGIIZmg4Qn5US5ACjUBenrhezwQ=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.5", "", { "os": "android", "cpu": "arm" }, "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ=="], "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.52.5", "", { "os": "android", "cpu": "arm64" }, "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA=="], @@ -605,6 +643,8 @@ "@tanstack/svelte-store": ["@tanstack/svelte-store@0.7.7", "", { "dependencies": { "@tanstack/store": "0.7.7" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-JeDyY7SxBi6EKzkf2wWoghdaC2bvmwNL9X/dgkx7LKEvJVle+te7tlELI3cqRNGbjXt9sx+97jx9M5dCCHcuog=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@types/cookie": ["@types/cookie@1.0.0", "", { "dependencies": { "cookie": "*" } }, "sha512-mGFXbkDQJ6kAXByHS7QAggRXgols0mAdP4MuXgloGY1tXokvzaFFM4SMqWvf7AH0oafI7zlFJwoGWzmhDqTZ9w=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], @@ -653,6 +693,8 @@ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="], + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], @@ -671,8 +713,6 @@ "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="], - "asn1": ["asn1@0.2.6", "", { "dependencies": { "safer-buffer": "~2.1.0" } }, "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ=="], - "asn1js": ["asn1js@3.0.6", "", { "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" } }, "sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA=="], "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], @@ -689,8 +729,6 @@ "baseline-browser-mapping": ["baseline-browser-mapping@2.8.21", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q=="], - "bcrypt-pbkdf": ["bcrypt-pbkdf@1.0.2", "", { "dependencies": { "tweetnacl": "^0.14.3" } }, "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w=="], - "better-auth": ["better-auth@1.3.27", "", { "dependencies": { "@better-auth/core": "1.3.27", "@better-auth/utils": "0.3.0", "@better-fetch/fetch": "1.1.18", "@noble/ciphers": "^2.0.0", "@noble/hashes": "^2.0.0", "@simplewebauthn/browser": "^13.1.2", "@simplewebauthn/server": "^13.1.2", "better-call": "1.0.19", "defu": "^6.1.4", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1", "zod": "^4.1.5" } }, "sha512-SwiGAJ7yU6dBhNg0NdV1h5M8T5sa7/AszZVc4vBfMDrLLmvUfbt9JoJ0uRUJUEdKRAAxTyl9yA+F3+GhtAD80w=="], "better-call": ["better-call@1.0.19", "", { "dependencies": { "@better-auth/utils": "^0.3.0", "@better-fetch/fetch": "^1.1.4", "rou3": "^0.5.1", "set-cookie-parser": "^2.7.1", "uncrypto": "^0.1.3" } }, "sha512-sI3GcA1SCVa3H+CDHl8W8qzhlrckwXOTKhqq3OOPXjgn5aTOMIqGY34zLY/pHA6tRRMjTUC3lz5Mi7EbDA24Kw=="], @@ -703,8 +741,6 @@ "browserslist": ["browserslist@4.27.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", "electron-to-chromium": "^1.5.238", "node-releases": "^2.0.26", "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw=="], - "buildcheck": ["buildcheck@0.0.6", "", {}, "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A=="], - "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], @@ -743,8 +779,6 @@ "core-js": ["core-js@3.46.0", "", {}, "sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA=="], - "cpu-features": ["cpu-features@0.0.10", "", { "dependencies": { "buildcheck": "~0.0.6", "nan": "^2.19.0" } }, "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA=="], - "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "css-line-break": ["css-line-break@2.1.0", "", { "dependencies": { "utrie": "^1.0.2" } }, "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w=="], @@ -1075,8 +1109,6 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "nan": ["nan@2.23.1", "", {}, "sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw=="], - "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "nanostores": ["nanostores@1.0.1", "", {}, "sha512-kNZ9xnoJYKg/AfxjrVL4SS0fKX++4awQReGqWnwTRHxeHGZ1FJFVgTqr/eMrNQdp0Tz7M7tG/TDaX8QfHDwVCw=="], @@ -1191,6 +1223,8 @@ "rgbcolor": ["rgbcolor@1.0.1", "", {}, "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw=="], + "rolldown": ["rolldown@1.0.0-beta.9-commit.d91dfb5", "", { "dependencies": { "@oxc-project/runtime": "0.71.0", "@oxc-project/types": "0.71.0", "@rolldown/pluginutils": "1.0.0-beta.9-commit.d91dfb5", "ansis": "^4.0.0" }, "optionalDependencies": { "@rolldown/binding-darwin-arm64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-darwin-x64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-freebsd-x64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-x64-musl": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-wasm32-wasi": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.9-commit.d91dfb5" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-FHkj6gGEiEgmAXQchglofvUUdwj2Oiw603Rs+zgFAnn9Cb7T7z3fiaEc0DbN3ja4wYkW6sF2rzMEtC1V4BGx/g=="], + "rollup": ["rollup@4.52.5", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.5", "@rollup/rollup-android-arm64": "4.52.5", "@rollup/rollup-darwin-arm64": "4.52.5", "@rollup/rollup-darwin-x64": "4.52.5", "@rollup/rollup-freebsd-arm64": "4.52.5", "@rollup/rollup-freebsd-x64": "4.52.5", "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", "@rollup/rollup-linux-arm-musleabihf": "4.52.5", "@rollup/rollup-linux-arm64-gnu": "4.52.5", "@rollup/rollup-linux-arm64-musl": "4.52.5", "@rollup/rollup-linux-loong64-gnu": "4.52.5", "@rollup/rollup-linux-ppc64-gnu": "4.52.5", "@rollup/rollup-linux-riscv64-gnu": "4.52.5", "@rollup/rollup-linux-riscv64-musl": "4.52.5", "@rollup/rollup-linux-s390x-gnu": "4.52.5", "@rollup/rollup-linux-x64-gnu": "4.52.5", "@rollup/rollup-linux-x64-musl": "4.52.5", "@rollup/rollup-openharmony-arm64": "4.52.5", "@rollup/rollup-win32-arm64-msvc": "4.52.5", "@rollup/rollup-win32-ia32-msvc": "4.52.5", "@rollup/rollup-win32-x64-gnu": "4.52.5", "@rollup/rollup-win32-x64-msvc": "4.52.5", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw=="], "rou3": ["rou3@0.5.1", "", {}, "sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ=="], @@ -1207,8 +1241,6 @@ "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], - "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], - "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], @@ -1237,8 +1269,6 @@ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - "ssh2": ["ssh2@1.17.0", "", { "dependencies": { "asn1": "^0.2.6", "bcrypt-pbkdf": "^1.0.2" }, "optionalDependencies": { "cpu-features": "~0.0.10", "nan": "^2.23.0" } }, "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ=="], - "stackblur-canvas": ["stackblur-canvas@2.7.0", "", {}, "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ=="], "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="], @@ -1263,6 +1293,8 @@ "svelte": ["svelte@5.43.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-ro1umEzX8rT5JpCmlf0PPv7ncD8MdVob9e18bhwqTKNoLjS8kDvhVpaoYVPc+qMwDAOfcwJtyY7ZFSDbOaNPgA=="], + "svelte-adapter-bun": ["svelte-adapter-bun@1.0.1", "", { "dependencies": { "rolldown": "^1.0.0-beta.38" }, "peerDependencies": { "@sveltejs/kit": "^2.4.0", "typescript": "^5" } }, "sha512-tNOvfm8BGgG+rmEA7hkmqtq07v7zoo4skLQc+hIoQ79J+1fkEMpJEA2RzCIe3aPc8JdrsMJkv3mpiZPMsgahjA=="], + "svelte-chartjs": ["svelte-chartjs@3.1.5", "", { "peerDependencies": { "chart.js": "^3.5.0 || ^4.0.0", "svelte": "^4.0.0" } }, "sha512-ka2zh7v5FiwfAX1oMflZ0HkNkgjHjFqANgRyC+vNYXfxtx2ku68Zo+2KgbKeBH2nS1ThDqkIACPzGxy4T0UaoA=="], "svelte-check": ["svelte-check@4.3.3", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg=="], @@ -1307,8 +1339,6 @@ "turbo-windows-arm64": ["turbo-windows-arm64@2.5.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-eFC5XzLmgXJfnAK3UMTmVECCwuBcORrWdewoiXBnUm934DY6QN8YowC/srhNnROMpaKaqNeRpoB5FxCww3eteQ=="], - "tweetnacl": ["tweetnacl@0.14.5", "", {}, "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="], - "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], diff --git a/packages/backend/convex/actions/jitsiServer.ts b/packages/backend/convex/actions/jitsiServer.ts index 3c47439..6baac7d 100644 --- a/packages/backend/convex/actions/jitsiServer.ts +++ b/packages/backend/convex/actions/jitsiServer.ts @@ -1,432 +1,432 @@ -"use node"; +// "use node"; -import { action } from "../_generated/server"; -import { v } from "convex/values"; -import { api, internal } from "../_generated/api"; -import { Client } from "ssh2"; -import { readFileSync } from "fs"; -import { decryptSMTPPasswordNode } from "./utils/nodeCrypto"; +// import { action } from "../_generated/server"; +// import { v } from "convex/values"; +// import { api, internal } from "../_generated/api"; +// import { Client } from "ssh2"; +// import { readFileSync } from "fs"; +// import { decryptSMTPPasswordNode } from "./utils/nodeCrypto"; -/** - * Interface para configuração SSH - */ -interface SSHConfig { - host: string; - port: number; - username: string; - password?: string; - keyPath?: string; -} +// /** +// * Interface para configuração SSH +// */ +// interface SSHConfig { +// host: string; +// port: number; +// username: string; +// password?: string; +// keyPath?: string; +// } -/** - * Executar comando via SSH - */ -async function executarComandoSSH( - config: SSHConfig, - comando: string -): Promise<{ sucesso: boolean; output: string; erro?: string }> { - return new Promise((resolve) => { - const conn = new Client(); - let output = ""; - let errorOutput = ""; +// /** +// * Executar comando via SSH +// */ +// async function executarComandoSSH( +// config: SSHConfig, +// comando: string +// ): Promise<{ sucesso: boolean; output: string; erro?: string }> { +// return new Promise((resolve) => { +// const conn = new Client(); +// let output = ""; +// let errorOutput = ""; - conn.on("ready", () => { - conn.exec(comando, (err, stream) => { - if (err) { - conn.end(); - resolve({ sucesso: false, output: "", erro: err.message }); - return; - } +// conn.on("ready", () => { +// conn.exec(comando, (err, stream) => { +// if (err) { +// conn.end(); +// resolve({ sucesso: false, output: "", erro: err.message }); +// return; +// } - stream - .on("close", (code: number | null, signal: string | null) => { - conn.end(); - if (code === 0) { - resolve({ sucesso: true, output: output.trim() }); - } else { - resolve({ - sucesso: false, - output: output.trim(), - erro: `Comando retornou código ${code}${signal ? ` (signal: ${signal})` : ""}. ${errorOutput}`, - }); - } - }) - .on("data", (data: Buffer) => { - output += data.toString(); - }) - .stderr.on("data", (data: Buffer) => { - errorOutput += data.toString(); - }); - }); - }).on("error", (err) => { - resolve({ sucesso: false, output: "", erro: err.message }); - }).connect({ - host: config.host, - port: config.port, - username: config.username, - password: config.password, - privateKey: config.keyPath ? readFileSync(config.keyPath) : undefined, - readyTimeout: 10000, - }); - }); -} +// stream +// .on("close", (code: number | null, signal: string | null) => { +// conn.end(); +// if (code === 0) { +// resolve({ sucesso: true, output: output.trim() }); +// } else { +// resolve({ +// sucesso: false, +// output: output.trim(), +// erro: `Comando retornou código ${code}${signal ? ` (signal: ${signal})` : ""}. ${errorOutput}`, +// }); +// } +// }) +// .on("data", (data: Buffer) => { +// output += data.toString(); +// }) +// .stderr.on("data", (data: Buffer) => { +// errorOutput += data.toString(); +// }); +// }); +// }).on("error", (err) => { +// resolve({ sucesso: false, output: "", erro: err.message }); +// }).connect({ +// host: config.host, +// port: config.port, +// username: config.username, +// password: config.password, +// privateKey: config.keyPath ? readFileSync(config.keyPath) : undefined, +// readyTimeout: 10000, +// }); +// }); +// } -/** - * Ler arquivo via SSH - */ -async function lerArquivoSSH( - config: SSHConfig, - caminho: string -): Promise<{ sucesso: boolean; conteudo?: string; erro?: string }> { - const comando = `cat "${caminho}" 2>&1`; - const resultado = await executarComandoSSH(config, comando); +// /** +// * Ler arquivo via SSH +// */ +// async function lerArquivoSSH( +// config: SSHConfig, +// caminho: string +// ): Promise<{ sucesso: boolean; conteudo?: string; erro?: string }> { +// const comando = `cat "${caminho}" 2>&1`; +// const resultado = await executarComandoSSH(config, comando); - if (!resultado.sucesso) { - return { sucesso: false, erro: resultado.erro || "Erro ao ler arquivo" }; - } +// if (!resultado.sucesso) { +// return { sucesso: false, erro: resultado.erro || "Erro ao ler arquivo" }; +// } - return { sucesso: true, conteudo: resultado.output }; -} +// return { sucesso: true, conteudo: resultado.output }; +// } -/** - * Escrever arquivo via SSH - */ -async function escreverArquivoSSH( - config: SSHConfig, - caminho: string, - conteudo: string -): Promise<{ sucesso: boolean; erro?: string }> { - // Escapar conteúdo para shell - const conteudoEscapado = conteudo - .replace(/\\/g, "\\\\") - .replace(/"/g, '\\"') - .replace(/\$/g, "\\$") - .replace(/`/g, "\\`"); +// /** +// * Escrever arquivo via SSH +// */ +// async function escreverArquivoSSH( +// config: SSHConfig, +// caminho: string, +// conteudo: string +// ): Promise<{ sucesso: boolean; erro?: string }> { +// // Escapar conteúdo para shell +// const conteudoEscapado = conteudo +// .replace(/\\/g, "\\\\") +// .replace(/"/g, '\\"') +// .replace(/\$/g, "\\$") +// .replace(/`/g, "\\`"); - const comando = `cat > "${caminho}" << 'JITSI_CONFIG_EOF' -${conteudo} -JITSI_CONFIG_EOF`; +// const comando = `cat > "${caminho}" << 'JITSI_CONFIG_EOF' +// ${conteudo} +// JITSI_CONFIG_EOF`; - const resultado = await executarComandoSSH(config, comando); +// const resultado = await executarComandoSSH(config, comando); - if (!resultado.sucesso) { - return { sucesso: false, erro: resultado.erro || "Erro ao escrever arquivo" }; - } +// if (!resultado.sucesso) { +// return { sucesso: false, erro: resultado.erro || "Erro ao escrever arquivo" }; +// } - return { sucesso: true }; -} +// return { sucesso: true }; +// } -/** - * Aplicar configurações do Jitsi no servidor Docker via SSH - */ -export const aplicarConfiguracaoServidor = action({ - args: { - configId: v.id("configuracaoJitsi"), - sshPassword: v.optional(v.string()), // Senha SSH (se não usar chave) - }, - returns: v.union( - v.object({ - sucesso: v.literal(true), - mensagem: v.string(), - detalhes: v.optional(v.string()), - }), - v.object({ sucesso: v.literal(false), erro: v.string() }) - ), - handler: async (ctx, args): Promise< - | { sucesso: true; mensagem: string; detalhes?: string } - | { sucesso: false; erro: string } - > => { - try { - // Buscar configuração - const config = await ctx.runQuery(api.configuracaoJitsi.obterConfigJitsi, {}); +// /** +// * Aplicar configurações do Jitsi no servidor Docker via SSH +// */ +// export const aplicarConfiguracaoServidor = action({ +// args: { +// configId: v.id("configuracaoJitsi"), +// sshPassword: v.optional(v.string()), // Senha SSH (se não usar chave) +// }, +// returns: v.union( +// v.object({ +// sucesso: v.literal(true), +// mensagem: v.string(), +// detalhes: v.optional(v.string()), +// }), +// v.object({ sucesso: v.literal(false), erro: v.string() }) +// ), +// handler: async (ctx, args): Promise< +// | { sucesso: true; mensagem: string; detalhes?: string } +// | { sucesso: false; erro: string } +// > => { +// try { +// // Buscar configuração +// const config = await ctx.runQuery(api.configuracaoJitsi.obterConfigJitsi, {}); - if (!config || config._id !== args.configId) { - return { sucesso: false as const, erro: "Configuração não encontrada" }; - } +// if (!config || config._id !== args.configId) { +// return { sucesso: false as const, erro: "Configuração não encontrada" }; +// } - // Verificar se tem configurações SSH - const configFull = await ctx.runQuery(api.configuracaoJitsi.obterConfigJitsiCompleta, { - configId: args.configId, - }); +// // Verificar se tem configurações SSH +// const configFull = await ctx.runQuery(api.configuracaoJitsi.obterConfigJitsiCompleta, { +// configId: args.configId, +// }); - if (!configFull || !configFull.sshHost) { - return { - sucesso: false as const, - erro: "Configurações SSH não estão definidas. Configure o servidor SSH primeiro.", - }; - } +// if (!configFull || !configFull.sshHost) { +// return { +// sucesso: false as const, +// erro: "Configurações SSH não estão definidas. Configure o servidor SSH primeiro.", +// }; +// } - // Configurar SSH - let sshPasswordDecrypted: string | undefined = undefined; +// // Configurar SSH +// let sshPasswordDecrypted: string | undefined = undefined; - // Se senha foi fornecida, usar ela. Caso contrário, tentar descriptografar a armazenada - if (args.sshPassword) { - sshPasswordDecrypted = args.sshPassword; - } else if (configFull.sshPasswordHash && configFull.sshPasswordHash !== "********") { - // Tentar descriptografar senha armazenada - try { - sshPasswordDecrypted = await decryptSMTPPasswordNode(configFull.sshPasswordHash); - } catch (error) { - return { - sucesso: false as const, - erro: "Não foi possível descriptografar a senha SSH armazenada. Forneça a senha novamente.", - }; - } - } +// // Se senha foi fornecida, usar ela. Caso contrário, tentar descriptografar a armazenada +// if (args.sshPassword) { +// sshPasswordDecrypted = args.sshPassword; +// } else if (configFull.sshPasswordHash && configFull.sshPasswordHash !== "********") { +// // Tentar descriptografar senha armazenada +// try { +// sshPasswordDecrypted = await decryptSMTPPasswordNode(configFull.sshPasswordHash); +// } catch (error) { +// return { +// sucesso: false as const, +// erro: "Não foi possível descriptografar a senha SSH armazenada. Forneça a senha novamente.", +// }; +// } +// } - const sshConfig: SSHConfig = { - host: configFull.sshHost, - port: configFull.sshPort || 22, - username: configFull.sshUsername || "", - password: sshPasswordDecrypted, - keyPath: configFull.sshKeyPath || undefined, - }; +// const sshConfig: SSHConfig = { +// host: configFull.sshHost, +// port: configFull.sshPort || 22, +// username: configFull.sshUsername || "", +// password: sshPasswordDecrypted, +// keyPath: configFull.sshKeyPath || undefined, +// }; - if (!sshConfig.username) { - return { sucesso: false as const, erro: "Usuário SSH não configurado" }; - } +// if (!sshConfig.username) { +// return { sucesso: false as const, erro: "Usuário SSH não configurado" }; +// } - if (!sshConfig.password && !sshConfig.keyPath) { - return { - sucesso: false as const, - erro: "Senha SSH ou caminho da chave deve ser fornecido", - }; - } +// if (!sshConfig.password && !sshConfig.keyPath) { +// return { +// sucesso: false as const, +// erro: "Senha SSH ou caminho da chave deve ser fornecido", +// }; +// } - const basePath = configFull.jitsiConfigPath || "~/.jitsi-meet-cfg"; - const dockerComposePath = configFull.dockerComposePath || "."; +// const basePath = configFull.jitsiConfigPath || "~/.jitsi-meet-cfg"; +// const dockerComposePath = configFull.dockerComposePath || "."; - // Extrair host e porta do domain - const [host, portStr] = configFull.domain.split(":"); - const port = portStr ? parseInt(portStr, 10) : configFull.useHttps ? 443 : 80; - const protocol = configFull.useHttps ? "https" : "http"; +// // Extrair host e porta do domain +// const [host, portStr] = configFull.domain.split(":"); +// const port = portStr ? parseInt(portStr, 10) : configFull.useHttps ? 443 : 80; +// const protocol = configFull.useHttps ? "https" : "http"; - const detalhes: string[] = []; +// const detalhes: string[] = []; - // 1. Atualizar arquivo .env do docker-compose - if (dockerComposePath) { - const envContent = `# Configuração Jitsi - Atualizada automaticamente pelo SGSE -CONFIG=${basePath} -TZ=America/Recife -ENABLE_LETSENCRYPT=0 -HTTP_PORT=${protocol === "https" ? 8000 : port} -HTTPS_PORT=${configFull.useHttps ? port : 8443} -PUBLIC_URL=${protocol}://${host}${portStr ? `:${port}` : ""} -DOMAIN=${host} -ENABLE_AUTH=0 -ENABLE_GUESTS=1 -ENABLE_TRANSCRIPTION=0 -ENABLE_RECORDING=0 -ENABLE_PREJOIN_PAGE=0 -START_AUDIO_MUTED=0 -START_VIDEO_MUTED=0 -ENABLE_XMPP_WEBSOCKET=0 -ENABLE_P2P=1 -MAX_NUMBER_OF_PARTICIPANTS=10 -RESOLUTION_WIDTH=1280 -RESOLUTION_HEIGHT=720 -JWT_APP_ID=${configFull.appId} -JWT_APP_SECRET= -`; +// // 1. Atualizar arquivo .env do docker-compose +// if (dockerComposePath) { +// const envContent = `# Configuração Jitsi - Atualizada automaticamente pelo SGSE +// CONFIG=${basePath} +// TZ=America/Recife +// ENABLE_LETSENCRYPT=0 +// HTTP_PORT=${protocol === "https" ? 8000 : port} +// HTTPS_PORT=${configFull.useHttps ? port : 8443} +// PUBLIC_URL=${protocol}://${host}${portStr ? `:${port}` : ""} +// DOMAIN=${host} +// ENABLE_AUTH=0 +// ENABLE_GUESTS=1 +// ENABLE_TRANSCRIPTION=0 +// ENABLE_RECORDING=0 +// ENABLE_PREJOIN_PAGE=0 +// START_AUDIO_MUTED=0 +// START_VIDEO_MUTED=0 +// ENABLE_XMPP_WEBSOCKET=0 +// ENABLE_P2P=1 +// MAX_NUMBER_OF_PARTICIPANTS=10 +// RESOLUTION_WIDTH=1280 +// RESOLUTION_HEIGHT=720 +// JWT_APP_ID=${configFull.appId} +// JWT_APP_SECRET= +// `; - const envPath = `${dockerComposePath}/.env`; - const resultadoEnv = await escreverArquivoSSH(sshConfig, envPath, envContent); +// const envPath = `${dockerComposePath}/.env`; +// const resultadoEnv = await escreverArquivoSSH(sshConfig, envPath, envContent); - if (!resultadoEnv.sucesso) { - return { - sucesso: false as const, - erro: `Erro ao atualizar .env: ${resultadoEnv.erro}`, - }; - } +// if (!resultadoEnv.sucesso) { +// return { +// sucesso: false as const, +// erro: `Erro ao atualizar .env: ${resultadoEnv.erro}`, +// }; +// } - detalhes.push(`✓ Arquivo .env atualizado: ${envPath}`); - } +// detalhes.push(`✓ Arquivo .env atualizado: ${envPath}`); +// } - // 2. Atualizar configuração do Prosody (conforme documentação oficial) - const prosodyConfigPath = `${basePath}/prosody/config/${host}.cfg.lua`; - const prosodyContent = `-- Configuração Prosody para ${host} --- Gerada automaticamente pelo SGSE --- Baseado na documentação oficial do Jitsi Meet +// // 2. Atualizar configuração do Prosody (conforme documentação oficial) +// const prosodyConfigPath = `${basePath}/prosody/config/${host}.cfg.lua`; +// const prosodyContent = `-- Configuração Prosody para ${host} +// -- Gerada automaticamente pelo SGSE +// -- Baseado na documentação oficial do Jitsi Meet -VirtualHost "${host}" - authentication = "anonymous" - modules_enabled = { - "bosh"; - "websocket"; - "ping"; - "speakerstats"; - "turncredentials"; - "presence"; - "conference_duration"; - "stats"; - } - c2s_require_encryption = false - allow_anonymous_s2s = false - bosh_max_inactivity = 60 - bosh_max_polling = 5 - bosh_max_stanzas = 5 +// VirtualHost "${host}" +// authentication = "anonymous" +// modules_enabled = { +// "bosh"; +// "websocket"; +// "ping"; +// "speakerstats"; +// "turncredentials"; +// "presence"; +// "conference_duration"; +// "stats"; +// } +// c2s_require_encryption = false +// allow_anonymous_s2s = false +// bosh_max_inactivity = 60 +// bosh_max_polling = 5 +// bosh_max_stanzas = 5 -Component "conference.${host}" "muc" - storage = "memory" - muc_room_locking = false - muc_room_default_public_jids = true - muc_room_cache_size = 1000 - muc_log_presences = true +// Component "conference.${host}" "muc" +// storage = "memory" +// muc_room_locking = false +// muc_room_default_public_jids = true +// muc_room_cache_size = 1000 +// muc_log_presences = true -Component "jitsi-videobridge.${host}" - component_secret = "" +// Component "jitsi-videobridge.${host}" +// component_secret = "" -Component "focus.${host}" - component_secret = "" -`; +// Component "focus.${host}" +// component_secret = "" +// `; - const resultadoProsody = await escreverArquivoSSH(sshConfig, prosodyConfigPath, prosodyContent); +// const resultadoProsody = await escreverArquivoSSH(sshConfig, prosodyConfigPath, prosodyContent); - if (!resultadoProsody.sucesso) { - return { - sucesso: false as const, - erro: `Erro ao atualizar Prosody: ${resultadoProsody.erro}`, - }; - } +// if (!resultadoProsody.sucesso) { +// return { +// sucesso: false as const, +// erro: `Erro ao atualizar Prosody: ${resultadoProsody.erro}`, +// }; +// } - detalhes.push(`✓ Configuração Prosody atualizada: ${prosodyConfigPath}`); +// detalhes.push(`✓ Configuração Prosody atualizada: ${prosodyConfigPath}`); - // 3. Atualizar configuração do Jicofo - const jicofoConfigPath = `${basePath}/jicofo/sip-communicator.properties`; - const jicofoContent = `# Configuração Jicofo -# Gerada automaticamente pelo SGSE -org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.${host} -org.jitsi.jicofo.jid=XMPP_USER@${host} -org.jitsi.jicofo.BRIDGE_MUC_JID=MUC_BRIDGE_JID@internal.${host} -org.jitsi.jicofo.app.ID=${configFull.appId} -`; +// // 3. Atualizar configuração do Jicofo +// const jicofoConfigPath = `${basePath}/jicofo/sip-communicator.properties`; +// const jicofoContent = `# Configuração Jicofo +// # Gerada automaticamente pelo SGSE +// org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.${host} +// org.jitsi.jicofo.jid=XMPP_USER@${host} +// org.jitsi.jicofo.BRIDGE_MUC_JID=MUC_BRIDGE_JID@internal.${host} +// org.jitsi.jicofo.app.ID=${configFull.appId} +// `; - const resultadoJicofo = await escreverArquivoSSH(sshConfig, jicofoConfigPath, jicofoContent); +// const resultadoJicofo = await escreverArquivoSSH(sshConfig, jicofoConfigPath, jicofoContent); - if (!resultadoJicofo.sucesso) { - return { - sucesso: false as const, - erro: `Erro ao atualizar Jicofo: ${resultadoJicofo.erro}`, - }; - } +// if (!resultadoJicofo.sucesso) { +// return { +// sucesso: false as const, +// erro: `Erro ao atualizar Jicofo: ${resultadoJicofo.erro}`, +// }; +// } - detalhes.push(`✓ Configuração Jicofo atualizada: ${jicofoConfigPath}`); +// detalhes.push(`✓ Configuração Jicofo atualizada: ${jicofoConfigPath}`); - // 4. Atualizar configuração do JVB - const jvbConfigPath = `${basePath}/jvb/sip-communicator.properties`; - const jvbContent = `# Configuração JVB (Jitsi Video Bridge) -# Gerada automaticamente pelo SGSE -org.jitsi.videobridge.AUTHORIZED_SOURCE_REGEXP=.*@${host}/.* -org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=${host} -org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.${host} -org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb -org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.${host} -`; +// // 4. Atualizar configuração do JVB +// const jvbConfigPath = `${basePath}/jvb/sip-communicator.properties`; +// const jvbContent = `# Configuração JVB (Jitsi Video Bridge) +// # Gerada automaticamente pelo SGSE +// org.jitsi.videobridge.AUTHORIZED_SOURCE_REGEXP=.*@${host}/.* +// org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=${host} +// org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.${host} +// org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb +// org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.${host} +// `; - const resultadoJvb = await escreverArquivoSSH(sshConfig, jvbConfigPath, jvbContent); +// const resultadoJvb = await escreverArquivoSSH(sshConfig, jvbConfigPath, jvbContent); - if (!resultadoJvb.sucesso) { - return { - sucesso: false as const, - erro: `Erro ao atualizar JVB: ${resultadoJvb.erro}`, - }; - } +// if (!resultadoJvb.sucesso) { +// return { +// sucesso: false as const, +// erro: `Erro ao atualizar JVB: ${resultadoJvb.erro}`, +// }; +// } - detalhes.push(`✓ Configuração JVB atualizada: ${jvbConfigPath}`); +// detalhes.push(`✓ Configuração JVB atualizada: ${jvbConfigPath}`); - // 5. Reiniciar containers Docker - if (dockerComposePath) { - const resultadoRestart = await executarComandoSSH( - sshConfig, - `cd "${dockerComposePath}" && docker-compose restart 2>&1 || docker compose restart 2>&1` - ); +// // 5. Reiniciar containers Docker +// if (dockerComposePath) { +// const resultadoRestart = await executarComandoSSH( +// sshConfig, +// `cd "${dockerComposePath}" && docker-compose restart 2>&1 || docker compose restart 2>&1` +// ); - if (!resultadoRestart.sucesso) { - return { - sucesso: false as const, - erro: `Erro ao reiniciar containers: ${resultadoRestart.erro}`, - }; - } +// if (!resultadoRestart.sucesso) { +// return { +// sucesso: false as const, +// erro: `Erro ao reiniciar containers: ${resultadoRestart.erro}`, +// }; +// } - detalhes.push(`✓ Containers Docker reiniciados`); - } +// detalhes.push(`✓ Containers Docker reiniciados`); +// } - // Atualizar timestamp de configuração no servidor - await ctx.runMutation(internal.configuracaoJitsi.marcarConfiguradoNoServidor, { - configId: args.configId, - }); +// // Atualizar timestamp de configuração no servidor +// await ctx.runMutation(internal.configuracaoJitsi.marcarConfiguradoNoServidor, { +// configId: args.configId, +// }); - return { - sucesso: true as const, - mensagem: "Configurações aplicadas com sucesso no servidor Jitsi", - detalhes: detalhes.join("\n"), - }; - } catch (error: unknown) { - const errorMessage = error instanceof Error ? error.message : String(error); - return { - sucesso: false as const, - erro: `Erro ao aplicar configurações: ${errorMessage}`, - }; - } - }, -}); +// return { +// sucesso: true as const, +// mensagem: "Configurações aplicadas com sucesso no servidor Jitsi", +// detalhes: detalhes.join("\n"), +// }; +// } catch (error: unknown) { +// const errorMessage = error instanceof Error ? error.message : String(error); +// return { +// sucesso: false as const, +// erro: `Erro ao aplicar configurações: ${errorMessage}`, +// }; +// } +// }, +// }); -/** - * Testar conexão SSH - */ -export const testarConexaoSSH = action({ - args: { - sshHost: v.string(), - sshPort: v.optional(v.number()), - sshUsername: v.string(), - sshPassword: v.optional(v.string()), - sshKeyPath: v.optional(v.string()), - }, - returns: v.union( - v.object({ sucesso: v.literal(true), mensagem: v.string() }), - v.object({ sucesso: v.literal(false), erro: v.string() }) - ), - handler: async (ctx, args): Promise< - | { sucesso: true; mensagem: string } - | { sucesso: false; erro: string } - > => { - try { - if (!args.sshPassword && !args.sshKeyPath) { - return { - sucesso: false as const, - erro: "Senha SSH ou caminho da chave deve ser fornecido", - }; - } +// /** +// * Testar conexão SSH +// */ +// export const testarConexaoSSH = action({ +// args: { +// sshHost: v.string(), +// sshPort: v.optional(v.number()), +// sshUsername: v.string(), +// sshPassword: v.optional(v.string()), +// sshKeyPath: v.optional(v.string()), +// }, +// returns: v.union( +// v.object({ sucesso: v.literal(true), mensagem: v.string() }), +// v.object({ sucesso: v.literal(false), erro: v.string() }) +// ), +// handler: async (ctx, args): Promise< +// | { sucesso: true; mensagem: string } +// | { sucesso: false; erro: string } +// > => { +// try { +// if (!args.sshPassword && !args.sshKeyPath) { +// return { +// sucesso: false as const, +// erro: "Senha SSH ou caminho da chave deve ser fornecido", +// }; +// } - const sshConfig: SSHConfig = { - host: args.sshHost, - port: args.sshPort || 22, - username: args.sshUsername, - password: args.sshPassword || undefined, - keyPath: args.sshKeyPath || undefined, - }; +// const sshConfig: SSHConfig = { +// host: args.sshHost, +// port: args.sshPort || 22, +// username: args.sshUsername, +// password: args.sshPassword || undefined, +// keyPath: args.sshKeyPath || undefined, +// }; - // Tentar executar um comando simples - const resultado = await executarComandoSSH(sshConfig, "echo 'SSH_OK'"); +// // Tentar executar um comando simples +// const resultado = await executarComandoSSH(sshConfig, "echo 'SSH_OK'"); - if (resultado.sucesso && resultado.output.includes("SSH_OK")) { - return { - sucesso: true as const, - mensagem: "Conexão SSH estabelecida com sucesso", - }; - } +// if (resultado.sucesso && resultado.output.includes("SSH_OK")) { +// return { +// sucesso: true as const, +// mensagem: "Conexão SSH estabelecida com sucesso", +// }; +// } - return { - sucesso: false as const, - erro: resultado.erro || "Falha ao estabelecer conexão SSH", - }; - } catch (error: unknown) { - const errorMessage = error instanceof Error ? error.message : String(error); - return { - sucesso: false as const, - erro: `Erro ao testar SSH: ${errorMessage}`, - }; - } - }, -}); +// return { +// sucesso: false as const, +// erro: resultado.erro || "Falha ao estabelecer conexão SSH", +// }; +// } catch (error: unknown) { +// const errorMessage = error instanceof Error ? error.message : String(error); +// return { +// sucesso: false as const, +// erro: `Erro ao testar SSH: ${errorMessage}`, +// }; +// } +// }, +// }); diff --git a/packages/backend/package.json b/packages/backend/package.json index 8b2c439..13e08b9 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -28,7 +28,6 @@ "@types/ssh2": "^1.15.5", "better-auth": "catalog:", "convex": "catalog:", - "nodemailer": "^7.0.10", - "ssh2": "^1.17.0" + "nodemailer": "^7.0.10" } } \ No newline at end of file