From bc91bb313277e436afb8c8bc4a2dee686759913f Mon Sep 17 00:00:00 2001 From: Dominik Koch Date: Sat, 26 Oct 2024 12:28:40 +0200 Subject: [PATCH 01/20] fix: use ! syntax instead of || "" --- .../dashboard/settings/billing/show-billing.tsx | 2 +- apps/dokploy/migration.ts | 2 +- apps/dokploy/pages/api/stripe/webhook.ts | 4 ++-- apps/dokploy/server/api/routers/auth.ts | 8 ++++---- apps/dokploy/server/api/routers/stripe.ts | 6 +++--- apps/dokploy/server/db/drizzle.config.ts | 2 +- apps/dokploy/server/db/index.ts | 4 ++-- apps/dokploy/server/db/migration.ts | 2 +- apps/dokploy/server/db/reset.ts | 2 +- apps/dokploy/server/db/seed.ts | 2 +- apps/dokploy/server/utils/stripe.ts | 4 ++-- apps/schedules/src/queue.ts | 2 +- packages/server/src/db/drizzle.config.ts | 2 +- packages/server/src/db/index.ts | 4 ++-- packages/server/src/db/migration.ts | 2 +- packages/server/src/db/reset.ts | 2 +- packages/server/src/db/seed.ts | 2 +- packages/server/src/emails/emails/notion-magic-link.tsx | 4 +--- .../server/src/emails/emails/plaid-verify-identity.tsx | 4 +--- packages/server/src/emails/emails/stripe-welcome.tsx | 4 +--- packages/server/src/emails/emails/vercel-invite-user.tsx | 4 +--- packages/server/src/setup/traefik-setup.ts | 4 ++-- 22 files changed, 32 insertions(+), 40 deletions(-) diff --git a/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx b/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx index a022d87c..08b820b1 100644 --- a/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx +++ b/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx @@ -10,7 +10,7 @@ import { AlertTriangle, CheckIcon, MinusIcon, PlusIcon } from "lucide-react"; import React, { useState } from "react"; const stripePromise = loadStripe( - process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || "", + process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!, ); export const calculatePrice = (count: number, isAnnual = false) => { diff --git a/apps/dokploy/migration.ts b/apps/dokploy/migration.ts index ff1b31d0..d52066c8 100644 --- a/apps/dokploy/migration.ts +++ b/apps/dokploy/migration.ts @@ -2,7 +2,7 @@ import { drizzle } from "drizzle-orm/postgres-js"; import { migrate } from "drizzle-orm/postgres-js/migrator"; import postgres from "postgres"; -const connectionString = process.env.DATABASE_URL || ""; +const connectionString = process.env.DATABASE_URL!; const sql = postgres(connectionString, { max: 1 }); const db = drizzle(sql); diff --git a/apps/dokploy/pages/api/stripe/webhook.ts b/apps/dokploy/pages/api/stripe/webhook.ts index 96e414d9..c6364d94 100644 --- a/apps/dokploy/pages/api/stripe/webhook.ts +++ b/apps/dokploy/pages/api/stripe/webhook.ts @@ -6,7 +6,7 @@ import { asc, eq } from "drizzle-orm"; import type { NextApiRequest, NextApiResponse } from "next"; import Stripe from "stripe"; -const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET || ""; +const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET!; export const config = { api: { @@ -21,7 +21,7 @@ export default async function handler( if (!endpointSecret) { return res.status(400).send("Webhook Error: Missing Stripe Secret Key"); } - const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", { + const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: "2024-09-30.acacia", maxNetworkRetries: 3, }); diff --git a/apps/dokploy/server/api/routers/auth.ts b/apps/dokploy/server/api/routers/auth.ts index 5315800e..9d0f2876 100644 --- a/apps/dokploy/server/api/routers/auth.ts +++ b/apps/dokploy/server/api/routers/auth.ts @@ -272,12 +272,12 @@ export const authRouter = createTRPCRouter({ const email = await sendEmailNotification( { - fromAddress: process.env.SMTP_FROM_ADDRESS || "", + fromAddress: process.env.SMTP_FROM_ADDRESS!, toAddresses: [authR.email], - smtpServer: process.env.SMTP_SERVER || "", + smtpServer: process.env.SMTP_SERVER!, smtpPort: Number(process.env.SMTP_PORT), - username: process.env.SMTP_USERNAME || "", - password: process.env.SMTP_PASSWORD || "", + username: process.env.SMTP_USERNAME!, + password: process.env.SMTP_PASSWORD!, }, "Reset Password", ` diff --git a/apps/dokploy/server/api/routers/stripe.ts b/apps/dokploy/server/api/routers/stripe.ts index f897e03f..ccfa162f 100644 --- a/apps/dokploy/server/api/routers/stripe.ts +++ b/apps/dokploy/server/api/routers/stripe.ts @@ -15,7 +15,7 @@ export const stripeRouter = createTRPCRouter({ const admin = await findAdminById(ctx.user.adminId); const stripeCustomerId = admin.stripeCustomerId; - const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", { + const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: "2024-09-30.acacia", }); @@ -51,7 +51,7 @@ export const stripeRouter = createTRPCRouter({ }), ) .mutation(async ({ ctx, input }) => { - const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", { + const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: "2024-09-30.acacia", }); @@ -98,7 +98,7 @@ export const stripeRouter = createTRPCRouter({ } const stripeCustomerId = admin.stripeCustomerId; - const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", { + const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: "2024-09-30.acacia", }); diff --git a/apps/dokploy/server/db/drizzle.config.ts b/apps/dokploy/server/db/drizzle.config.ts index f556649b..60a3bb93 100644 --- a/apps/dokploy/server/db/drizzle.config.ts +++ b/apps/dokploy/server/db/drizzle.config.ts @@ -4,7 +4,7 @@ export default defineConfig({ schema: "./server/db/schema/index.ts", dialect: "postgresql", dbCredentials: { - url: process.env.DATABASE_URL || "", + url: process.env.DATABASE_URL!, }, out: "drizzle", migrations: { diff --git a/apps/dokploy/server/db/index.ts b/apps/dokploy/server/db/index.ts index 4ebcc38a..e153d689 100644 --- a/apps/dokploy/server/db/index.ts +++ b/apps/dokploy/server/db/index.ts @@ -8,12 +8,12 @@ declare global { export let db: PostgresJsDatabase; if (process.env.NODE_ENV === "production") { - db = drizzle(postgres(process.env.DATABASE_URL || ""), { + db = drizzle(postgres(process.env.DATABASE_URL!), { schema, }); } else { if (!global.db) - global.db = drizzle(postgres(process.env.DATABASE_URL || ""), { + global.db = drizzle(postgres(process.env.DATABASE_URL!), { schema, }); diff --git a/apps/dokploy/server/db/migration.ts b/apps/dokploy/server/db/migration.ts index d38d3943..fa2e1a80 100644 --- a/apps/dokploy/server/db/migration.ts +++ b/apps/dokploy/server/db/migration.ts @@ -2,7 +2,7 @@ import { drizzle } from "drizzle-orm/postgres-js"; import { migrate } from "drizzle-orm/postgres-js/migrator"; import postgres from "postgres"; -const connectionString = process.env.DATABASE_URL || ""; +const connectionString = process.env.DATABASE_URL!; const sql = postgres(connectionString, { max: 1 }); const db = drizzle(sql); diff --git a/apps/dokploy/server/db/reset.ts b/apps/dokploy/server/db/reset.ts index 4a4dbecb..7497bec3 100644 --- a/apps/dokploy/server/db/reset.ts +++ b/apps/dokploy/server/db/reset.ts @@ -3,7 +3,7 @@ import { sql } from "drizzle-orm"; import { drizzle } from "drizzle-orm/postgres-js"; import postgres from "postgres"; -const connectionString = process.env.DATABASE_URL || ""; +const connectionString = process.env.DATABASE_URL!; const pg = postgres(connectionString, { max: 1 }); const db = drizzle(pg); diff --git a/apps/dokploy/server/db/seed.ts b/apps/dokploy/server/db/seed.ts index bbb3c3f2..b7935079 100644 --- a/apps/dokploy/server/db/seed.ts +++ b/apps/dokploy/server/db/seed.ts @@ -3,7 +3,7 @@ import { drizzle } from "drizzle-orm/postgres-js"; import postgres from "postgres"; import { users } from "./schema"; -const connectionString = process.env.DATABASE_URL || ""; +const connectionString = process.env.DATABASE_URL!; const pg = postgres(connectionString, { max: 1 }); const db = drizzle(pg); diff --git a/apps/dokploy/server/utils/stripe.ts b/apps/dokploy/server/utils/stripe.ts index b5af6a0b..9e3e751a 100644 --- a/apps/dokploy/server/utils/stripe.ts +++ b/apps/dokploy/server/utils/stripe.ts @@ -3,9 +3,9 @@ export const WEBSITE_URL = ? "http://localhost:3000" : process.env.SITE_URL; -const BASE_PRICE_MONTHLY_ID = process.env.BASE_PRICE_MONTHLY_ID || ""; // $4.00 +const BASE_PRICE_MONTHLY_ID = process.env.BASE_PRICE_MONTHLY_ID!; // $4.00 -const BASE_ANNUAL_MONTHLY_ID = process.env.BASE_ANNUAL_MONTHLY_ID || ""; // $7.99 +const BASE_ANNUAL_MONTHLY_ID = process.env.BASE_ANNUAL_MONTHLY_ID!; // $7.99 export const getStripeItems = (serverQuantity: number, isAnnual: boolean) => { const items = []; diff --git a/apps/schedules/src/queue.ts b/apps/schedules/src/queue.ts index f8ecba7f..471b9a4a 100644 --- a/apps/schedules/src/queue.ts +++ b/apps/schedules/src/queue.ts @@ -3,7 +3,7 @@ import IORedis from "ioredis"; import { logger } from "./logger"; import type { QueueJob } from "./schema"; -export const connection = new IORedis(process.env.REDIS_URL || "", { +export const connection = new IORedis(process.env.REDIS_URL!, { maxRetriesPerRequest: null, }); export const jobQueue = new Queue("backupQueue", { diff --git a/packages/server/src/db/drizzle.config.ts b/packages/server/src/db/drizzle.config.ts index f556649b..60a3bb93 100644 --- a/packages/server/src/db/drizzle.config.ts +++ b/packages/server/src/db/drizzle.config.ts @@ -4,7 +4,7 @@ export default defineConfig({ schema: "./server/db/schema/index.ts", dialect: "postgresql", dbCredentials: { - url: process.env.DATABASE_URL || "", + url: process.env.DATABASE_URL!, }, out: "drizzle", migrations: { diff --git a/packages/server/src/db/index.ts b/packages/server/src/db/index.ts index c8153144..d5e1d712 100644 --- a/packages/server/src/db/index.ts +++ b/packages/server/src/db/index.ts @@ -7,12 +7,12 @@ declare global { export let db: PostgresJsDatabase; if (process.env.NODE_ENV === "production") { - db = drizzle(postgres(process.env.DATABASE_URL || ""), { + db = drizzle(postgres(process.env.DATABASE_URL!), { schema, }); } else { if (!global.db) - global.db = drizzle(postgres(process.env.DATABASE_URL || ""), { + global.db = drizzle(postgres(process.env.DATABASE_URL!), { schema, }); diff --git a/packages/server/src/db/migration.ts b/packages/server/src/db/migration.ts index 75a79b34..6fada083 100644 --- a/packages/server/src/db/migration.ts +++ b/packages/server/src/db/migration.ts @@ -2,7 +2,7 @@ // import { migrate } from "drizzle-orm/postgres-js/migrator"; // import postgres from "postgres"; -// const connectionString = process.env.DATABASE_URL || ""; +// const connectionString = process.env.DATABASE_URL!; // const sql = postgres(connectionString, { max: 1 }); // const db = drizzle(sql); diff --git a/packages/server/src/db/reset.ts b/packages/server/src/db/reset.ts index 4a4dbecb..7497bec3 100644 --- a/packages/server/src/db/reset.ts +++ b/packages/server/src/db/reset.ts @@ -3,7 +3,7 @@ import { sql } from "drizzle-orm"; import { drizzle } from "drizzle-orm/postgres-js"; import postgres from "postgres"; -const connectionString = process.env.DATABASE_URL || ""; +const connectionString = process.env.DATABASE_URL!; const pg = postgres(connectionString, { max: 1 }); const db = drizzle(pg); diff --git a/packages/server/src/db/seed.ts b/packages/server/src/db/seed.ts index 9e19cb0f..7e2736b0 100644 --- a/packages/server/src/db/seed.ts +++ b/packages/server/src/db/seed.ts @@ -3,7 +3,7 @@ // import postgres from "postgres"; // import { users } from "./schema"; -// const connectionString = process.env.DATABASE_URL || ""; +// const connectionString = process.env.DATABASE_URL!; // const pg = postgres(connectionString, { max: 1 }); // const db = drizzle(pg); diff --git a/packages/server/src/emails/emails/notion-magic-link.tsx b/packages/server/src/emails/emails/notion-magic-link.tsx index 89cc3444..a8dc4337 100644 --- a/packages/server/src/emails/emails/notion-magic-link.tsx +++ b/packages/server/src/emails/emails/notion-magic-link.tsx @@ -15,9 +15,7 @@ interface NotionMagicLinkEmailProps { loginCode?: string; } -const baseUrl = process.env.VERCEL_URL - ? `https://${process.env.VERCEL_URL}` - : ""; +const baseUrl = process.env.VERCEL_URL! export const NotionMagicLinkEmail = ({ loginCode, diff --git a/packages/server/src/emails/emails/plaid-verify-identity.tsx b/packages/server/src/emails/emails/plaid-verify-identity.tsx index 2fce846a..25661325 100644 --- a/packages/server/src/emails/emails/plaid-verify-identity.tsx +++ b/packages/server/src/emails/emails/plaid-verify-identity.tsx @@ -15,9 +15,7 @@ interface PlaidVerifyIdentityEmailProps { validationCode?: string; } -const baseUrl = process.env.VERCEL_URL - ? `https://${process.env.VERCEL_URL}` - : ""; +const baseUrl = process.env.VERCEL_URL! export const PlaidVerifyIdentityEmail = ({ validationCode, diff --git a/packages/server/src/emails/emails/stripe-welcome.tsx b/packages/server/src/emails/emails/stripe-welcome.tsx index 232f4a2c..de21cf24 100644 --- a/packages/server/src/emails/emails/stripe-welcome.tsx +++ b/packages/server/src/emails/emails/stripe-welcome.tsx @@ -13,9 +13,7 @@ import { } from "@react-email/components"; import * as React from "react"; -const baseUrl = process.env.VERCEL_URL - ? `https://${process.env.VERCEL_URL}` - : ""; +const baseUrl = process.env.VERCEL_URL! export const StripeWelcomeEmail = () => ( diff --git a/packages/server/src/emails/emails/vercel-invite-user.tsx b/packages/server/src/emails/emails/vercel-invite-user.tsx index bd7404ab..ffc29bb2 100644 --- a/packages/server/src/emails/emails/vercel-invite-user.tsx +++ b/packages/server/src/emails/emails/vercel-invite-user.tsx @@ -29,9 +29,7 @@ interface VercelInviteUserEmailProps { inviteFromLocation?: string; } -const baseUrl = process.env.VERCEL_URL - ? `https://${process.env.VERCEL_URL}` - : ""; +const baseUrl = process.env.VERCEL_URL! export const VercelInviteUserEmail = ({ username, diff --git a/packages/server/src/setup/traefik-setup.ts b/packages/server/src/setup/traefik-setup.ts index 27bc99a4..82832027 100644 --- a/packages/server/src/setup/traefik-setup.ts +++ b/packages/server/src/setup/traefik-setup.ts @@ -9,8 +9,8 @@ import type { FileConfig } from "../utils/traefik/file-types"; import type { MainTraefikConfig } from "../utils/traefik/types"; const TRAEFIK_SSL_PORT = - Number.parseInt(process.env.TRAEFIK_SSL_PORT ?? "", 10) || 443; -const TRAEFIK_PORT = Number.parseInt(process.env.TRAEFIK_PORT ?? "", 10) || 80; + Number.parseInt(process.env.TRAEFIK_SSL_PORT!, 10) || 443; +const TRAEFIK_PORT = Number.parseInt(process.env.TRAEFIK_PORT!, 10) || 80; interface TraefikOptions { enableDashboard?: boolean; From 5f13fb2316a9220bdb9157c5556fc87f362b732e Mon Sep 17 00:00:00 2001 From: Dominik Koch Date: Sat, 26 Oct 2024 12:42:23 +0200 Subject: [PATCH 02/20] style: lint code --- packages/server/src/emails/emails/notion-magic-link.tsx | 2 +- packages/server/src/emails/emails/plaid-verify-identity.tsx | 2 +- packages/server/src/emails/emails/stripe-welcome.tsx | 2 +- packages/server/src/emails/emails/vercel-invite-user.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/server/src/emails/emails/notion-magic-link.tsx b/packages/server/src/emails/emails/notion-magic-link.tsx index a8dc4337..b2286c34 100644 --- a/packages/server/src/emails/emails/notion-magic-link.tsx +++ b/packages/server/src/emails/emails/notion-magic-link.tsx @@ -15,7 +15,7 @@ interface NotionMagicLinkEmailProps { loginCode?: string; } -const baseUrl = process.env.VERCEL_URL! +const baseUrl = process.env.VERCEL_URL!; export const NotionMagicLinkEmail = ({ loginCode, diff --git a/packages/server/src/emails/emails/plaid-verify-identity.tsx b/packages/server/src/emails/emails/plaid-verify-identity.tsx index 25661325..650ab486 100644 --- a/packages/server/src/emails/emails/plaid-verify-identity.tsx +++ b/packages/server/src/emails/emails/plaid-verify-identity.tsx @@ -15,7 +15,7 @@ interface PlaidVerifyIdentityEmailProps { validationCode?: string; } -const baseUrl = process.env.VERCEL_URL! +const baseUrl = process.env.VERCEL_URL!; export const PlaidVerifyIdentityEmail = ({ validationCode, diff --git a/packages/server/src/emails/emails/stripe-welcome.tsx b/packages/server/src/emails/emails/stripe-welcome.tsx index de21cf24..9377853b 100644 --- a/packages/server/src/emails/emails/stripe-welcome.tsx +++ b/packages/server/src/emails/emails/stripe-welcome.tsx @@ -13,7 +13,7 @@ import { } from "@react-email/components"; import * as React from "react"; -const baseUrl = process.env.VERCEL_URL! +const baseUrl = process.env.VERCEL_URL!; export const StripeWelcomeEmail = () => ( diff --git a/packages/server/src/emails/emails/vercel-invite-user.tsx b/packages/server/src/emails/emails/vercel-invite-user.tsx index ffc29bb2..53b31987 100644 --- a/packages/server/src/emails/emails/vercel-invite-user.tsx +++ b/packages/server/src/emails/emails/vercel-invite-user.tsx @@ -29,7 +29,7 @@ interface VercelInviteUserEmailProps { inviteFromLocation?: string; } -const baseUrl = process.env.VERCEL_URL! +const baseUrl = process.env.VERCEL_URL!; export const VercelInviteUserEmail = ({ username, From 0873618c63bccce4e1c1e4c4e1b30d181f48bddf Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:08:49 -0600 Subject: [PATCH 03/20] chore(dokploy): set latest tag in cloud --- .github/workflows/deploy.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 987800f9..a7b60213 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -70,7 +70,7 @@ jobs: file: ./Dockerfile.cloud push: true tags: | - siumauricio/cloud:${{ github.ref_name == 'main' && 'main' || 'canary' }} + siumauricio/cloud:${{ github.ref_name == 'main' && 'latest' || 'canary' }} platforms: linux/amd64 build-args: | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${{ github.ref_name == 'main' && 'pk_live_51QAm7bF3cxQuHeOzMpfNfJIch6oLif8rS32pRE392CdTbBf0MYBdbapAxarQGspqJBWT2nVOxu8e6ZHrHB4NhVHG008DE2A90d' || 'pk_test_51QAm7bF3cxQuHeOz0xg04o9teeyTbbNHQPJ5Tr98MlTEan9MzewT3gwh0jSWBNvrRWZ5vASoBgxUSF4gPWsJwATk00Ir2JZ0S1' }} @@ -95,7 +95,7 @@ jobs: file: ./Dockerfile.schedule push: true tags: | - siumauricio/schedule:${{ github.ref_name == 'main' && 'main' || 'canary' }} + siumauricio/schedule:${{ github.ref_name == 'main' && 'latest' || 'canary' }} platforms: linux/amd64 @@ -119,5 +119,5 @@ jobs: file: ./Dockerfile.server push: true tags: | - siumauricio/server:${{ github.ref_name == 'main' && 'main' || 'canary' }} + siumauricio/server:${{ github.ref_name == 'main' && 'latest' || 'canary' }} platforms: linux/amd64 \ No newline at end of file From 27c33c76614d2650d60dff695b8b89790660ae35 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:48:30 -0600 Subject: [PATCH 04/20] fix(server): update build paths --- apps/api/src/types.ts | 16 ----------- apps/api/src/utils.ts | 35 +------------------------ apps/schedules/src/utils.ts | 2 +- packages/server/package.json | 12 --------- packages/server/scripts/switchToDist.js | 14 ++++++++++ packages/server/scripts/switchToSrc.js | 15 ++--------- 6 files changed, 18 insertions(+), 76 deletions(-) delete mode 100644 apps/api/src/types.ts diff --git a/apps/api/src/types.ts b/apps/api/src/types.ts deleted file mode 100644 index 2547432b..00000000 --- a/apps/api/src/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -export interface LemonSqueezyLicenseResponse { - valid: boolean; - error?: string; - meta?: { - store_id: string; - order_id: number; - order_item_id: number; - product_id: number; - product_name: string; - variant_id: number; - variant_name: string; - customer_id: number; - customer_name: string; - customer_email: string; - }; -} diff --git a/apps/api/src/utils.ts b/apps/api/src/utils.ts index 5d776a5c..03c836e0 100644 --- a/apps/api/src/utils.ts +++ b/apps/api/src/utils.ts @@ -1,45 +1,12 @@ import { - deployApplication, - deployCompose, deployRemoteApplication, deployRemoteCompose, - rebuildApplication, - rebuildCompose, rebuildRemoteApplication, rebuildRemoteCompose, updateApplicationStatus, updateCompose, -} from "@dokploy/server/dist"; +} from "@dokploy/server"; import type { DeployJob } from "./schema"; -import type { LemonSqueezyLicenseResponse } from "./types"; - -// const LEMON_SQUEEZY_API_KEY = process.env.LEMON_SQUEEZY_API_KEY; -// const LEMON_SQUEEZY_STORE_ID = process.env.LEMON_SQUEEZY_STORE_ID; -// export const validateLemonSqueezyLicense = async ( -// licenseKey: string, -// ): Promise => { -// try { -// const response = await fetch( -// "https://api.lemonsqueezy.com/v1/licenses/validate", -// { -// method: "POST", -// headers: { -// "Content-Type": "application/json", -// "x-api-key": LEMON_SQUEEZY_API_KEY as string, -// }, -// body: JSON.stringify({ -// license_key: licenseKey, -// store_id: LEMON_SQUEEZY_STORE_ID as string, -// }), -// }, -// ); - -// return response.json(); -// } catch (error) { -// console.error("Error validating license:", error); -// return { valid: false, error: "Error validating license" }; -// } -// }; export const deploy = async (job: DeployJob) => { try { diff --git a/apps/schedules/src/utils.ts b/apps/schedules/src/utils.ts index 07cefeef..65f3cbda 100644 --- a/apps/schedules/src/utils.ts +++ b/apps/schedules/src/utils.ts @@ -8,7 +8,7 @@ import { runMongoBackup, runMySqlBackup, runPostgresBackup, -} from "@dokploy/server/dist"; +} from "@dokploy/server"; import { db } from "@dokploy/server/dist/db"; import { backups, server } from "@dokploy/server/dist/db/schema"; import { eq } from "drizzle-orm"; diff --git a/packages/server/package.json b/packages/server/package.json index 6772f035..e9064582 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -16,18 +16,6 @@ "./constants": { "import": "./src/constants/index.ts", "require": "./dist/constants.cjs.js" - }, - "./dist": { - "import": "./dist/index.js", - "require": "./dist/index.cjs.js" - }, - "./dist/db": { - "import": "./dist/db/index.js", - "require": "./dist/db/*.cjs" - }, - "./dist/db/schema": { - "import": "./dist/db/schema/index.js", - "require": "./dist/db/schema/*.cjs" } }, "scripts": { diff --git a/packages/server/scripts/switchToDist.js b/packages/server/scripts/switchToDist.js index 12f5625a..67c9f411 100644 --- a/packages/server/scripts/switchToDist.js +++ b/packages/server/scripts/switchToDist.js @@ -8,6 +8,8 @@ const __dirname = path.dirname(__filename); const packagePath = path.resolve(__dirname, "../package.json"); const pkg = JSON.parse(fs.readFileSync(packagePath, "utf-8")); +pkg.main = "./dist/index.js"; + pkg.exports = { ".": { import: "./dist/index.js", @@ -21,6 +23,18 @@ pkg.exports = { import: "./dist/*", require: "./dist/*.cjs", }, + "./dist": { + import: "./dist/index.js", + require: "./dist/index.cjs.js", + }, + "./dist/db": { + import: "./dist/db/index.js", + require: "./dist/db/index.cjs.js", + }, + "./dist/db/schema": { + import: "./dist/db/schema/index.js", + require: "./dist/db/schema/index.cjs.js", + }, }; fs.writeFileSync(packagePath, JSON.stringify(pkg, null, 2)); diff --git a/packages/server/scripts/switchToSrc.js b/packages/server/scripts/switchToSrc.js index 9387cd15..b18c2d15 100644 --- a/packages/server/scripts/switchToSrc.js +++ b/packages/server/scripts/switchToSrc.js @@ -10,6 +10,8 @@ const packagePath = path.resolve(__dirname, "../package.json"); // Leer el archivo package.json const pkg = JSON.parse(fs.readFileSync(packagePath, "utf-8")); +pkg.main = "./src/index.ts"; + // Modificar los exports pkg.exports = { ".": "./src/index.ts", @@ -25,19 +27,6 @@ pkg.exports = { import: "./src/constants/index.ts", require: "./dist/constants.cjs.js", }, - "./dist": { - import: "./dist/index.js", - require: "./dist/index.cjs.js", - }, - - "./dist/db": { - import: "./dist/db/index.js", - require: "./dist/db/*.cjs", - }, - "./dist/db/schema": { - import: "./dist/db/schema/index.js", - require: "./dist/db/schema/*.cjs", - }, }; // Guardar los cambios en package.json From 5417f6376b16fa9d134a7be6d209533eec640ce8 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:56:03 -0600 Subject: [PATCH 05/20] chore(server): update switch prod in build command --- Dockerfile | 1 - Dockerfile.cloud | 1 - Dockerfile.schedule | 1 - Dockerfile.server | 1 - packages/server/package.json | 2 +- 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index bb5310f2..74b70db0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,6 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile # Deploy only the dokploy app ENV NODE_ENV=production -RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build RUN pnpm --filter=./apps/dokploy run build diff --git a/Dockerfile.cloud b/Dockerfile.cloud index 664180f7..8d80fb64 100644 --- a/Dockerfile.cloud +++ b/Dockerfile.cloud @@ -17,7 +17,6 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm --filter=@dokploy/server ARG NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY ENV NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=$NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY ENV NODE_ENV=production -RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build RUN pnpm --filter=./apps/dokploy run build diff --git a/Dockerfile.schedule b/Dockerfile.schedule index 36f06aef..5eca3420 100644 --- a/Dockerfile.schedule +++ b/Dockerfile.schedule @@ -15,7 +15,6 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm --filter=@dokploy/server # Deploy only the dokploy app ENV NODE_ENV=production -RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build RUN pnpm --filter=./apps/schedules run build diff --git a/Dockerfile.server b/Dockerfile.server index 9cf04b21..a25b22e5 100644 --- a/Dockerfile.server +++ b/Dockerfile.server @@ -15,7 +15,6 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm --filter=@dokploy/server # Deploy only the dokploy app ENV NODE_ENV=production -RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build RUN pnpm --filter=./apps/api run build diff --git a/packages/server/package.json b/packages/server/package.json index e9064582..4ebee48c 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -19,7 +19,7 @@ } }, "scripts": { - "build": "rm -rf ./dist && tsc --project tsconfig.server.json && tsc-alias -p tsconfig.server.json", + "build": "npm run switch:prod && rm -rf ./dist && tsc --project tsconfig.server.json && tsc-alias -p tsconfig.server.json", "build:types": "tsc --emitDeclarationOnly --experimenta-dts", "switch:dev": "node scripts/switchToSrc.js", "switch:prod": "node scripts/switchToDist.js", From 4b5408c05049ec71c487c5f8cceb015ae29adf23 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 26 Oct 2024 16:04:43 -0600 Subject: [PATCH 06/20] chore: lint From 78659b2ad9cb73b5c32a4e1d0686b6a9648756d4 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 26 Oct 2024 16:17:20 -0600 Subject: [PATCH 07/20] chore: exclude package.json to format --- biome.json | 9 +- packages/server/package.json | 180 +++++++++++++++++------------------ 2 files changed, 98 insertions(+), 91 deletions(-) diff --git a/biome.json b/biome.json index b6f6c417..f5a6c232 100644 --- a/biome.json +++ b/biome.json @@ -1,7 +1,14 @@ { "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", "files": { - "ignore": ["node_modules/**", ".next/**", "drizzle/**", ".docker", "dist"] + "ignore": [ + "node_modules/**", + ".next/**", + "drizzle/**", + ".docker", + "dist", + "packages/server/package.json" + ] }, "organizeImports": { "enabled": true diff --git a/packages/server/package.json b/packages/server/package.json index 4ebee48c..f21a82c4 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,91 +1,91 @@ { - "name": "@dokploy/server", - "version": "1.0.0", - "main": "./src/index.ts", - "type": "module", - "exports": { - ".": "./src/index.ts", - "./db": { - "import": "./src/db/index.ts", - "require": "./dist/db/index.cjs.js" - }, - "./setup/*": { - "import": "./src/setup/*.ts", - "require": "./dist/setup/index.cjs.js" - }, - "./constants": { - "import": "./src/constants/index.ts", - "require": "./dist/constants.cjs.js" - } - }, - "scripts": { - "build": "npm run switch:prod && rm -rf ./dist && tsc --project tsconfig.server.json && tsc-alias -p tsconfig.server.json", - "build:types": "tsc --emitDeclarationOnly --experimenta-dts", - "switch:dev": "node scripts/switchToSrc.js", - "switch:prod": "node scripts/switchToDist.js", - "dev": "rm -rf ./dist && pnpm esbuild && tsc --emitDeclarationOnly --outDir dist -p tsconfig.server.json", - "esbuild": "tsx ./esbuild.config.ts && tsc --project tsconfig.server.json --emitDeclarationOnly ", - "typecheck": "tsc --noEmit" - }, - "dependencies": { - "rotating-file-stream": "3.2.3", - "@faker-js/faker": "^8.4.1", - "@lucia-auth/adapter-drizzle": "1.0.7", - "@octokit/auth-app": "^6.0.4", - "@react-email/components": "^0.0.21", - "@trpc/server": "^10.43.6", - "adm-zip": "^0.5.14", - "bcrypt": "5.1.1", - "bl": "6.0.11", - "boxen": "^7.1.1", - "date-fns": "3.6.0", - "dockerode": "4.0.2", - "dotenv": "16.4.5", - "drizzle-orm": "^0.30.8", - "drizzle-zod": "0.5.1", - "hi-base32": "^0.5.1", - "js-yaml": "4.1.0", - "lodash": "4.17.21", - "lucia": "^3.0.1", - "nanoid": "3", - "node-os-utils": "1.3.7", - "node-pty": "1.0.0", - "node-schedule": "2.1.1", - "nodemailer": "6.9.14", - "octokit": "3.1.2", - "otpauth": "^9.2.3", - "postgres": "3.4.4", - "public-ip": "6.0.2", - "qrcode": "^1.5.3", - "react": "18.2.0", - "react-dom": "18.2.0", - "slugify": "^1.6.6", - "ws": "8.16.0", - "zod": "^3.23.4", - "ssh2": "1.15.0" - }, - "devDependencies": { - "esbuild-plugin-alias": "0.2.1", - "tailwindcss": "^3.4.1", - "tsx": "^4.7.1", - "tsc-alias": "1.8.10", - "@types/adm-zip": "^0.5.5", - "@types/bcrypt": "5.0.2", - "@types/dockerode": "3.3.23", - "@types/js-yaml": "4.0.9", - "@types/lodash": "4.17.4", - "@types/node": "^18.17.0", - "@types/node-os-utils": "1.3.4", - "@types/node-schedule": "2.1.6", - "@types/nodemailer": "^6.4.15", - "@types/qrcode": "^1.5.5", - "@types/react": "^18.2.37", - "@types/react-dom": "^18.2.15", - "@types/ws": "8.5.10", - "drizzle-kit": "^0.21.1", - "esbuild": "0.20.2", - "postcss": "^8.4.31", - "typescript": "^5.4.2", - "@types/ssh2": "1.15.1" - } -} + "name": "@dokploy/server", + "version": "1.0.0", + "main": "./src/index.ts", + "type": "module", + "exports": { + ".": "./src/index.ts", + "./db": { + "import": "./src/db/index.ts", + "require": "./dist/db/index.cjs.js" + }, + "./setup/*": { + "import": "./src/setup/*.ts", + "require": "./dist/setup/index.cjs.js" + }, + "./constants": { + "import": "./src/constants/index.ts", + "require": "./dist/constants.cjs.js" + } + }, + "scripts": { + "build": "npm run switch:prod && rm -rf ./dist && tsc --project tsconfig.server.json && tsc-alias -p tsconfig.server.json", + "build:types": "tsc --emitDeclarationOnly --experimenta-dts", + "switch:dev": "node scripts/switchToSrc.js", + "switch:prod": "node scripts/switchToDist.js", + "dev": "rm -rf ./dist && pnpm esbuild && tsc --emitDeclarationOnly --outDir dist -p tsconfig.server.json", + "esbuild": "tsx ./esbuild.config.ts && tsc --project tsconfig.server.json --emitDeclarationOnly ", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "rotating-file-stream": "3.2.3", + "@faker-js/faker": "^8.4.1", + "@lucia-auth/adapter-drizzle": "1.0.7", + "@octokit/auth-app": "^6.0.4", + "@react-email/components": "^0.0.21", + "@trpc/server": "^10.43.6", + "adm-zip": "^0.5.14", + "bcrypt": "5.1.1", + "bl": "6.0.11", + "boxen": "^7.1.1", + "date-fns": "3.6.0", + "dockerode": "4.0.2", + "dotenv": "16.4.5", + "drizzle-orm": "^0.30.8", + "drizzle-zod": "0.5.1", + "hi-base32": "^0.5.1", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "lucia": "^3.0.1", + "nanoid": "3", + "node-os-utils": "1.3.7", + "node-pty": "1.0.0", + "node-schedule": "2.1.1", + "nodemailer": "6.9.14", + "octokit": "3.1.2", + "otpauth": "^9.2.3", + "postgres": "3.4.4", + "public-ip": "6.0.2", + "qrcode": "^1.5.3", + "react": "18.2.0", + "react-dom": "18.2.0", + "slugify": "^1.6.6", + "ws": "8.16.0", + "zod": "^3.23.4", + "ssh2": "1.15.0" + }, + "devDependencies": { + "esbuild-plugin-alias": "0.2.1", + "tailwindcss": "^3.4.1", + "tsx": "^4.7.1", + "tsc-alias": "1.8.10", + "@types/adm-zip": "^0.5.5", + "@types/bcrypt": "5.0.2", + "@types/dockerode": "3.3.23", + "@types/js-yaml": "4.0.9", + "@types/lodash": "4.17.4", + "@types/node": "^18.17.0", + "@types/node-os-utils": "1.3.4", + "@types/node-schedule": "2.1.6", + "@types/nodemailer": "^6.4.15", + "@types/qrcode": "^1.5.5", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "@types/ws": "8.5.10", + "drizzle-kit": "^0.21.1", + "esbuild": "0.20.2", + "postcss": "^8.4.31", + "typescript": "^5.4.2", + "@types/ssh2": "1.15.1" + } +} \ No newline at end of file From 680c22a41ed5caa95fec867b5d690adf09c819a7 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:09:55 -0600 Subject: [PATCH 08/20] feat(dokploy): add verification email to cloud version --- .../settings/billing/show-billing.tsx | 308 +- .../settings/profile/profile-form.tsx | 4 +- .../dashboard/settings/users/add-user.tsx | 2 +- .../dashboard/settings/users/update-user.tsx | 162 - apps/dokploy/drizzle/0042_fancy_havok.sql | 2 + apps/dokploy/drizzle/meta/0042_snapshot.json | 3968 +++++++++++++++++ apps/dokploy/drizzle/meta/_journal.json | 7 + apps/dokploy/pages/confirm-email.tsx | 95 + apps/dokploy/pages/index.tsx | 10 +- apps/dokploy/pages/invitation.tsx | 33 +- apps/dokploy/pages/register.tsx | 18 +- apps/dokploy/server/api/routers/admin.ts | 1 - apps/dokploy/server/api/routers/auth.ts | 131 +- packages/server/src/db/schema/auth.ts | 2 + packages/server/src/services/admin.ts | 2 +- packages/server/src/services/auth.ts | 4 +- 16 files changed, 4419 insertions(+), 330 deletions(-) delete mode 100644 apps/dokploy/components/dashboard/settings/users/update-user.tsx create mode 100644 apps/dokploy/drizzle/0042_fancy_havok.sql create mode 100644 apps/dokploy/drizzle/meta/0042_snapshot.json create mode 100644 apps/dokploy/pages/confirm-email.tsx diff --git a/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx b/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx index a022d87c..ca684c68 100644 --- a/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx +++ b/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx @@ -6,7 +6,14 @@ import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; import { loadStripe } from "@stripe/stripe-js"; import clsx from "clsx"; -import { AlertTriangle, CheckIcon, MinusIcon, PlusIcon } from "lucide-react"; +import { + AlertTriangle, + CheckIcon, + Loader2, + MinusIcon, + PlusIcon, +} from "lucide-react"; +import Link from "next/link"; import React, { useState } from "react"; const stripePromise = loadStripe( @@ -24,7 +31,7 @@ export const calculatePrice = (count: number, isAnnual = false) => { export const ShowBilling = () => { const { data: servers } = api.server.all.useQuery(undefined); const { data: admin } = api.admin.one.useQuery(); - const { data } = api.stripe.getProducts.useQuery(); + const { data, isLoading } = api.stripe.getProducts.useQuery(); const { mutateAsync: createCheckoutSession } = api.stripe.createCheckoutSession.useMutation(); @@ -96,145 +103,186 @@ export const ShowBilling = () => { )} )} - {products?.map((product) => { - const featured = true; - return ( -
-
+ + Need Help? We are here to help you. + + + Join to our Discord server and we will help you. + + - { - setServerQuantity(e.target.value as unknown as number); - }} - /> - - -
-
0 - ? "justify-between" - : "justify-end", - "flex flex-row items-center gap-2 mt-4", + + + Join Discord + + +
+ {isLoading ? ( + + Loading... + + + ) : ( + <> + {products?.map((product) => { + const featured = true; + return ( +
+
- {admin?.stripeCustomerId && ( - + {isAnnual ? ( +
+

+ $ {calculatePrice(serverQuantity, isAnnual).toFixed(2)}{" "} + USD +

+ | +

+ ${" "} + {( + calculatePrice(serverQuantity, isAnnual) / 12 + ).toFixed(2)}{" "} + / Month USD +

+
+ ) : ( +

+ $ {calculatePrice(serverQuantity, isAnnual).toFixed(2)}{" "} + USD +

)} +

+ {product.name} +

+

+ {product.description} +

- {data?.subscriptions?.length === 0 && ( -
+
    + {[ + "All the features of Dokploy", + "Unlimited deployments", + "Self-hosted on your own infrastructure", + "Full access to all deployment features", + "Dokploy integration", + "Backups", + "All Incoming features", + ].map((feature) => ( +
  • + + {feature} +
  • + ))} +
+
+
+ + {serverQuantity} Servers + +
+ +
+ { + setServerQuantity( + e.target.value as unknown as number, + ); + }} + /> + +
- )} -
+
0 + ? "justify-between" + : "justify-end", + "flex flex-row items-center gap-2 mt-4", + )} + > + {admin?.stripeCustomerId && ( + + )} + + {data?.subscriptions?.length === 0 && ( +
+ +
+ )} +
+
+
- - - ); - })} + ); + })} + + )} ); }; diff --git a/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx b/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx index 43cd2f0e..3c8d51bb 100644 --- a/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx +++ b/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx @@ -52,8 +52,6 @@ export const ProfileForm = () => { const { data, refetch } = api.auth.get.useQuery(); const { mutateAsync, isLoading } = api.auth.update.useMutation(); - const { mutateAsync: generateToken, isLoading: isLoadingToken } = - api.auth.generateToken.useMutation(); const form = useForm({ defaultValues: { email: data?.email || "", @@ -76,7 +74,7 @@ export const ProfileForm = () => { const onSubmit = async (values: Profile) => { await mutateAsync({ - email: values.email, + email: values.email.toLowerCase(), password: values.password, image: values.image, }) diff --git a/apps/dokploy/components/dashboard/settings/users/add-user.tsx b/apps/dokploy/components/dashboard/settings/users/add-user.tsx index 16af8787..1643f37f 100644 --- a/apps/dokploy/components/dashboard/settings/users/add-user.tsx +++ b/apps/dokploy/components/dashboard/settings/users/add-user.tsx @@ -54,7 +54,7 @@ export const AddUser = () => { const onSubmit = async (data: AddUser) => { await mutateAsync({ - email: data.email, + email: data.email.toLowerCase(), }) .then(async () => { toast.success("Invitation created"); diff --git a/apps/dokploy/components/dashboard/settings/users/update-user.tsx b/apps/dokploy/components/dashboard/settings/users/update-user.tsx deleted file mode 100644 index 78ad2c1a..00000000 --- a/apps/dokploy/components/dashboard/settings/users/update-user.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import { AlertBlock } from "@/components/shared/alert-block"; -import { Button } from "@/components/ui/button"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; -import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { SquarePen } from "lucide-react"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; - -const updateUserSchema = z.object({ - email: z - .string() - .min(1, "Email is required") - .email({ message: "Invalid email" }), - password: z.string(), -}); - -type UpdateUser = z.infer; - -interface Props { - authId: string; -} - -export const UpdateUser = ({ authId }: Props) => { - const utils = api.useUtils(); - const { mutateAsync, error, isError, isLoading } = - api.auth.updateByAdmin.useMutation(); - const { data } = api.auth.one.useQuery( - { - id: authId, - }, - { - enabled: !!authId, - }, - ); - - const form = useForm({ - defaultValues: { - email: "", - password: "", - }, - resolver: zodResolver(updateUserSchema), - }); - useEffect(() => { - if (data) { - form.reset({ - email: data.email || "", - password: "", - }); - } - }, [data, form, form.reset]); - - const onSubmit = async (formData: UpdateUser) => { - await mutateAsync({ - email: formData.email === data?.email ? null : formData.email, - password: formData.password, - id: authId, - }) - .then(() => { - toast.success("User updated succesfully"); - utils.user.all.invalidate(); - }) - .catch(() => { - toast.error("Error to update the user"); - }) - .finally(() => {}); - }; - - return ( - - - - - - - Update User - Update the user - - {isError && {error?.message}} - -
-
-
- - ( - - Email - - - - - - - )} - /> - ( - - Password - - - - - - - )} - /> - - - - - -
-
-
-
- ); -}; diff --git a/apps/dokploy/drizzle/0042_fancy_havok.sql b/apps/dokploy/drizzle/0042_fancy_havok.sql new file mode 100644 index 00000000..a16ce816 --- /dev/null +++ b/apps/dokploy/drizzle/0042_fancy_havok.sql @@ -0,0 +1,2 @@ +ALTER TABLE "auth" ADD COLUMN "confirmationToken" text;--> statement-breakpoint +ALTER TABLE "auth" ADD COLUMN "confirmationExpiresAt" text; \ No newline at end of file diff --git a/apps/dokploy/drizzle/meta/0042_snapshot.json b/apps/dokploy/drizzle/meta/0042_snapshot.json new file mode 100644 index 00000000..9d8f76ef --- /dev/null +++ b/apps/dokploy/drizzle/meta/0042_snapshot.json @@ -0,0 +1,3968 @@ +{ + "id": "24bfb192-237f-4297-83d1-27988dcb6be2", + "prevId": "9933f3e8-77a2-40e6-b579-922fe6bb2cb6", + "version": "6", + "dialect": "postgresql", + "tables": { + "public.application": { + "name": "application", + "schema": "", + "columns": { + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buildArgs": { + "name": "buildArgs", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "subtitle": { + "name": "subtitle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refreshToken": { + "name": "refreshToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sourceType": { + "name": "sourceType", + "type": "sourceType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "repository": { + "name": "repository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owner": { + "name": "owner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buildPath": { + "name": "buildPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "autoDeploy": { + "name": "autoDeploy", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "gitlabProjectId": { + "name": "gitlabProjectId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "gitlabRepository": { + "name": "gitlabRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabOwner": { + "name": "gitlabOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabBranch": { + "name": "gitlabBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabBuildPath": { + "name": "gitlabBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "gitlabPathNamespace": { + "name": "gitlabPathNamespace", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketRepository": { + "name": "bitbucketRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketOwner": { + "name": "bitbucketOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketBranch": { + "name": "bitbucketBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketBuildPath": { + "name": "bitbucketBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitUrl": { + "name": "customGitUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitBranch": { + "name": "customGitBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitBuildPath": { + "name": "customGitBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitSSHKeyId": { + "name": "customGitSSHKeyId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerfile": { + "name": "dockerfile", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerContextPath": { + "name": "dockerContextPath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerBuildStage": { + "name": "dockerBuildStage", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dropBuildPath": { + "name": "dropBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "healthCheckSwarm": { + "name": "healthCheckSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "restartPolicySwarm": { + "name": "restartPolicySwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "placementSwarm": { + "name": "placementSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "updateConfigSwarm": { + "name": "updateConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "rollbackConfigSwarm": { + "name": "rollbackConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "modeSwarm": { + "name": "modeSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "labelsSwarm": { + "name": "labelsSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "networkSwarm": { + "name": "networkSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "replicas": { + "name": "replicas", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "buildType": { + "name": "buildType", + "type": "buildType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'nixpacks'" + }, + "publishDirectory": { + "name": "publishDirectory", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "registryId": { + "name": "registryId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "githubId": { + "name": "githubId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabId": { + "name": "gitlabId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketId": { + "name": "bitbucketId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "application_customGitSSHKeyId_ssh-key_sshKeyId_fk": { + "name": "application_customGitSSHKeyId_ssh-key_sshKeyId_fk", + "tableFrom": "application", + "tableTo": "ssh-key", + "columnsFrom": [ + "customGitSSHKeyId" + ], + "columnsTo": [ + "sshKeyId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_registryId_registry_registryId_fk": { + "name": "application_registryId_registry_registryId_fk", + "tableFrom": "application", + "tableTo": "registry", + "columnsFrom": [ + "registryId" + ], + "columnsTo": [ + "registryId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_projectId_project_projectId_fk": { + "name": "application_projectId_project_projectId_fk", + "tableFrom": "application", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "projectId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "application_githubId_github_githubId_fk": { + "name": "application_githubId_github_githubId_fk", + "tableFrom": "application", + "tableTo": "github", + "columnsFrom": [ + "githubId" + ], + "columnsTo": [ + "githubId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_gitlabId_gitlab_gitlabId_fk": { + "name": "application_gitlabId_gitlab_gitlabId_fk", + "tableFrom": "application", + "tableTo": "gitlab", + "columnsFrom": [ + "gitlabId" + ], + "columnsTo": [ + "gitlabId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_bitbucketId_bitbucket_bitbucketId_fk": { + "name": "application_bitbucketId_bitbucket_bitbucketId_fk", + "tableFrom": "application", + "tableTo": "bitbucket", + "columnsFrom": [ + "bitbucketId" + ], + "columnsTo": [ + "bitbucketId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_serverId_server_serverId_fk": { + "name": "application_serverId_server_serverId_fk", + "tableFrom": "application", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "application_appName_unique": { + "name": "application_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + } + }, + "public.postgres": { + "name": "postgres", + "schema": "", + "columns": { + "postgresId": { + "name": "postgresId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseName": { + "name": "databaseName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseUser": { + "name": "databaseUser", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databasePassword": { + "name": "databasePassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "postgres_projectId_project_projectId_fk": { + "name": "postgres_projectId_project_projectId_fk", + "tableFrom": "postgres", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "projectId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "postgres_serverId_server_serverId_fk": { + "name": "postgres_serverId_server_serverId_fk", + "tableFrom": "postgres", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "postgres_appName_unique": { + "name": "postgres_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + } + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "userId": { + "name": "userId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "isRegistered": { + "name": "isRegistered", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "expirationDate": { + "name": "expirationDate", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "canCreateProjects": { + "name": "canCreateProjects", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToSSHKeys": { + "name": "canAccessToSSHKeys", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canCreateServices": { + "name": "canCreateServices", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canDeleteProjects": { + "name": "canDeleteProjects", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canDeleteServices": { + "name": "canDeleteServices", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToDocker": { + "name": "canAccessToDocker", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToAPI": { + "name": "canAccessToAPI", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToGitProviders": { + "name": "canAccessToGitProviders", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToTraefikFiles": { + "name": "canAccessToTraefikFiles", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "accesedProjects": { + "name": "accesedProjects", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "ARRAY[]::text[]" + }, + "accesedServices": { + "name": "accesedServices", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "ARRAY[]::text[]" + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "authId": { + "name": "authId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_adminId_admin_adminId_fk": { + "name": "user_adminId_admin_adminId_fk", + "tableFrom": "user", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_authId_auth_id_fk": { + "name": "user_authId_auth_id_fk", + "tableFrom": "user", + "tableTo": "auth", + "columnsFrom": [ + "authId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.admin": { + "name": "admin", + "schema": "", + "columns": { + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "serverIp": { + "name": "serverIp", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "certificateType": { + "name": "certificateType", + "type": "certificateType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "host": { + "name": "host", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "letsEncryptEmail": { + "name": "letsEncryptEmail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sshPrivateKey": { + "name": "sshPrivateKey", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enableDockerCleanup": { + "name": "enableDockerCleanup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enableLogRotation": { + "name": "enableLogRotation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "authId": { + "name": "authId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripeCustomerId": { + "name": "stripeCustomerId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripeSubscriptionId": { + "name": "stripeSubscriptionId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serversQuantity": { + "name": "serversQuantity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "admin_authId_auth_id_fk": { + "name": "admin_authId_auth_id_fk", + "tableFrom": "admin", + "tableTo": "auth", + "columnsFrom": [ + "authId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.auth": { + "name": "auth", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rol": { + "name": "rol", + "type": "Roles", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is2FAEnabled": { + "name": "is2FAEnabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "resetPasswordToken": { + "name": "resetPasswordToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resetPasswordExpiresAt": { + "name": "resetPasswordExpiresAt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmationToken": { + "name": "confirmationToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmationExpiresAt": { + "name": "confirmationExpiresAt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "auth_email_unique": { + "name": "auth_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + } + }, + "public.project": { + "name": "project", + "schema": "", + "columns": { + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "project_adminId_admin_adminId_fk": { + "name": "project_adminId_admin_adminId_fk", + "tableFrom": "project", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.domain": { + "name": "domain", + "schema": "", + "columns": { + "domainId": { + "name": "domainId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "host": { + "name": "host", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "https": { + "name": "https", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 3000 + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "serviceName": { + "name": "serviceName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "domainType": { + "name": "domainType", + "type": "domainType", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'application'" + }, + "uniqueConfigKey": { + "name": "uniqueConfigKey", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "certificateType": { + "name": "certificateType", + "type": "certificateType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'none'" + } + }, + "indexes": {}, + "foreignKeys": { + "domain_composeId_compose_composeId_fk": { + "name": "domain_composeId_compose_composeId_fk", + "tableFrom": "domain", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "domain_applicationId_application_applicationId_fk": { + "name": "domain_applicationId_application_applicationId_fk", + "tableFrom": "domain", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.mariadb": { + "name": "mariadb", + "schema": "", + "columns": { + "mariadbId": { + "name": "mariadbId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "databaseName": { + "name": "databaseName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseUser": { + "name": "databaseUser", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databasePassword": { + "name": "databasePassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rootPassword": { + "name": "rootPassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mariadb_projectId_project_projectId_fk": { + "name": "mariadb_projectId_project_projectId_fk", + "tableFrom": "mariadb", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "projectId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mariadb_serverId_server_serverId_fk": { + "name": "mariadb_serverId_server_serverId_fk", + "tableFrom": "mariadb", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mariadb_appName_unique": { + "name": "mariadb_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + } + }, + "public.mongo": { + "name": "mongo", + "schema": "", + "columns": { + "mongoId": { + "name": "mongoId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "databaseUser": { + "name": "databaseUser", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databasePassword": { + "name": "databasePassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mongo_projectId_project_projectId_fk": { + "name": "mongo_projectId_project_projectId_fk", + "tableFrom": "mongo", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "projectId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mongo_serverId_server_serverId_fk": { + "name": "mongo_serverId_server_serverId_fk", + "tableFrom": "mongo", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mongo_appName_unique": { + "name": "mongo_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + } + }, + "public.mysql": { + "name": "mysql", + "schema": "", + "columns": { + "mysqlId": { + "name": "mysqlId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "databaseName": { + "name": "databaseName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseUser": { + "name": "databaseUser", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databasePassword": { + "name": "databasePassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rootPassword": { + "name": "rootPassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mysql_projectId_project_projectId_fk": { + "name": "mysql_projectId_project_projectId_fk", + "tableFrom": "mysql", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "projectId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mysql_serverId_server_serverId_fk": { + "name": "mysql_serverId_server_serverId_fk", + "tableFrom": "mysql", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mysql_appName_unique": { + "name": "mysql_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + } + }, + "public.backup": { + "name": "backup", + "schema": "", + "columns": { + "backupId": { + "name": "backupId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "schedule": { + "name": "schedule", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "database": { + "name": "database", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "destinationId": { + "name": "destinationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseType": { + "name": "databaseType", + "type": "databaseType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "postgresId": { + "name": "postgresId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mariadbId": { + "name": "mariadbId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mysqlId": { + "name": "mysqlId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mongoId": { + "name": "mongoId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "backup_destinationId_destination_destinationId_fk": { + "name": "backup_destinationId_destination_destinationId_fk", + "tableFrom": "backup", + "tableTo": "destination", + "columnsFrom": [ + "destinationId" + ], + "columnsTo": [ + "destinationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_postgresId_postgres_postgresId_fk": { + "name": "backup_postgresId_postgres_postgresId_fk", + "tableFrom": "backup", + "tableTo": "postgres", + "columnsFrom": [ + "postgresId" + ], + "columnsTo": [ + "postgresId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_mariadbId_mariadb_mariadbId_fk": { + "name": "backup_mariadbId_mariadb_mariadbId_fk", + "tableFrom": "backup", + "tableTo": "mariadb", + "columnsFrom": [ + "mariadbId" + ], + "columnsTo": [ + "mariadbId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_mysqlId_mysql_mysqlId_fk": { + "name": "backup_mysqlId_mysql_mysqlId_fk", + "tableFrom": "backup", + "tableTo": "mysql", + "columnsFrom": [ + "mysqlId" + ], + "columnsTo": [ + "mysqlId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_mongoId_mongo_mongoId_fk": { + "name": "backup_mongoId_mongo_mongoId_fk", + "tableFrom": "backup", + "tableTo": "mongo", + "columnsFrom": [ + "mongoId" + ], + "columnsTo": [ + "mongoId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.destination": { + "name": "destination", + "schema": "", + "columns": { + "destinationId": { + "name": "destinationId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "accessKey": { + "name": "accessKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "secretAccessKey": { + "name": "secretAccessKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bucket": { + "name": "bucket", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "region": { + "name": "region", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint": { + "name": "endpoint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "destination_adminId_admin_adminId_fk": { + "name": "destination_adminId_admin_adminId_fk", + "tableFrom": "destination", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.deployment": { + "name": "deployment", + "schema": "", + "columns": { + "deploymentId": { + "name": "deploymentId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "deploymentStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'running'" + }, + "logPath": { + "name": "logPath", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "deployment_applicationId_application_applicationId_fk": { + "name": "deployment_applicationId_application_applicationId_fk", + "tableFrom": "deployment", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_composeId_compose_composeId_fk": { + "name": "deployment_composeId_compose_composeId_fk", + "tableFrom": "deployment", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_serverId_server_serverId_fk": { + "name": "deployment_serverId_server_serverId_fk", + "tableFrom": "deployment", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.mount": { + "name": "mount", + "schema": "", + "columns": { + "mountId": { + "name": "mountId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "type": { + "name": "type", + "type": "mountType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "hostPath": { + "name": "hostPath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "volumeName": { + "name": "volumeName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filePath": { + "name": "filePath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serviceType": { + "name": "serviceType", + "type": "serviceType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'application'" + }, + "mountPath": { + "name": "mountPath", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postgresId": { + "name": "postgresId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mariadbId": { + "name": "mariadbId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mongoId": { + "name": "mongoId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mysqlId": { + "name": "mysqlId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "redisId": { + "name": "redisId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mount_applicationId_application_applicationId_fk": { + "name": "mount_applicationId_application_applicationId_fk", + "tableFrom": "mount", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_postgresId_postgres_postgresId_fk": { + "name": "mount_postgresId_postgres_postgresId_fk", + "tableFrom": "mount", + "tableTo": "postgres", + "columnsFrom": [ + "postgresId" + ], + "columnsTo": [ + "postgresId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_mariadbId_mariadb_mariadbId_fk": { + "name": "mount_mariadbId_mariadb_mariadbId_fk", + "tableFrom": "mount", + "tableTo": "mariadb", + "columnsFrom": [ + "mariadbId" + ], + "columnsTo": [ + "mariadbId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_mongoId_mongo_mongoId_fk": { + "name": "mount_mongoId_mongo_mongoId_fk", + "tableFrom": "mount", + "tableTo": "mongo", + "columnsFrom": [ + "mongoId" + ], + "columnsTo": [ + "mongoId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_mysqlId_mysql_mysqlId_fk": { + "name": "mount_mysqlId_mysql_mysqlId_fk", + "tableFrom": "mount", + "tableTo": "mysql", + "columnsFrom": [ + "mysqlId" + ], + "columnsTo": [ + "mysqlId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_redisId_redis_redisId_fk": { + "name": "mount_redisId_redis_redisId_fk", + "tableFrom": "mount", + "tableTo": "redis", + "columnsFrom": [ + "redisId" + ], + "columnsTo": [ + "redisId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_composeId_compose_composeId_fk": { + "name": "mount_composeId_compose_composeId_fk", + "tableFrom": "mount", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.certificate": { + "name": "certificate", + "schema": "", + "columns": { + "certificateId": { + "name": "certificateId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "certificateData": { + "name": "certificateData", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "privateKey": { + "name": "privateKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "certificatePath": { + "name": "certificatePath", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "autoRenew": { + "name": "autoRenew", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "certificate_adminId_admin_adminId_fk": { + "name": "certificate_adminId_admin_adminId_fk", + "tableFrom": "certificate", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "certificate_serverId_server_serverId_fk": { + "name": "certificate_serverId_server_serverId_fk", + "tableFrom": "certificate", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "certificate_certificatePath_unique": { + "name": "certificate_certificatePath_unique", + "nullsNotDistinct": false, + "columns": [ + "certificatePath" + ] + } + } + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_auth_id_fk": { + "name": "session_user_id_auth_id_fk", + "tableFrom": "session", + "tableTo": "auth", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.redirect": { + "name": "redirect", + "schema": "", + "columns": { + "redirectId": { + "name": "redirectId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "regex": { + "name": "regex", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "replacement": { + "name": "replacement", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "permanent": { + "name": "permanent", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "uniqueConfigKey": { + "name": "uniqueConfigKey", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "redirect_applicationId_application_applicationId_fk": { + "name": "redirect_applicationId_application_applicationId_fk", + "tableFrom": "redirect", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.security": { + "name": "security", + "schema": "", + "columns": { + "securityId": { + "name": "securityId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "security_applicationId_application_applicationId_fk": { + "name": "security_applicationId_application_applicationId_fk", + "tableFrom": "security", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "security_username_applicationId_unique": { + "name": "security_username_applicationId_unique", + "nullsNotDistinct": false, + "columns": [ + "username", + "applicationId" + ] + } + } + }, + "public.port": { + "name": "port", + "schema": "", + "columns": { + "portId": { + "name": "portId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "publishedPort": { + "name": "publishedPort", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "targetPort": { + "name": "targetPort", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "protocol": { + "name": "protocol", + "type": "protocolType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "port_applicationId_application_applicationId_fk": { + "name": "port_applicationId_application_applicationId_fk", + "tableFrom": "port", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.redis": { + "name": "redis", + "schema": "", + "columns": { + "redisId": { + "name": "redisId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "redis_projectId_project_projectId_fk": { + "name": "redis_projectId_project_projectId_fk", + "tableFrom": "redis", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "projectId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "redis_serverId_server_serverId_fk": { + "name": "redis_serverId_server_serverId_fk", + "tableFrom": "redis", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "redis_appName_unique": { + "name": "redis_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + } + }, + "public.compose": { + "name": "compose", + "schema": "", + "columns": { + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "composeFile": { + "name": "composeFile", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "refreshToken": { + "name": "refreshToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sourceType": { + "name": "sourceType", + "type": "sourceTypeCompose", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "composeType": { + "name": "composeType", + "type": "composeType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'docker-compose'" + }, + "repository": { + "name": "repository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owner": { + "name": "owner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "autoDeploy": { + "name": "autoDeploy", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "gitlabProjectId": { + "name": "gitlabProjectId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "gitlabRepository": { + "name": "gitlabRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabOwner": { + "name": "gitlabOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabBranch": { + "name": "gitlabBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabPathNamespace": { + "name": "gitlabPathNamespace", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketRepository": { + "name": "bitbucketRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketOwner": { + "name": "bitbucketOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketBranch": { + "name": "bitbucketBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitUrl": { + "name": "customGitUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitBranch": { + "name": "customGitBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitSSHKeyId": { + "name": "customGitSSHKeyId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "composePath": { + "name": "composePath", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'./docker-compose.yml'" + }, + "suffix": { + "name": "suffix", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "randomize": { + "name": "randomize", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "composeStatus": { + "name": "composeStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "githubId": { + "name": "githubId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabId": { + "name": "gitlabId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketId": { + "name": "bitbucketId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "compose_customGitSSHKeyId_ssh-key_sshKeyId_fk": { + "name": "compose_customGitSSHKeyId_ssh-key_sshKeyId_fk", + "tableFrom": "compose", + "tableTo": "ssh-key", + "columnsFrom": [ + "customGitSSHKeyId" + ], + "columnsTo": [ + "sshKeyId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_projectId_project_projectId_fk": { + "name": "compose_projectId_project_projectId_fk", + "tableFrom": "compose", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "projectId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "compose_githubId_github_githubId_fk": { + "name": "compose_githubId_github_githubId_fk", + "tableFrom": "compose", + "tableTo": "github", + "columnsFrom": [ + "githubId" + ], + "columnsTo": [ + "githubId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_gitlabId_gitlab_gitlabId_fk": { + "name": "compose_gitlabId_gitlab_gitlabId_fk", + "tableFrom": "compose", + "tableTo": "gitlab", + "columnsFrom": [ + "gitlabId" + ], + "columnsTo": [ + "gitlabId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_bitbucketId_bitbucket_bitbucketId_fk": { + "name": "compose_bitbucketId_bitbucket_bitbucketId_fk", + "tableFrom": "compose", + "tableTo": "bitbucket", + "columnsFrom": [ + "bitbucketId" + ], + "columnsTo": [ + "bitbucketId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_serverId_server_serverId_fk": { + "name": "compose_serverId_server_serverId_fk", + "tableFrom": "compose", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.registry": { + "name": "registry", + "schema": "", + "columns": { + "registryId": { + "name": "registryId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "registryName": { + "name": "registryName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "imagePrefix": { + "name": "imagePrefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "registryUrl": { + "name": "registryUrl", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "selfHosted": { + "name": "selfHosted", + "type": "RegistryType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'cloud'" + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "registry_adminId_admin_adminId_fk": { + "name": "registry_adminId_admin_adminId_fk", + "tableFrom": "registry", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.discord": { + "name": "discord", + "schema": "", + "columns": { + "discordId": { + "name": "discordId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "webhookUrl": { + "name": "webhookUrl", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.email": { + "name": "email", + "schema": "", + "columns": { + "emailId": { + "name": "emailId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "smtpServer": { + "name": "smtpServer", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "smtpPort": { + "name": "smtpPort", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fromAddress": { + "name": "fromAddress", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "toAddress": { + "name": "toAddress", + "type": "text[]", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.notification": { + "name": "notification", + "schema": "", + "columns": { + "notificationId": { + "name": "notificationId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appDeploy": { + "name": "appDeploy", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "appBuildError": { + "name": "appBuildError", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "databaseBackup": { + "name": "databaseBackup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "dokployRestart": { + "name": "dokployRestart", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "dockerCleanup": { + "name": "dockerCleanup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notificationType": { + "name": "notificationType", + "type": "notificationType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slackId": { + "name": "slackId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "telegramId": { + "name": "telegramId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "discordId": { + "name": "discordId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "emailId": { + "name": "emailId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "notification_slackId_slack_slackId_fk": { + "name": "notification_slackId_slack_slackId_fk", + "tableFrom": "notification", + "tableTo": "slack", + "columnsFrom": [ + "slackId" + ], + "columnsTo": [ + "slackId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_telegramId_telegram_telegramId_fk": { + "name": "notification_telegramId_telegram_telegramId_fk", + "tableFrom": "notification", + "tableTo": "telegram", + "columnsFrom": [ + "telegramId" + ], + "columnsTo": [ + "telegramId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_discordId_discord_discordId_fk": { + "name": "notification_discordId_discord_discordId_fk", + "tableFrom": "notification", + "tableTo": "discord", + "columnsFrom": [ + "discordId" + ], + "columnsTo": [ + "discordId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_emailId_email_emailId_fk": { + "name": "notification_emailId_email_emailId_fk", + "tableFrom": "notification", + "tableTo": "email", + "columnsFrom": [ + "emailId" + ], + "columnsTo": [ + "emailId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_adminId_admin_adminId_fk": { + "name": "notification_adminId_admin_adminId_fk", + "tableFrom": "notification", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.slack": { + "name": "slack", + "schema": "", + "columns": { + "slackId": { + "name": "slackId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "webhookUrl": { + "name": "webhookUrl", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.telegram": { + "name": "telegram", + "schema": "", + "columns": { + "telegramId": { + "name": "telegramId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "botToken": { + "name": "botToken", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "chatId": { + "name": "chatId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.ssh-key": { + "name": "ssh-key", + "schema": "", + "columns": { + "sshKeyId": { + "name": "sshKeyId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "privateKey": { + "name": "privateKey", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "publicKey": { + "name": "publicKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lastUsedAt": { + "name": "lastUsedAt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "ssh-key_adminId_admin_adminId_fk": { + "name": "ssh-key_adminId_admin_adminId_fk", + "tableFrom": "ssh-key", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.git_provider": { + "name": "git_provider", + "schema": "", + "columns": { + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "providerType": { + "name": "providerType", + "type": "gitProviderType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "git_provider_adminId_admin_adminId_fk": { + "name": "git_provider_adminId_admin_adminId_fk", + "tableFrom": "git_provider", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.bitbucket": { + "name": "bitbucket", + "schema": "", + "columns": { + "bitbucketId": { + "name": "bitbucketId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "bitbucketUsername": { + "name": "bitbucketUsername", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "appPassword": { + "name": "appPassword", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketWorkspaceName": { + "name": "bitbucketWorkspaceName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "bitbucket_gitProviderId_git_provider_gitProviderId_fk": { + "name": "bitbucket_gitProviderId_git_provider_gitProviderId_fk", + "tableFrom": "bitbucket", + "tableTo": "git_provider", + "columnsFrom": [ + "gitProviderId" + ], + "columnsTo": [ + "gitProviderId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.github": { + "name": "github", + "schema": "", + "columns": { + "githubId": { + "name": "githubId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "githubAppName": { + "name": "githubAppName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubAppId": { + "name": "githubAppId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "githubClientId": { + "name": "githubClientId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubClientSecret": { + "name": "githubClientSecret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubInstallationId": { + "name": "githubInstallationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubPrivateKey": { + "name": "githubPrivateKey", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubWebhookSecret": { + "name": "githubWebhookSecret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "github_gitProviderId_git_provider_gitProviderId_fk": { + "name": "github_gitProviderId_git_provider_gitProviderId_fk", + "tableFrom": "github", + "tableTo": "git_provider", + "columnsFrom": [ + "gitProviderId" + ], + "columnsTo": [ + "gitProviderId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.gitlab": { + "name": "gitlab", + "schema": "", + "columns": { + "gitlabId": { + "name": "gitlabId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "redirect_uri": { + "name": "redirect_uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "group_name": { + "name": "group_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "gitlab_gitProviderId_git_provider_gitProviderId_fk": { + "name": "gitlab_gitProviderId_git_provider_gitProviderId_fk", + "tableFrom": "gitlab", + "tableTo": "git_provider", + "columnsFrom": [ + "gitProviderId" + ], + "columnsTo": [ + "gitProviderId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.server": { + "name": "server", + "schema": "", + "columns": { + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ipAddress": { + "name": "ipAddress", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'root'" + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enableDockerCleanup": { + "name": "enableDockerCleanup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "adminId": { + "name": "adminId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverStatus": { + "name": "serverStatus", + "type": "serverStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "sshKeyId": { + "name": "sshKeyId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "server_adminId_admin_adminId_fk": { + "name": "server_adminId_admin_adminId_fk", + "tableFrom": "server", + "tableTo": "admin", + "columnsFrom": [ + "adminId" + ], + "columnsTo": [ + "adminId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "server_sshKeyId_ssh-key_sshKeyId_fk": { + "name": "server_sshKeyId_ssh-key_sshKeyId_fk", + "tableFrom": "server", + "tableTo": "ssh-key", + "columnsFrom": [ + "sshKeyId" + ], + "columnsTo": [ + "sshKeyId" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.buildType": { + "name": "buildType", + "schema": "public", + "values": [ + "dockerfile", + "heroku_buildpacks", + "paketo_buildpacks", + "nixpacks", + "static" + ] + }, + "public.sourceType": { + "name": "sourceType", + "schema": "public", + "values": [ + "docker", + "git", + "github", + "gitlab", + "bitbucket", + "drop" + ] + }, + "public.Roles": { + "name": "Roles", + "schema": "public", + "values": [ + "admin", + "user" + ] + }, + "public.domainType": { + "name": "domainType", + "schema": "public", + "values": [ + "compose", + "application" + ] + }, + "public.databaseType": { + "name": "databaseType", + "schema": "public", + "values": [ + "postgres", + "mariadb", + "mysql", + "mongo" + ] + }, + "public.deploymentStatus": { + "name": "deploymentStatus", + "schema": "public", + "values": [ + "running", + "done", + "error" + ] + }, + "public.mountType": { + "name": "mountType", + "schema": "public", + "values": [ + "bind", + "volume", + "file" + ] + }, + "public.serviceType": { + "name": "serviceType", + "schema": "public", + "values": [ + "application", + "postgres", + "mysql", + "mariadb", + "mongo", + "redis", + "compose" + ] + }, + "public.protocolType": { + "name": "protocolType", + "schema": "public", + "values": [ + "tcp", + "udp" + ] + }, + "public.applicationStatus": { + "name": "applicationStatus", + "schema": "public", + "values": [ + "idle", + "running", + "done", + "error" + ] + }, + "public.certificateType": { + "name": "certificateType", + "schema": "public", + "values": [ + "letsencrypt", + "none" + ] + }, + "public.composeType": { + "name": "composeType", + "schema": "public", + "values": [ + "docker-compose", + "stack" + ] + }, + "public.sourceTypeCompose": { + "name": "sourceTypeCompose", + "schema": "public", + "values": [ + "git", + "github", + "gitlab", + "bitbucket", + "raw" + ] + }, + "public.RegistryType": { + "name": "RegistryType", + "schema": "public", + "values": [ + "selfHosted", + "cloud" + ] + }, + "public.notificationType": { + "name": "notificationType", + "schema": "public", + "values": [ + "slack", + "telegram", + "discord", + "email" + ] + }, + "public.gitProviderType": { + "name": "gitProviderType", + "schema": "public", + "values": [ + "github", + "gitlab", + "bitbucket" + ] + }, + "public.serverStatus": { + "name": "serverStatus", + "schema": "public", + "values": [ + "active", + "inactive" + ] + } + }, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/apps/dokploy/drizzle/meta/_journal.json b/apps/dokploy/drizzle/meta/_journal.json index dfd87337..72851672 100644 --- a/apps/dokploy/drizzle/meta/_journal.json +++ b/apps/dokploy/drizzle/meta/_journal.json @@ -295,6 +295,13 @@ "when": 1729667438853, "tag": "0041_huge_bruce_banner", "breakpoints": true + }, + { + "idx": 42, + "version": "6", + "when": 1729984439862, + "tag": "0042_fancy_havok", + "breakpoints": true } ] } \ No newline at end of file diff --git a/apps/dokploy/pages/confirm-email.tsx b/apps/dokploy/pages/confirm-email.tsx new file mode 100644 index 00000000..b7203fbf --- /dev/null +++ b/apps/dokploy/pages/confirm-email.tsx @@ -0,0 +1,95 @@ +import { OnboardingLayout } from "@/components/layouts/onboarding-layout"; +import { Logo } from "@/components/shared/logo"; +import { CardDescription, CardTitle } from "@/components/ui/card"; +import { auth } from "@/server/db/schema"; +import { IS_CLOUD, updateAuthById } from "@dokploy/server"; +import { isBefore } from "date-fns"; +import { eq } from "drizzle-orm"; +import type { GetServerSidePropsContext } from "next"; +import Link from "next/link"; +import type { ReactElement } from "react"; + +export default function Home() { + return ( +
+
+ + + Dokploy + + Email Confirmed + + Congratulations, your email is confirmed. + +
+ + Click here to login + +
+
+
+ ); +} + +Home.getLayout = (page: ReactElement) => { + return {page}; +}; +export async function getServerSideProps(context: GetServerSidePropsContext) { + if (!IS_CLOUD) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + const { token } = context.query; + + if (typeof token !== "string") { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + + const authR = await db?.query.auth.findFirst({ + where: eq(auth.confirmationToken, token), + }); + + if ( + !authR || + authR?.confirmationToken === null || + authR?.confirmationExpiresAt === null + ) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + + const isExpired = isBefore(new Date(authR.confirmationExpiresAt), new Date()); + + if (isExpired) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + + await updateAuthById(authR.id, { + confirmationToken: null, + confirmationExpiresAt: null, + }); + + return { + props: { + token: authR.confirmationToken, + }, + }; +} diff --git a/apps/dokploy/pages/index.tsx b/apps/dokploy/pages/index.tsx index a8364186..f30877f1 100644 --- a/apps/dokploy/pages/index.tsx +++ b/apps/dokploy/pages/index.tsx @@ -1,5 +1,6 @@ import { Login2FA } from "@/components/auth/login-2fa"; import { OnboardingLayout } from "@/components/layouts/onboarding-layout"; +import { AlertBlock } from "@/components/shared/alert-block"; import { Logo } from "@/components/shared/logo"; import { Button } from "@/components/ui/button"; import { @@ -63,7 +64,8 @@ export default function Home({ IS_CLOUD }: Props) { is2FAEnabled: false, authId: "", }); - const { mutateAsync, isLoading } = api.auth.login.useMutation(); + const { mutateAsync, isLoading, error, isError } = + api.auth.login.useMutation(); const router = useRouter(); const form = useForm({ defaultValues: { @@ -115,6 +117,12 @@ export default function Home({ IS_CLOUD }: Props) {
+ {isError && ( + + {error?.message} + + )} + {!temp.is2FAEnabled ? (
diff --git a/apps/dokploy/pages/invitation.tsx b/apps/dokploy/pages/invitation.tsx index 9e7a02ff..adb1cf24 100644 --- a/apps/dokploy/pages/invitation.tsx +++ b/apps/dokploy/pages/invitation.tsx @@ -16,7 +16,7 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; -import { getUserByToken } from "@dokploy/server"; +import { IS_CLOUD, getUserByToken } from "@dokploy/server"; import { zodResolver } from "@hookform/resolvers/zod"; import { AlertTriangle } from "lucide-react"; import type { GetServerSidePropsContext } from "next"; @@ -69,9 +69,10 @@ type Register = z.infer; interface Props { token: string; invitation: Awaited>; + isCloud: boolean; } -const Invitation = ({ token, invitation }: Props) => { +const Invitation = ({ token, invitation, isCloud }: Props) => { const router = useRouter(); const { data } = api.admin.getUserByToken.useQuery( { @@ -83,7 +84,8 @@ const Invitation = ({ token, invitation }: Props) => { }, ); - const { mutateAsync, error, isError } = api.auth.createUser.useMutation(); + const { mutateAsync, error, isError, isSuccess } = + api.auth.createUser.useMutation(); const form = useForm({ defaultValues: { @@ -112,7 +114,9 @@ const Invitation = ({ token, invitation }: Props) => { }) .then(() => { toast.success("User registration succesfuly", { - duration: 2000, + description: + "Please check your inbox or spam folder to confirm your account.", + duration: 100000, }); router.push("/dashboard/projects"); }) @@ -146,6 +150,7 @@ const Invitation = ({ token, invitation }: Props) => {
)} + { Register + +
+ {isCloud && ( + <> + + Login + + + Lost your password? + + + )} +
@@ -250,6 +274,7 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) { return { props: { + isCloud: IS_CLOUD, token: token, invitation: invitation, }, diff --git a/apps/dokploy/pages/register.tsx b/apps/dokploy/pages/register.tsx index 0d602cf5..d1094e65 100644 --- a/apps/dokploy/pages/register.tsx +++ b/apps/dokploy/pages/register.tsx @@ -1,3 +1,4 @@ +import { AlertBlock } from "@/components/shared/alert-block"; import { Logo } from "@/components/shared/logo"; import { Button } from "@/components/ui/button"; import { @@ -72,7 +73,8 @@ interface Props { const Register = ({ isCloud }: Props) => { const router = useRouter(); - const { mutateAsync, error, isError } = api.auth.createAdmin.useMutation(); + const { mutateAsync, error, isError, data } = + api.auth.createAdmin.useMutation(); const form = useForm({ defaultValues: { @@ -89,14 +91,16 @@ const Register = ({ isCloud }: Props) => { const onSubmit = async (values: Register) => { await mutateAsync({ - email: values.email, + email: values.email.toLowerCase(), password: values.password, }) .then(() => { toast.success("User registration succesfuly", { duration: 2000, }); - router.push("/"); + if (!isCloud) { + router.push("/"); + } }) .catch((e) => e); }; @@ -130,6 +134,14 @@ const Register = ({ isCloud }: Props) => { )} + {data && ( + + + Registration succesfuly, Please check your inbox or spam + folder to confirm your account. + + + )}
{ const auth = await updateAuthById(ctx.user.authId, { - ...(input.email && { email: input.email }), + ...(input.email && { email: input.email.toLowerCase() }), ...(input.password && { password: bcrypt.hashSync(input.password, 10), }), @@ -183,19 +208,6 @@ export const authRouter = createTRPCRouter({ return auth; }), - updateByAdmin: protectedProcedure - .input(apiUpdateAuthByAdmin) - .mutation(async ({ input }) => { - const auth = await updateAuthById(input.id, { - ...(input.email && { email: input.email }), - ...(input.password && { - password: bcrypt.hashSync(input.password, 10), - }), - ...(input.image && { image: input.image }), - }); - - return auth; - }), generate2FASecret: protectedProcedure.query(async ({ ctx }) => { return await generate2FASecret(ctx.user.authId); }), @@ -236,9 +248,6 @@ export const authRouter = createTRPCRouter({ }); return auth; }), - verifyToken: protectedProcedure.mutation(async () => { - return true; - }), sendResetPasswordEmail: publicProcedure .input( z.object({ @@ -270,7 +279,7 @@ export const authRouter = createTRPCRouter({ ).toISOString(), }); - const email = await sendEmailNotification( + await sendEmailNotification( { fromAddress: process.env.SMTP_FROM_ADDRESS || "", toAddresses: [authR.email], @@ -283,7 +292,7 @@ export const authRouter = createTRPCRouter({ ` Reset your password by clicking the link below: The link will expire in 24 hours. - + Reset Password @@ -334,6 +343,84 @@ export const authRouter = createTRPCRouter({ password: bcrypt.hashSync(input.password, 10), }); + return true; + }), + confirmEmail: adminProcedure + .input( + z.object({ + confirmationToken: z.string().min(1), + }), + ) + .mutation(async ({ ctx, input }) => { + const authR = await db.query.auth.findFirst({ + where: eq(auth.confirmationToken, input.confirmationToken), + }); + if (!authR || authR.confirmationExpiresAt === null) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Token not found", + }); + } + if (authR.confirmationToken !== input.confirmationToken) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Confirmation Token not found", + }); + } + + const isExpired = isBefore( + new Date(authR.confirmationExpiresAt), + new Date(), + ); + + if (isExpired) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Confirmation Token expired", + }); + } + 1; + await updateAuthById(authR.id, { + confirmationToken: null, + confirmationExpiresAt: null, + }); return true; }), }); + +export const sendVerificationEmail = async (authId: string) => { + const token = nanoid(); + const result = await updateAuthById(authId, { + confirmationToken: token, + confirmationExpiresAt: new Date( + new Date().getTime() + 24 * 60 * 60 * 1000, + ).toISOString(), + }); + + if (!result) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: "User not found", + }); + } + await sendEmailNotification( + { + fromAddress: process.env.SMTP_FROM_ADDRESS || "", + toAddresses: [result?.email], + smtpServer: process.env.SMTP_SERVER || "", + smtpPort: Number(process.env.SMTP_PORT), + username: process.env.SMTP_USERNAME || "", + password: process.env.SMTP_PASSWORD || "", + }, + "Confirm your email | Dokploy", + ` + Welcome to Dokploy! + Please confirm your email by clicking the link below: + + Confirm Email + + `, + ); + + return true; +}; diff --git a/packages/server/src/db/schema/auth.ts b/packages/server/src/db/schema/auth.ts index e8deb3c0..0f8640fc 100644 --- a/packages/server/src/db/schema/auth.ts +++ b/packages/server/src/db/schema/auth.ts @@ -50,6 +50,8 @@ export const auth = pgTable("auth", { .$defaultFn(() => new Date().toISOString()), resetPasswordToken: text("resetPasswordToken"), resetPasswordExpiresAt: text("resetPasswordExpiresAt"), + confirmationToken: text("confirmationToken"), + confirmationExpiresAt: text("confirmationExpiresAt"), }); export const authRelations = relations(auth, ({ many }) => ({ diff --git a/packages/server/src/services/admin.ts b/packages/server/src/services/admin.ts index 94bd92d9..a52b1a6e 100644 --- a/packages/server/src/services/admin.ts +++ b/packages/server/src/services/admin.ts @@ -20,7 +20,7 @@ export const createInvitation = async ( const result = await tx .insert(auth) .values({ - email: input.email, + email: input.email.toLowerCase(), rol: "user", password: bcrypt.hashSync("01231203012312", 10), }) diff --git a/packages/server/src/services/auth.ts b/packages/server/src/services/auth.ts index 0003c61a..11e2d24c 100644 --- a/packages/server/src/services/auth.ts +++ b/packages/server/src/services/auth.ts @@ -24,7 +24,7 @@ export const createAdmin = async (input: typeof apiCreateAdmin._type) => { const newAuth = await tx .insert(auth) .values({ - email: input.email, + email: input.email.toLowerCase(), password: hashedPassword, rol: "admin", }) @@ -93,7 +93,7 @@ export const findAuthByEmail = async (email: string) => { if (!result) { throw new TRPCError({ code: "NOT_FOUND", - message: "Auth not found", + message: "User not found", }); } return result; From 28221a4e7ac5b5faf7f95882261bc421d7a784dc Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 26 Oct 2024 19:27:01 -0600 Subject: [PATCH 09/20] refactor(dokploy): add umami and update favicon --- .github/workflows/deploy.yml | 3 ++- Dockerfile.cloud | 7 +++++++ apps/docs/app/[lang]/layout.tsx | 7 +++++++ apps/dokploy/pages/_app.tsx | 9 +++++++++ apps/dokploy/pages/_document.tsx | 5 +++-- apps/dokploy/public/favicon.ico | Bin 3494 -> 0 bytes apps/dokploy/public/logo.png | Bin 17567 -> 0 bytes apps/website/app/[locale]/layout.tsx | 11 ++++++++--- pnpm-lock.yaml | 6 +++--- 9 files changed, 39 insertions(+), 9 deletions(-) delete mode 100644 apps/dokploy/public/favicon.ico delete mode 100644 apps/dokploy/public/logo.png diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a7b60213..73a021cc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -74,7 +74,8 @@ jobs: platforms: linux/amd64 build-args: | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${{ github.ref_name == 'main' && 'pk_live_51QAm7bF3cxQuHeOzMpfNfJIch6oLif8rS32pRE392CdTbBf0MYBdbapAxarQGspqJBWT2nVOxu8e6ZHrHB4NhVHG008DE2A90d' || 'pk_test_51QAm7bF3cxQuHeOz0xg04o9teeyTbbNHQPJ5Tr98MlTEan9MzewT3gwh0jSWBNvrRWZ5vASoBgxUSF4gPWsJwATk00Ir2JZ0S1' }} - + NEXT_PUBLIC_UMAMI_HOST="https://umami.dokploy.com/script.js" + NEXT_PUBLIC_UMAMI_WEBSITE_ID="ef083745-e111-4bac-9fe6-c549807adefe" build-and-push-schedule-image: runs-on: ubuntu-latest diff --git a/Dockerfile.cloud b/Dockerfile.cloud index 664180f7..f664e1a4 100644 --- a/Dockerfile.cloud +++ b/Dockerfile.cloud @@ -14,8 +14,15 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm --filter=@dokploy/server # Deploy only the dokploy app +ARG NEXT_PUBLIC_UMAMI_HOST +ENV NEXT_PUBLIC_UMAMI_HOST=$NEXT_PUBLIC_UMAMI_HOST + +ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID +ENV NEXT_PUBLIC_UMAMI_WEBSITE_ID=$NEXT_PUBLIC_UMAMI_WEBSITE_ID + ARG NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY ENV NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=$NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY + ENV NODE_ENV=production RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build diff --git a/apps/docs/app/[lang]/layout.tsx b/apps/docs/app/[lang]/layout.tsx index aa0d2c63..d00df307 100644 --- a/apps/docs/app/[lang]/layout.tsx +++ b/apps/docs/app/[lang]/layout.tsx @@ -63,6 +63,13 @@ export default function Layout({ className={inter.className} suppressHydrationWarning > + +